summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2026-01-12 01:30:44 +0100
committerGravatar Nikias Bassen2026-01-12 01:32:25 +0100
commitc74e34edda2cd76194a09e76f945cfa89dd41a79 (patch)
treec23304b3e95e89a738f6abf1e2a12dda2d0f2cef
parent15164ebe870590376b2286b09dc97890a07dd373 (diff)
downloadlibplist-c74e34edda2cd76194a09e76f945cfa89dd41a79.tar.gz
libplist-c74e34edda2cd76194a09e76f945cfa89dd41a79.tar.bz2
plist: make plist_data_compare NULL-safe
Ensure plist_data_compare safely handles NULL inputs by normalizing NULL data to empty values and avoiding invalid dereferences.
-rw-r--r--src/plist.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/plist.c b/src/plist.c
index fe98f34..17b8419 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -515,8 +515,10 @@ plist_t plist_new_data(const char *val, uint64_t length)
515{ 515{
516 plist_data_t data = plist_new_plist_data(); 516 plist_data_t data = plist_new_plist_data();
517 data->type = PLIST_DATA; 517 data->type = PLIST_DATA;
518if (val && length) {
518 data->buff = (uint8_t *) malloc(length); 519 data->buff = (uint8_t *) malloc(length);
519 memcpy(data->buff, val, length); 520 memcpy(data->buff, val, length);
521}
520 data->length = length; 522 data->length = length;
521 return plist_new_node(data); 523 return plist_new_node(data);
522} 524}
@@ -1422,15 +1424,21 @@ int plist_data_compare(const void *a, const void *b)
1422 plist_data_t val_a = NULL; 1424 plist_data_t val_a = NULL;
1423 plist_data_t val_b = NULL; 1425 plist_data_t val_b = NULL;
1424 1426
1425 if (!a || !b) 1427 if (a == b)
1426 return FALSE; 1428 return TRUE;
1427 1429
1428 if (!((node_t) a)->data || !((node_t) b)->data) 1430 if (!a || !b)
1429 return FALSE; 1431 return FALSE;
1430 1432
1431 val_a = plist_get_data((plist_t) a); 1433 val_a = plist_get_data((plist_t) a);
1432 val_b = plist_get_data((plist_t) b); 1434 val_b = plist_get_data((plist_t) b);
1433 1435
1436 if (val_a == NULL && val_b == NULL)
1437 return TRUE;
1438
1439 if (val_a == NULL || val_b == NULL)
1440 return FALSE;
1441
1434 if (val_a->type != val_b->type) 1442 if (val_a->type != val_b->type)
1435 return FALSE; 1443 return FALSE;
1436 1444
@@ -1442,28 +1450,30 @@ int plist_data_compare(const void *a, const void *b)
1442 case PLIST_REAL: 1450 case PLIST_REAL:
1443 case PLIST_DATE: 1451 case PLIST_DATE:
1444 case PLIST_UID: 1452 case PLIST_UID:
1445 if (val_a->length != val_b->length) 1453 return val_a->length == val_b->length
1446 return FALSE; 1454 && val_a->intval == val_b->intval; // it is a union so this is sufficient
1447 return val_a->intval == val_b->intval; //it is an union so this is sufficient
1448 1455
1449 case PLIST_KEY: 1456 case PLIST_KEY:
1450 case PLIST_STRING: 1457 case PLIST_STRING:
1458 if (!val_a->strval || !val_b->strval)
1459 return val_a->strval == val_b->strval;
1451 return strcmp(val_a->strval, val_b->strval) == 0; 1460 return strcmp(val_a->strval, val_b->strval) == 0;
1452 1461
1453 case PLIST_DATA: 1462 case PLIST_DATA: {
1454 if (val_a->length != val_b->length) 1463 if (val_a->length != val_b->length)
1455 return FALSE; 1464 return FALSE;
1465 if (val_a->length == 0)
1466 return TRUE;
1456 return memcmp(val_a->buff, val_b->buff, val_a->length) == 0; 1467 return memcmp(val_a->buff, val_b->buff, val_a->length) == 0;
1457 1468 }
1458 case PLIST_ARRAY: 1469 case PLIST_ARRAY:
1459 case PLIST_DICT: 1470 case PLIST_DICT:
1460 //compare pointer 1471 //compare pointer
1461 return a == b; 1472 return a == b;
1462 1473
1463 default: 1474 default:
1464 break; 1475 return FALSE;
1465 } 1476 }
1466 return FALSE;
1467} 1477}
1468 1478
1469char plist_compare_node_value(plist_t node_l, plist_t node_r) 1479char plist_compare_node_value(plist_t node_l, plist_t node_r)