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-safeHEADmaster
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)
{
plist_data_t data = plist_new_plist_data();
data->type = PLIST_DATA;
+if (val && length) {
data->buff = (uint8_t *) malloc(length);
memcpy(data->buff, val, length);
+}
data->length = length;
return plist_new_node(data);
}
@@ -1422,15 +1424,21 @@ int plist_data_compare(const void *a, const void *b)
plist_data_t val_a = NULL;
plist_data_t val_b = NULL;
- if (!a || !b)
- return FALSE;
+ if (a == b)
+ return TRUE;
- if (!((node_t) a)->data || !((node_t) b)->data)
+ if (!a || !b)
return FALSE;
val_a = plist_get_data((plist_t) a);
val_b = plist_get_data((plist_t) b);
+ if (val_a == NULL && val_b == NULL)
+ return TRUE;
+
+ if (val_a == NULL || val_b == NULL)
+ return FALSE;
+
if (val_a->type != val_b->type)
return FALSE;
@@ -1442,28 +1450,30 @@ int plist_data_compare(const void *a, const void *b)
case PLIST_REAL:
case PLIST_DATE:
case PLIST_UID:
- if (val_a->length != val_b->length)
- return FALSE;
- return val_a->intval == val_b->intval; //it is an union so this is sufficient
+ return val_a->length == val_b->length
+ && val_a->intval == val_b->intval; // it is a union so this is sufficient
case PLIST_KEY:
case PLIST_STRING:
+ if (!val_a->strval || !val_b->strval)
+ return val_a->strval == val_b->strval;
return strcmp(val_a->strval, val_b->strval) == 0;
- case PLIST_DATA:
+ case PLIST_DATA: {
if (val_a->length != val_b->length)
return FALSE;
+ if (val_a->length == 0)
+ return TRUE;
return memcmp(val_a->buff, val_b->buff, val_a->length) == 0;
-
+ }
case PLIST_ARRAY:
case PLIST_DICT:
//compare pointer
return a == b;
default:
- break;
+ return FALSE;
}
- return FALSE;
}
char plist_compare_node_value(plist_t node_l, plist_t node_r)