summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2014-05-23 11:01:57 +0200
committerGravatar Nikias Bassen2014-05-23 11:01:57 +0200
commit6c0bf73f0773873edf8754246c291235aa217e7a (patch)
treec8b3023f702ff98cb92cb437ed65b37a7e6b1797 /src
parent8ac53f53b60e0ac22b4f41f67c3f1f0526e1abb2 (diff)
downloadlibplist-6c0bf73f0773873edf8754246c291235aa217e7a.tar.gz
libplist-6c0bf73f0773873edf8754246c291235aa217e7a.tar.bz2
Handle signed vs. unsigned integer values correctly
Diffstat (limited to 'src')
-rw-r--r--src/bplist.c27
-rw-r--r--src/xplist.c31
2 files changed, 53 insertions, 5 deletions
diff --git a/src/bplist.c b/src/bplist.c
index d1694b9..c4b2e13 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -212,6 +212,12 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
212 case sizeof(uint64_t): 212 case sizeof(uint64_t):
213 memcpy(&data->intval, bnode, size); 213 memcpy(&data->intval, bnode, size);
214 data->intval = UINT_TO_HOST(&data->intval, size); 214 data->intval = UINT_TO_HOST(&data->intval, size);
215 data->length = sizeof(uint64_t);
216 break;
217 case 16:
218 memcpy(&data->intval, bnode+8, sizeof(uint64_t));
219 data->intval = UINT_TO_HOST(&data->intval, sizeof(uint64_t));
220 data->length = size;
215 break; 221 break;
216 default: 222 default:
217 free(data); 223 free(data);
@@ -220,7 +226,6 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
220 226
221 *next_object = bnode + size; 227 *next_object = bnode + size;
222 data->type = PLIST_UINT; 228 data->type = PLIST_UINT;
223 data->length = sizeof(uint64_t);
224 229
225 return node_create(NULL, data); 230 return node_create(NULL, data);
226} 231}
@@ -833,6 +838,20 @@ static void write_int(bytearray_t * bplist, uint64_t val)
833 free(buff); 838 free(buff);
834} 839}
835 840
841static void write_uint(bytearray_t * bplist, uint64_t val)
842{
843 uint64_t size = 16;
844 uint8_t *buff = NULL;
845
846 buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
847 buff[0] = BPLIST_UINT | 4;
848 memset(buff + 1, '\0', 8);
849 memcpy(buff + 9, &val, 8);
850 byte_convert(buff + 9, 8);
851 byte_array_append(bplist, buff, sizeof(uint8_t) + size);
852 free(buff);
853}
854
836static void write_real(bytearray_t * bplist, double val) 855static void write_real(bytearray_t * bplist, double val)
837{ 856{
838 uint64_t size = get_real_bytes(val); //cheat to know used space 857 uint64_t size = get_real_bytes(val); //cheat to know used space
@@ -1143,7 +1162,11 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
1143 break; 1162 break;
1144 1163
1145 case PLIST_UINT: 1164 case PLIST_UINT:
1146 write_int(bplist_buff, data->intval); 1165 if (data->length == 16) {
1166 write_uint(bplist_buff, data->intval);
1167 } else {
1168 write_int(bplist_buff, data->intval);
1169 }
1147 break; 1170 break;
1148 1171
1149 case PLIST_REAL: 1172 case PLIST_REAL:
diff --git a/src/xplist.c b/src/xplist.c
index d953e23..eaa2468 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -184,7 +184,11 @@ static void node_to_xml(node_t* node, void *xml_struct)
184 case PLIST_UINT: 184 case PLIST_UINT:
185 tag = XPLIST_INT; 185 tag = XPLIST_INT;
186 val = (char*)malloc(64); 186 val = (char*)malloc(64);
187 (void)snprintf(val, 64, "%"PRIu64, node_data->intval); 187 if (node_data->length == 16) {
188 (void)snprintf(val, 64, "%"PRIu64, node_data->intval);
189 } else {
190 (void)snprintf(val, 64, "%"PRIi64, node_data->intval);
191 }
188 break; 192 break;
189 193
190 case PLIST_REAL: 194 case PLIST_REAL:
@@ -377,9 +381,30 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
377 if (!xmlStrcmp(node->name, XPLIST_INT)) 381 if (!xmlStrcmp(node->name, XPLIST_INT))
378 { 382 {
379 xmlChar *strval = xmlNodeGetContent(node); 383 xmlChar *strval = xmlNodeGetContent(node);
380 data->intval = strtoull((char*)strval, NULL, 0); 384 int is_negative = 0;
385 char *str = (char*)strval;
386 if ((str[0] == '-') || (str[0] == '+')) {
387 if (str[0] == '-') {
388 is_negative = 1;
389 }
390 str++;
391 }
392 char* endp = NULL;
393 data->intval = strtoull((char*)str, &endp, 0);
394 if ((endp != NULL) && (strlen(endp) > 0)) {
395 fprintf(stderr, "%s: integer parse error: string contains invalid characters: '%s'\n", __func__, endp);
396 }
397 if (is_negative || (data->intval <= INT64_MAX)) {
398 int64_t v = data->intval;
399 if (is_negative) {
400 v = -v;
401 }
402 data->intval = (uint64_t)v;
403 data->length = 8;
404 } else {
405 data->length = 16;
406 }
381 data->type = PLIST_UINT; 407 data->type = PLIST_UINT;
382 data->length = 8;
383 xmlFree(strval); 408 xmlFree(strval);
384 continue; 409 continue;
385 } 410 }