summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2022-04-05 01:43:29 +0200
committerGravatar Nikias Bassen2022-04-05 01:43:29 +0200
commite28d96d4e976ecb19a4d2a094609f122e08ea8fa (patch)
tree0649313d16b2e519dfaacd4ba6224d475e33800f
parentd0a61eb39fc79e6ebc7e9a91188213e742b048dd (diff)
downloadidevicerestore-e28d96d4e976ecb19a4d2a094609f122e08ea8fa.tar.gz
idevicerestore-e28d96d4e976ecb19a4d2a094609f122e08ea8fa.tar.bz2
ipsw: Use libplist's new plist_from_json API
-rw-r--r--src/Makefile.am4
-rw-r--r--src/ipsw.c4
-rw-r--r--src/jsmn.c280
-rw-r--r--src/jsmn.h91
-rw-r--r--src/json_plist.c229
-rw-r--r--src/json_plist.h34
6 files changed, 3 insertions, 639 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4a99dec..a89a9c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,9 +45,7 @@ idevicerestore_SOURCES = \
limera1n_payload.h \
limera1n.c limera1n.h \
download.c download.h \
- locking.c locking.h \
- jsmn.c jsmn.h \
- json_plist.c json_plist.h
+ locking.c locking.h
if USE_INTERNAL_SHA
idevicerestore_SOURCES += sha1.c sha1.h sha512.c sha512.h fixedint.h
endif
diff --git a/src/ipsw.c b/src/ipsw.c
index da00a6e..03e10c2 100644
--- a/src/ipsw.c
+++ b/src/ipsw.c
@@ -45,13 +45,13 @@
#endif
#include <libimobiledevice-glue/termcolors.h>
+#include <plist/plist.h>
#include "ipsw.h"
#include "locking.h"
#include "download.h"
#include "common.h"
#include "idevicerestore.h"
-#include "json_plist.h"
#define BUFSIZE 0x100000
@@ -892,7 +892,7 @@ int ipsw_get_signed_firmwares(const char* product, plist_t* firmwares)
error("ERROR: Download from %s failed.\n", url);
return -1;
}
- dict = json_to_plist(jdata);
+ plist_from_json(jdata, jsize, &dict);
free(jdata);
if (!dict || plist_get_node_type(dict) != PLIST_DICT) {
error("ERROR: Failed to parse json data.\n");
diff --git a/src/jsmn.c b/src/jsmn.c
deleted file mode 100644
index a56f20a..0000000
--- a/src/jsmn.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * jsmn.c
- * Simple JSON parser
- *
- * Copyright (c) 2010 Serge A. Zaitsev
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdlib.h>
-
-#include "jsmn.h"
-
-/**
- * Allocates a fresh unused token from the token pull.
- */
-static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
- jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *tok;
- if (parser->toknext >= num_tokens) {
- return NULL;
- }
- tok = &tokens[parser->toknext++];
- tok->start = tok->end = -1;
- tok->size = 0;
-#ifdef JSMN_PARENT_LINKS
- tok->parent = -1;
-#endif
- return tok;
-}
-
-/**
- * Fills token type and boundaries.
- */
-static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
- int start, int end) {
- token->type = type;
- token->start = start;
- token->end = end;
- token->size = 0;
-}
-
-/**
- * Fills next available token with JSON primitive.
- */
-static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
- jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *token;
- int start;
-
- start = parser->pos;
-
- for (; js[parser->pos] != '\0'; parser->pos++) {
- switch (js[parser->pos]) {
-#ifndef JSMN_STRICT
- /* In strict mode primitive must be followed by "," or "}" or "]" */
- case ':':
-#endif
- case '\t' : case '\r' : case '\n' : case ' ' :
- case ',' : case ']' : case '}' :
- goto found;
- }
- if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
- parser->pos = start;
- return JSMN_ERROR_INVAL;
- }
- }
-#ifdef JSMN_STRICT
- /* In strict mode primitive must be followed by a comma/object/array */
- parser->pos = start;
- return JSMN_ERROR_PART;
-#endif
-
-found:
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL) {
- parser->pos = start;
- return JSMN_ERROR_NOMEM;
- }
- jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- parser->pos--;
- return JSMN_SUCCESS;
-}
-
-/**
- * Filsl next token with JSON string.
- */
-static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
- jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *token;
-
- int start = parser->pos;
-
- parser->pos++;
-
- /* Skip starting quote */
- for (; js[parser->pos] != '\0'; parser->pos++) {
- char c = js[parser->pos];
-
- /* Quote: end of string */
- if (c == '\"') {
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL) {
- parser->pos = start;
- return JSMN_ERROR_NOMEM;
- }
- jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- return JSMN_SUCCESS;
- }
-
- /* Backslash: Quoted symbol expected */
- if (c == '\\') {
- parser->pos++;
- switch (js[parser->pos]) {
- /* Allowed escaped symbols */
- case '\"': case '/' : case '\\' : case 'b' :
- case 'f' : case 'r' : case 'n' : case 't' :
- break;
- /* Allows escaped symbol \uXXXX */
- case 'u':
- /* TODO */
- break;
- /* Unexpected symbol */
- default:
- parser->pos = start;
- return JSMN_ERROR_INVAL;
- }
- }
- }
- parser->pos = start;
- return JSMN_ERROR_PART;
-}
-
-/**
- * Parse JSON string and fill tokens.
- */
-jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
- unsigned int num_tokens) {
- jsmnerr_t r;
- int i;
- jsmntok_t *token;
-
- for (; js[parser->pos] != '\0'; parser->pos++) {
- char c;
- jsmntype_t type;
-
- c = js[parser->pos];
- switch (c) {
- case '{': case '[':
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL)
- return JSMN_ERROR_NOMEM;
- if (parser->toksuper != -1) {
- tokens[parser->toksuper].size++;
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- }
- token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
- token->start = parser->pos;
- parser->toksuper = parser->toknext - 1;
- break;
- case '}': case ']':
- type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
-#ifdef JSMN_PARENT_LINKS
- if (parser->toknext < 1) {
- return JSMN_ERROR_INVAL;
- }
- token = &tokens[parser->toknext - 1];
- for (;;) {
- if (token->start != -1 && token->end == -1) {
- if (token->type != type) {
- return JSMN_ERROR_INVAL;
- }
- token->end = parser->pos + 1;
- parser->toksuper = token->parent;
- break;
- }
- if (token->parent == -1) {
- break;
- }
- token = &tokens[token->parent];
- }
-#else
- for (i = parser->toknext - 1; i >= 0; i--) {
- token = &tokens[i];
- if (token->start != -1 && token->end == -1) {
- if (token->type != type) {
- return JSMN_ERROR_INVAL;
- }
- parser->toksuper = -1;
- token->end = parser->pos + 1;
- break;
- }
- }
- /* Error if unmatched closing bracket */
- if (i == -1) return JSMN_ERROR_INVAL;
- for (; i >= 0; i--) {
- token = &tokens[i];
- if (token->start != -1 && token->end == -1) {
- parser->toksuper = i;
- break;
- }
- }
-#endif
- break;
- case '\"':
- r = jsmn_parse_string(parser, js, tokens, num_tokens);
- if (r < 0) return r;
- if (parser->toksuper != -1)
- tokens[parser->toksuper].size++;
- break;
- case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
- break;
-#ifdef JSMN_STRICT
- /* In strict mode primitives are: numbers and booleans */
- case '-': case '0': case '1' : case '2': case '3' : case '4':
- case '5': case '6': case '7' : case '8': case '9':
- case 't': case 'f': case 'n' :
-#else
- /* In non-strict mode every unquoted value is a primitive */
- default:
-#endif
- r = jsmn_parse_primitive(parser, js, tokens, num_tokens);
- if (r < 0) return r;
- if (parser->toksuper != -1)
- tokens[parser->toksuper].size++;
- break;
-
-#ifdef JSMN_STRICT
- /* Unexpected char in strict mode */
- default:
- return JSMN_ERROR_INVAL;
-#endif
-
- }
- }
-
- for (i = parser->toknext - 1; i >= 0; i--) {
- /* Unmatched opened object or array */
- if (tokens[i].start != -1 && tokens[i].end == -1) {
- return JSMN_ERROR_PART;
- }
- }
-
- return JSMN_SUCCESS;
-}
-
-/**
- * Creates a new parser based over a given buffer with an array of tokens
- * available.
- */
-void jsmn_init(jsmn_parser *parser) {
- parser->pos = 0;
- parser->toknext = 0;
- parser->toksuper = -1;
-}
-
diff --git a/src/jsmn.h b/src/jsmn.h
deleted file mode 100644
index f12dc5a..0000000
--- a/src/jsmn.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * jsmn.h
- * Simple JSON parser (header file)
- *
- * Copyright (c) 2010 Serge A. Zaitsev
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef __JSMN_H_
-#define __JSMN_H_
-
-/**
- * JSON type identifier. Basic types are:
- * o Object
- * o Array
- * o String
- * o Other primitive: number, boolean (true/false) or null
- */
-typedef enum {
- JSMN_PRIMITIVE = 0,
- JSMN_OBJECT = 1,
- JSMN_ARRAY = 2,
- JSMN_STRING = 3
-} jsmntype_t;
-
-typedef enum {
- /* Not enough tokens were provided */
- JSMN_ERROR_NOMEM = -1,
- /* Invalid character inside JSON string */
- JSMN_ERROR_INVAL = -2,
- /* The string is not a full JSON packet, more bytes expected */
- JSMN_ERROR_PART = -3,
- /* Everything was fine */
- JSMN_SUCCESS = 0
-} jsmnerr_t;
-
-/**
- * JSON token description.
- * @param type type (object, array, string etc.)
- * @param start start position in JSON data string
- * @param end end position in JSON data string
- */
-typedef struct {
- jsmntype_t type;
- int start;
- int end;
- int size;
-#ifdef JSMN_PARENT_LINKS
- int parent;
-#endif
-} jsmntok_t;
-
-/**
- * JSON parser. Contains an array of token blocks available. Also stores
- * the string being parsed now and current position in that string
- */
-typedef struct {
- unsigned int pos; /* offset in the JSON string */
- int toknext; /* next token to allocate */
- int toksuper; /* superior token node, e.g parent object or array */
-} jsmn_parser;
-
-/**
- * Create JSON parser over an array of tokens
- */
-void jsmn_init(jsmn_parser *parser);
-
-/**
- * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
- * a single JSON object.
- */
-jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js,
- jsmntok_t *tokens, unsigned int num_tokens);
-
-#endif /* __JSMN_H_ */
diff --git a/src/json_plist.c b/src/json_plist.c
deleted file mode 100644
index 7bbead0..0000000
--- a/src/json_plist.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * json_plist.c
- * JSON/property list functions
- *
- * Copyright (c) 2013 Nikias Bassen. All Rights Reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsmn.h>
-#include <plist/plist.h>
-
-#include "json_plist.h"
-
-static plist_t parse_primitive(const char* js, jsmntok_t* tokens, int* index);
-static plist_t parse_string(const char* js, jsmntok_t* tokens, int* index);
-static plist_t parse_array(const char* js, jsmntok_t* tokens, int* index);
-static plist_t parse_object(const char* js, jsmntok_t* tokens, int* index);
-
-static char* get_string_value(const char* js, jsmntok_t token)
-{
- int len = (token.end - token.start);
- char* str = malloc(len+1);
- memcpy(str, js + token.start, len);
- str[len] = 0;
- return str;
-}
-
-static plist_t parse_primitive(const char* js, jsmntok_t* tokens, int* index)
-{
- if (tokens[*index].type != JSMN_PRIMITIVE) {
- fprintf(stderr, "%s: ERROR: token type != JSMN_PRIMITIVE?!\n", __func__);
- return NULL;
- }
- plist_t val = NULL;
- char* strval = get_string_value(js, tokens[*index]);
- if (strval[0] == 'f') {
- val = plist_new_bool(0);
- } else if (strval[0] == 't') {
- val = plist_new_bool(1);
- } else if ((strval[0] == '-') || ((strval[0] >= '0') && (strval[0] <= '9'))) {
- val = plist_new_uint(strtoll(strval, NULL, 10));
- } else {
- fprintf(stderr, "%s: WARNING: invalid primitive value '%s' encountered, will return as string\n", __func__, strval);
- val = plist_new_string(strval);
- }
- free(strval);
- (*index)++;
- return val;
-}
-
-static plist_t parse_string(const char* js, jsmntok_t* tokens, int* index)
-{
- if (tokens[*index].type != JSMN_STRING) {
- fprintf(stderr, "%s: ERROR: token type != JSMN_STRING?!\n", __func__);
- return NULL;
- }
- char* str = get_string_value(js, tokens[*index]);
- plist_t val = plist_new_string(str);
- free(str);
- (*index)++;
- return val;
-}
-
-static plist_t parse_array(const char* js, jsmntok_t* tokens, int* index)
-{
- if (tokens[*index].type != JSMN_ARRAY) {
- fprintf(stderr, "%s: ERROR: token type != JSMN_ARRAY?!\n", __func__);
- return NULL;
- }
- plist_t arr = plist_new_array();
- int num_tokens = tokens[*index].size;
- int num;
- int j = (*index)+1;
- for (num = 0; num < num_tokens; num++) {
- plist_t val = NULL;
- switch (tokens[j].type) {
- case JSMN_OBJECT:
- val = parse_object(js, tokens, &j);
- break;
- case JSMN_ARRAY:
- val = parse_array(js, tokens, &j);
- break;
- case JSMN_STRING:
- val = parse_string(js, tokens, &j);
- break;
- case JSMN_PRIMITIVE:
- val = parse_primitive(js, tokens, &j);
- break;
- default:
- break;
- }
- if (val) {
- plist_array_append_item(arr, val);
- }
- }
- *(index) = j;
- return arr;
-}
-
-static plist_t parse_object(const char* js, jsmntok_t* tokens, int* index)
-{
- if (tokens[*index].type != JSMN_OBJECT) {
- fprintf(stderr, "%s: ERROR: token type != JSMN_OBJECT?!\n", __func__);
- return NULL;
- }
- plist_t obj = plist_new_dict();
- int num_tokens = tokens[*index].size;
- int num;
- int j = (*index)+1;
- for (num = 0; num < num_tokens; num++) {
- if (tokens[j].type == JSMN_STRING) {
- char* key = get_string_value(js, tokens[j]);
- plist_t val = NULL;
- j++;
- num++;
- switch (tokens[j].type) {
- case JSMN_OBJECT:
- val = parse_object(js, tokens, &j);
- break;
- case JSMN_ARRAY:
- val = parse_array(js, tokens, &j);
- break;
- case JSMN_STRING:
- val = parse_string(js, tokens, &j);
- break;
- case JSMN_PRIMITIVE:
- val = parse_primitive(js, tokens, &j);
- break;
- default:
- break;
- }
- if (val) {
- plist_dict_set_item(obj, key, val);
- }
- free(key);
- } else {
- fprintf(stderr, "%s: keys must be of type STRING\n", __func__);
- return NULL;
- }
- }
- (*index) = j;
- return obj;
-}
-
-plist_t json_to_plist(const char* json_string)
-{
- jsmn_parser parser;
- jsmn_init(&parser);
- int maxtoks = 256;
- jsmntok_t *tokens;
-
- if (!json_string) {
- fprintf(stderr, "%s: ERROR: no JSON string given.\n", __func__);
- return NULL;
- }
-
- tokens = malloc(sizeof(jsmntok_t)*maxtoks);
- if (!tokens) {
- fprintf(stderr, "%s: Out of memory\n", __func__);
- return NULL;
- }
-
- int r = 0;
-reparse:
- r = jsmn_parse(&parser, json_string, tokens, maxtoks);
- if (r == JSMN_ERROR_NOMEM) {
- //printf("not enough tokens (%d), retrying...\n", maxtoks);
- maxtoks+=256;
- jsmntok_t* newtokens = realloc(tokens, sizeof(jsmntok_t)*maxtoks);
- if (newtokens) {
- tokens = newtokens;
- goto reparse;
- }
- }
-
- switch(r) {
- case JSMN_ERROR_NOMEM:
- fprintf(stderr, "%s: ERROR: Out of memory...\n", __func__);
- return NULL;
- case JSMN_ERROR_INVAL:
- fprintf(stderr, "%s: ERROR: Invalid character inside JSON string\n", __func__);
- return NULL;
- case JSMN_ERROR_PART:
- fprintf(stderr, "%s: ERROR: The string is not a full JSON packet, more bytes expected\n", __func__);
- return NULL;
- default:
- break;
- }
-
- int startindex = 0;
- plist_t plist = NULL;
- switch (tokens[startindex].type) {
- case JSMN_PRIMITIVE:
- plist = parse_primitive(json_string, tokens, &startindex);
- break;
- case JSMN_STRING:
- plist = parse_string(json_string, tokens, &startindex);
- break;
- case JSMN_ARRAY:
- plist = parse_array(json_string, tokens, &startindex);
- break;
- case JSMN_OBJECT:
- plist = parse_object(json_string, tokens, &startindex);
- break;
- default:
- break;
- }
-
- free(tokens);
-
- return plist;
-}
-
diff --git a/src/json_plist.h b/src/json_plist.h
deleted file mode 100644
index d6eec0b..0000000
--- a/src/json_plist.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * json_plist.h
- * JSON/property list functions (header file)
- *
- * Copyright (c) 2013 Nikias Bassen. All Rights Reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __JSON_PLIST_H
-#define __JSON_PLIST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-plist_t json_to_plist(const char* json_string);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif