summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plist.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/src/plist.c b/src/plist.c
index 781f795..a9199ee 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -900,31 +900,39 @@ plist_t plist_dict_item_get_key(plist_t node)
plist_t plist_dict_get_item(plist_t node, const char* key)
{
plist_t ret = NULL;
-
- if (node && PLIST_DICT == plist_get_node_type(node))
- {
- plist_data_t data = plist_get_data(node);
- hashtable_t *ht = (hashtable_t*)data->hashtable;
- if (ht) {
- struct plist_data_s sdata;
- sdata.strval = (char*)key;
- sdata.length = strlen(key);
- ret = (plist_t)hash_table_lookup(ht, &sdata);
- } else {
- plist_t current = NULL;
- for (current = (plist_t)node_first_child((node_t)node);
- current;
- current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
- {
- data = plist_get_data(current);
- assert( PLIST_KEY == plist_get_node_type(current) );
-
- if (data && !strcmp(key, data->strval))
- {
- ret = (plist_t)node_next_sibling((node_t)current);
- break;
- }
+ if (!PLIST_IS_DICT(node) || !key) {
+ PLIST_ERR("invalid argument passed to %s (node=%p, key=%p)\n", __func__, node, key);
+ return NULL;
+ }
+ plist_data_t data = plist_get_data(node);
+ assert(data);
+ if (!data) {
+ PLIST_ERR("%s: invalid node\n", __func__);
+ return NULL;
+ }
+ size_t keylen = strlen(key);
+ hashtable_t *ht = (hashtable_t*)data->hashtable;
+ if (ht) {
+ struct plist_data_s sdata = { 0 };
+ sdata.strval = (char*)key;
+ sdata.length = keylen;
+ return (plist_t)hash_table_lookup(ht, &sdata);
+ } else {
+ plist_t k = NULL;
+ for (k = (plist_t)node_first_child((node_t)node); k; ) {
+ plist_t v = (plist_t)node_next_sibling(k);
+ if (!v) break;
+ data = plist_get_data(k);
+ assert(PLIST_IS_KEY(k));
+ if (!PLIST_IS_KEY(k) || !data || !data->strval) {
+ PLIST_ERR("invalid key node at %p\n", k);
+ break;
+ }
+ if (data->length == keylen && !memcmp(key, data->strval, keylen+1)) {
+ ret = v;
+ break;
}
+ k = node_next_sibling(v);
}
}
return ret;