diff options
author | Jonathan Beck | 2008-12-12 22:05:44 +0100 |
---|---|---|
committer | Jonathan Beck | 2008-12-12 22:05:44 +0100 |
commit | 9ca887308d59e6cb5bf684f9f3bd968118e8014f (patch) | |
tree | 14dd1cffa8e082ea71fcc8e7fdf878655cd98a3e | |
parent | 31379321cec6bf6c6d670e0738d1b1e23dc92ac1 (diff) | |
download | libimobiledevice-9ca887308d59e6cb5bf684f9f3bd968118e8014f.tar.gz libimobiledevice-9ca887308d59e6cb5bf684f9f3bd968118e8014f.tar.bz2 |
Fix some bugs in binary plist generation.
-rw-r--r-- | dev/plutil.c | 37 | ||||
-rw-r--r-- | src/bplist.c | 29 | ||||
-rw-r--r-- | src/lockdown.c | 105 | ||||
-rw-r--r-- | src/plist.c | 27 | ||||
-rw-r--r-- | src/plist.h | 20 | ||||
-rw-r--r-- | src/xplist.c | 26 |
6 files changed, 129 insertions, 115 deletions
diff --git a/dev/plutil.c b/dev/plutil.c index e76506e..3d93797 100644 --- a/dev/plutil.c +++ b/dev/plutil.c @@ -14,9 +14,7 @@ int main(int argc, char *argv[]) { struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); - uint32_t position = 0; Options *options = parse_arguments(argc, argv); - int argh = 0; if (!options) { print_usage(); @@ -25,29 +23,42 @@ int main(int argc, char *argv[]) iphone_set_debug(options->debug); - FILE *bplist = fopen(options->in_file, "r"); - + //read input file + FILE *iplist = fopen(options->in_file, "r"); + if (!iplist) + return 1; stat(options->in_file, filestats); + char *plist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1)); + fread(plist_entire, sizeof(char), filestats->st_size, iplist); + fclose(iplist); - char *bplist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1)); - argh = fread(bplist_entire, sizeof(char), filestats->st_size, bplist); - fclose(bplist); - // bplist_entire contains our stuff + //convert one format to another plist_t root_node = NULL; char *plist_out = NULL; int size = 0; - if (memcmp(bplist_entire, "bplist00", 8) == 0) { - bin_to_plist(bplist_entire, filestats->st_size, &root_node); + if (memcmp(plist_entire, "bplist00", 8) == 0) { + bin_to_plist(plist_entire, filestats->st_size, &root_node); plist_to_xml(root_node, &plist_out, &size); } else { - xml_to_plist(bplist_entire, filestats->st_size, &root_node); + xml_to_plist(plist_entire, filestats->st_size, &root_node); plist_to_bin(root_node, &plist_out, &size); } - - printf("%s\n", plist_out); + if (plist_out) { + if (options->out_file != NULL) { + FILE *oplist = fopen(options->out_file, "wb"); + if (!oplist) + return 1; + fwrite(plist_out, size, sizeof(char), oplist); + fclose(oplist); + } + //if no output file specified, write to stdout + else + fwrite(plist_out, size, sizeof(char), stdout); + } else + printf("ERROR\n"); return 0; } diff --git a/src/bplist.c b/src/bplist.c index 6136fe9..a5b1c9b 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -567,15 +567,15 @@ void serialize_plist(GNode * node, gpointer data) return; } - +#define Log2(x) (x == 8 ? 3 : (x == 4 ? 2 : (x == 2 ? 1 : 0))) void write_int(GByteArray * bplist, uint64_t val) { uint64_t size = get_needed_bytes(val); uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); - buff[0] = BPLIST_UINT | size >> 1; + buff[0] = BPLIST_UINT | Log2(size); memcpy(buff + 1, &val, size); - swap_n_bytes(buff + 1, size); + byte_convert(buff + 1, size); g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); free(buff); } @@ -584,9 +584,9 @@ void write_real(GByteArray * bplist, double val) { uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); - buff[0] = BPLIST_REAL | size >> 1; + buff[0] = BPLIST_REAL | Log2(size); memcpy(buff + 1, &val, size); - swap_n_bytes(buff + 1, size); + byte_convert(buff + 1, size); g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); free(buff); } @@ -638,7 +638,7 @@ void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) { idx = GPOINTER_TO_UINT(g_hash_table_lookup(ref_table, cur)); memcpy(buff + i * dict_param_size, &idx, dict_param_size); - swap_n_bytes(buff + i * dict_param_size, dict_param_size); + byte_convert(buff + i * dict_param_size, dict_param_size); } //now append to bplist @@ -650,7 +650,7 @@ void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) { uint64_t size = g_node_n_children(node) / 2; - uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf); + uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf); g_byte_array_append(bplist, &marker, sizeof(uint8_t)); if (size >= 15) { GByteArray *int_buff = g_byte_array_new(); @@ -668,22 +668,24 @@ void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8 for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) { idx1 = GPOINTER_TO_UINT(g_hash_table_lookup(ref_table, cur)); memcpy(buff + i * dict_param_size, &idx1, dict_param_size); - swap_n_bytes(buff + i * dict_param_size, dict_param_size); + byte_convert(buff + i * dict_param_size, dict_param_size); idx2 = GPOINTER_TO_UINT(g_hash_table_lookup(ref_table, cur->next)); memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size); - swap_n_bytes(buff + (i + size) * dict_param_size, dict_param_size); + byte_convert(buff + (i + size) * dict_param_size, dict_param_size); } //now append to bplist - g_byte_array_append(bplist, buff, size * dict_param_size); + g_byte_array_append(bplist, buff, size * 2 * dict_param_size); free(buff); } void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) { - //first serialize tree + //check for valid input + if (!plist || !plist_bin || *plist_bin || !length) + return; //list of objects GPtrArray *objects = g_ptr_array_new(); @@ -692,7 +694,7 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) //serialize plist struct serialize_s ser_s = { objects, ref_table }; - g_node_children_foreach(plist, G_TRAVERSE_ALL, serialize_plist, &ser_s); + serialize_plist(plist, &ser_s); //now stream to output buffer uint8_t offset_size = 0; //unknown yet @@ -759,10 +761,11 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) //write offsets offset_size = get_needed_bytes(bplist_buff->len); + offset_table_index = bplist_buff->len; for (i = 0; i <= num_objects; i++) { uint8_t *buff = (uint8_t *) malloc(offset_size); memcpy(buff, offsets + i, offset_size); - swap_n_bytes(buff, offset_size); + byte_convert(buff, offset_size); g_byte_array_append(bplist_buff, buff, offset_size); free(buff); } diff --git a/src/lockdown.c b/src/lockdown.c index 0957fa2..4c96a7d 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -177,11 +177,8 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) int bytes = 0, i = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - plist_t plist = NULL; - plist_new_plist(&plist); - - dict_t dict = NULL; - plist_new_dict_in_plist(plist, &dict); + plist_t dict = NULL; + plist_new_dict(&dict); plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType"); @@ -189,23 +186,23 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) char *XML_content = NULL; uint32_t length = 0; - plist_to_xml(plist, &XML_content, &length); + plist_to_xml(dict, &XML_content, &length); log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); ret = iphone_lckd_send(control, XML_content, length, &bytes); xmlFree(XML_content); XML_content = NULL; - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; ret = iphone_lckd_recv(control, &XML_content, &bytes); log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - xml_to_plist(XML_content, bytes, &plist); + xml_to_plist(XML_content, bytes, &dict); - if (!plist) + if (!dict) return IPHONE_E_PLIST_ERROR; - plist_t query_node = find_query_node(plist, "Request", "QueryType"); + plist_t query_node = find_query_node(dict, "Request", "QueryType"); plist_t result_node = g_node_next_sibling(query_node); plist_t value_node = g_node_next_sibling(result_node); @@ -239,19 +236,18 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r { if (!control || !req_key || !value || (value && *value)) return IPHONE_E_INVALID_ARG; - plist_t plist = NULL; - dict_t dict = NULL; + + plist_t dict = NULL; int bytes = 0, i = 0; char *XML_content = NULL; uint32_t length = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; /* Setup DevicePublicKey request plist */ - plist_new_plist(&plist); - plist_new_dict_in_plist(plist, &dict); + plist_new_dict(&dict); plist_add_dict_element(dict, req_key, PLIST_STRING, (void *) req_string); plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "GetValue"); - plist_to_xml(plist, &XML_content, &length); + plist_to_xml(dict, &XML_content, &length); /* send to iPhone */ log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); @@ -259,8 +255,8 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r xmlFree(XML_content); XML_content = NULL; - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; if (ret != IPHONE_E_SUCCESS) return ret; @@ -272,11 +268,11 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r if (ret != IPHONE_E_SUCCESS) return ret; - xml_to_plist(XML_content, bytes, &plist); - if (!plist) + xml_to_plist(XML_content, bytes, &dict); + if (!dict) return IPHONE_E_PLIST_ERROR; - plist_t query_node = find_query_node(plist, "Request", "GetValue"); + plist_t query_node = find_query_node(dict, "Request", "GetValue"); plist_t result_key_node = g_node_next_sibling(query_node); plist_t result_value_node = g_node_next_sibling(result_key_node); @@ -314,7 +310,7 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r ret = IPHONE_E_SUCCESS; } - plist_free(plist); + plist_free(dict); free(XML_content); return ret; } @@ -408,9 +404,8 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id) { iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - plist_t plist = NULL; - dict_t dict = NULL; - dict_t dict_record = NULL; + plist_t dict = NULL; + plist_t dict_record = NULL; int bytes = 0, i = 0; char *XML_content = NULL; uint32_t length = 0; @@ -433,8 +428,7 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch } /* Setup Pair request plist */ - plist_new_plist(&plist); - plist_new_dict_in_plist(plist, &dict); + plist_new_dict(&dict); plist_add_dict_element(dict, "PairRecord", PLIST_DICT, NULL); dict_record = g_node_last_child(dict); plist_add_dict_element(dict_record, "DeviceCertificate", PLIST_DATA, (void *) device_cert_b64); @@ -442,15 +436,15 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch plist_add_dict_element(dict_record, "HostID", PLIST_STRING, (void *) host_id); plist_add_dict_element(dict_record, "RootCertificate", PLIST_DATA, (void *) root_cert_b64); plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "Pair"); - plist_to_xml(plist, &XML_content, &length); + plist_to_xml(dict, &XML_content, &length); log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content); /* send to iPhone */ ret = iphone_lckd_send(control, XML_content, length, &bytes); xmlFree(XML_content); - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; if (ret != IPHONE_E_SUCCESS) return ret; @@ -465,11 +459,11 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch log_debug_msg(XML_content); log_debug_msg("\n\n"); - xml_to_plist(XML_content, bytes, &plist); - if (!plist) + xml_to_plist(XML_content, bytes, &dict); + if (!dict) return IPHONE_E_PLIST_ERROR; - plist_t query_node = find_query_node(plist, "Request", "Pair"); + plist_t query_node = find_query_node(dict, "Request", "Pair"); plist_t result_key_node = g_node_next_sibling(query_node); plist_t result_value_node = g_node_next_sibling(result_key_node); @@ -635,27 +629,25 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_ */ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID) { - plist_t plist = NULL; - dict_t dict = NULL; + plist_t dict = NULL; char *XML_content = NULL; uint32_t length = 0, bytes = 0, return_me = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; /* Setup DevicePublicKey request plist */ - plist_new_plist(&plist); - plist_new_dict_in_plist(plist, &dict); + plist_new_dict(&dict); plist_add_dict_element(dict, "HostID", PLIST_STRING, (void *) HostID); plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartSession"); - plist_to_xml(plist, &XML_content, &length); + plist_to_xml(dict, &XML_content, &length); log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); ret = iphone_lckd_send(control, XML_content, length, &bytes); xmlFree(XML_content); XML_content = NULL; - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; if (ret != IPHONE_E_SUCCESS) return ret; @@ -663,11 +655,11 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c if (bytes > 0) { ret = iphone_lckd_recv(control, &XML_content, &bytes); log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - xml_to_plist(XML_content, bytes, &plist); - if (!plist) + xml_to_plist(XML_content, bytes, &dict); + if (!dict) return IPHONE_E_PLIST_ERROR; - plist_t query_node = find_query_node(plist, "Request", "StartSession"); + plist_t query_node = find_query_node(dict, "Request", "StartSession"); plist_t result_key_node = g_node_next_sibling(query_node); plist_t result_value_node = g_node_next_sibling(result_key_node); @@ -681,8 +673,8 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c xmlFree(XML_content); XML_content = NULL; - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { @@ -871,8 +863,7 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char return IPHONE_E_SSL_ERROR; - plist_t plist = NULL; - dict_t dict = NULL; + plist_t dict = NULL; char *XML_content = NULL; uint32_t length, i = 0, port_loc = 0, bytes = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; @@ -880,11 +871,10 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char free(host_id); host_id = NULL; - plist_new_plist(&plist); - plist_new_dict_in_plist(plist, &dict); + plist_new_dict(&dict); plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartService"); plist_add_dict_element(dict, "Service", PLIST_STRING, (void *) service); - plist_to_xml(plist, &XML_content, &length); + plist_to_xml(dict, &XML_content, &length); /* send to iPhone */ log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); @@ -892,8 +882,8 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char xmlFree(XML_content); XML_content = NULL; - plist_free(plist); - plist = NULL; + plist_free(dict); + dict = NULL; if (IPHONE_E_SUCCESS != ret) return ret; @@ -903,8 +893,8 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char if (IPHONE_E_SUCCESS != ret) return ret; - xml_to_plist(XML_content, bytes, &plist); - if (!plist) + xml_to_plist(XML_content, bytes, &dict); + if (!dict) return IPHONE_E_PLIST_ERROR; @@ -912,11 +902,11 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char return IPHONE_E_NOT_ENOUGH_DATA; else { - plist_t query_node = find_query_node(plist, "Request", "StartService"); + plist_t query_node = find_query_node(dict, "Request", "StartService"); plist_t result_key_node = g_node_next_sibling(query_node); plist_t result_value_node = g_node_next_sibling(result_key_node); - plist_t port_key_node = find_node(plist, PLIST_KEY, "Port"); + plist_t port_key_node = find_node(dict, PLIST_KEY, "Port"); plist_t port_value_node = g_node_next_sibling(port_key_node); plist_type result_key_type; @@ -947,7 +937,8 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char log_debug_msg("end data received by lockdownd_start_service()\n"); free(XML_content); - plist_free(plist); + plist_free(dict); + dict = NULL; if (port && ret == IPHONE_E_SUCCESS) { *port = port_loc; return IPHONE_E_SUCCESS; diff --git a/src/plist.c b/src/plist.c index 76ae954..66a74c3 100644 --- a/src/plist.c +++ b/src/plist.c @@ -29,7 +29,7 @@ #include <stdio.h> -void plist_new_plist(plist_t * plist) +void plist_new_dict(plist_t * plist) { if (*plist != NULL) return; @@ -38,7 +38,16 @@ void plist_new_plist(plist_t * plist) *plist = g_node_new(data); } -void plist_new_dict_in_plist(plist_t plist, dict_t * dict) +void plist_new_array(plist_t * plist) +{ + if (*plist != NULL) + return; + struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); + data->type = PLIST_ARRAY; + *plist = g_node_new(data); +} + +void plist_new_dict_in_plist(plist_t plist, plist_t * dict) { if (!plist || *dict) return; @@ -49,9 +58,6 @@ void plist_new_dict_in_plist(plist_t plist, dict_t * dict) g_node_append(plist, *dict); } -void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array) -{ -} /** Adds a new key pair to a dict. * @@ -61,7 +67,7 @@ void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void * * @param value a pointer to the actual buffer containing the value. WARNING : the buffer is supposed to match the type of the value * */ -void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value) +void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value) { if (!dict || !key || !value) return; @@ -110,7 +116,7 @@ void plist_free(plist_t plist) g_node_destroy(plist); } -GNode *find_query_node(plist_t plist, char *key, char *request) +plist_t find_query_node(plist_t plist, char *key, char *request) { if (!plist) return NULL; @@ -167,7 +173,7 @@ char compare_node_value(plist_type type, struct plist_data *data, void *value) return res; } -GNode *find_node(plist_t plist, plist_type type, void *value) +plist_t find_node(plist_t plist, plist_type type, void *value) { if (!plist) return NULL; @@ -228,7 +234,10 @@ void get_type_and_value(GNode * node, plist_type * type, void *value) plist_type plist_get_node_type(plist_t node) { - return ((struct plist_data *) node->data)->type; + if (node && node->data) + return ((struct plist_data *) node->data)->type; + else + return PLIST_NONE; } uint64_t plist_get_node_uint_val(plist_t node) diff --git a/src/plist.h b/src/plist.h index e3f3f59..ff4bdbf 100644 --- a/src/plist.h +++ b/src/plist.h @@ -30,8 +30,6 @@ #include <unistd.h> #include <glib.h> -char *format_string(const char *buf, int cols, int depth); - typedef enum { PLIST_BOOLEAN, @@ -44,6 +42,7 @@ typedef enum { PLIST_DATE, PLIST_DATA, PLIST_KEY, + PLIST_NONE } plist_type; @@ -63,13 +62,12 @@ struct plist_data { typedef GNode *plist_t; -typedef GNode *dict_t; -typedef GNode *array_t; -void plist_new_plist(plist_t * plist); -void plist_new_dict_in_plist(plist_t plist, dict_t * dict); -void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array); -void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value); + +void plist_new_dict(plist_t * plist); +void plist_new_array(plist_t * plist); +void plist_new_dict_in_plist(plist_t plist, plist_t * dict); +void plist_add_dict_element(plist_t dict, char *key, plist_type type, void *value); void plist_free(plist_t plist); void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); @@ -78,8 +76,8 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist); void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); -GNode *find_query_node(plist_t plist, char *key, char *request); -GNode *find_node(plist_t plist, plist_type type, void *value); -void get_type_and_value(GNode * node, plist_type * type, void *value); +plist_t find_query_node(plist_t plist, char *key, char *request); +plist_t find_node(plist_t plist, plist_type type, void *value); +void get_type_and_value(plist_t node, plist_type * type, void *value); #endif diff --git a/src/xplist.c b/src/xplist.c index a87b259..3e975f6 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -89,7 +89,7 @@ struct xml_node { * * @return The plist XML document. */ -xmlDocPtr new_plist() +xmlDocPtr new_xml_plist() { char *plist = strdup(plist_base); xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0); @@ -207,7 +207,7 @@ void node_to_xml(GNode * node, gpointer xml_struct) return; } -void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) +void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) { xmlNodePtr node = NULL; @@ -220,7 +220,10 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); GNode *subnode = g_node_new(data); - g_node_append(plist_node, subnode); + if (*plist_node) + g_node_append(*plist_node, subnode); + else + *plist_node = subnode; if (!xmlStrcmp(node->name, "true")) { data->boolval = 1; @@ -236,7 +239,7 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) if (!xmlStrcmp(node->name, "integer")) { char *strval = xmlNodeGetContent(node); - data->intval = atoi(strval); + data->intval = g_ascii_strtoull(strval, NULL, 0); data->type = PLIST_UINT; continue; } @@ -271,13 +274,13 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) if (!xmlStrcmp(node->name, "array")) { data->type = PLIST_ARRAY; - xml_to_node(node, subnode); + xml_to_node(node, &subnode); continue; } if (!xmlStrcmp(node->name, "dict")) { data->type = PLIST_DICT; - xml_to_node(node, subnode); + xml_to_node(node, &subnode); continue; } } @@ -287,10 +290,12 @@ void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) { if (!plist || !plist_xml || *plist_xml) return; - xmlDocPtr plist_doc = new_plist(); + xmlDocPtr plist_doc = new_xml_plist(); xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); struct xml_node root = { root_node, 0 }; - g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, &root); + + node_to_xml(plist, &root); + xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length); } @@ -299,8 +304,5 @@ void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist) xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0); xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); - struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); - *plist = g_node_new(data); - data->type = PLIST_DICT; - xml_to_node(root_node, *plist); + xml_to_node(root_node, plist); } |