From: Alexander Klauer Date: Tue, 8 Jan 2013 13:24:21 +0000 (+0100) Subject: Fixed json_object_object_add(). X-Git-Tag: json-c-0.13-20171207~176^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2be921d88376e78f84d79aafa6db2714da804e59;p=thirdparty%2Fjson-c.git Fixed json_object_object_add(). * Return value of json_object_object_add() changed from void to int. Return value now indicates success or failure. * Check whether allocations are successful. * Do not exit program from within the library. --- diff --git a/json_object.c b/json_object.c index 6060554a..39c93279 100644 --- a/json_object.c +++ b/json_object.c @@ -371,7 +371,7 @@ struct lh_table* json_object_get_object(struct json_object *jso) } } -void json_object_object_add(struct json_object* jso, const char *key, +int json_object_object_add(struct json_object* jso, const char *key, struct json_object *val) { // We lookup the entry and replace the value, rather than just deleting @@ -381,13 +381,19 @@ void json_object_object_add(struct json_object* jso, const char *key, existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key); if (!existing_entry) { - lh_table_insert(jso->o.c_object, strdup(key), val); - return; + char * keydup = strdup( key ); + if ( keydup == NULL ) { + return -1; + } + + return lh_table_insert(jso->o.c_object, keydup, val); } existing_value = (void *)existing_entry->v; if (existing_value) json_object_put(existing_value); existing_entry->v = val; + + return 0; } struct json_object* json_object_object_get(struct json_object* jso, const char *key) diff --git a/json_object.h b/json_object.h index 0ff65845..b7d37fee 100644 --- a/json_object.h +++ b/json_object.h @@ -230,8 +230,11 @@ extern struct lh_table* json_object_get_object(struct json_object *obj); * @param obj the json_object instance * @param key the object field name (a private copy will be duplicated) * @param val a json_object or NULL member to associate with the given field + * + * @return On success, 0 is returned. + * On error, a negative value is returned. */ -extern void json_object_object_add(struct json_object* obj, const char *key, +extern int json_object_object_add(struct json_object* obj, const char *key, struct json_object *val); /** Get the json_object associate with a given object field diff --git a/linkhash.c b/linkhash.c index ddedc126..b77cd5f1 100644 --- a/linkhash.c +++ b/linkhash.c @@ -63,17 +63,27 @@ struct lh_table* lh_table_new(int size, const char *name, struct lh_table *t; t = (struct lh_table*)calloc(1, sizeof(struct lh_table)); - if(!t) lh_abort("lh_table_new: calloc failed\n"); + if(!t) { + goto nomem; + } + t->count = 0; t->size = size; t->name = name; t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry)); - if(!t->table) lh_abort("lh_table_new: calloc failed\n"); + if(!t->table) { + goto notablemem; + } t->free_fn = free_fn; t->hash_fn = hash_fn; t->equal_fn = equal_fn; for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY; return t; + +notablemem: + free( t ); +nomem: + return NULL; } struct lh_table* lh_kchar_table_new(int size, const char *name, @@ -88,16 +98,20 @@ struct lh_table* lh_kptr_table_new(int size, const char *name, return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal); } -void lh_table_resize(struct lh_table *t, int new_size) +int lh_table_resize(struct lh_table *t, int new_size) { struct lh_table *new_t; - struct lh_entry *ent; new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn); - ent = t->head; - while(ent) { - lh_table_insert(new_t, ent->k, ent->v); - ent = ent->next; + if ( new_t == NULL ) { + goto nonewtable; + } + + for ( struct lh_entry * ent = t->head; ent != NULL; ent = ent->next ) { + int rc = lh_table_insert(new_t, ent->k, ent->v); + if ( rc != 0 ) { + goto noinsert; + } } free(t->table); t->table = new_t->table; @@ -106,6 +120,14 @@ void lh_table_resize(struct lh_table *t, int new_size) t->tail = new_t->tail; t->resizes++; free(new_t); + + return 0; + +noinsert: + free( new_t->table ); + free( new_t ); +nonewtable: + return -1; } void lh_table_free(struct lh_table *t) @@ -126,7 +148,12 @@ int lh_table_insert(struct lh_table *t, void *k, const void *v) unsigned long h, n; t->inserts++; - if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2); + if(t->count >= t->size * LH_LOAD_FACTOR) { + int rc = lh_table_resize(t, t->size * 2); + if ( rc != 0 ) { + return -1; + } + } h = t->hash_fn(k); n = h % t->size; diff --git a/linkhash.h b/linkhash.h index bbb54886..c834a3bc 100644 --- a/linkhash.h +++ b/linkhash.h @@ -182,7 +182,8 @@ for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) * @param equal_fn comparison function to compare keys. 2 standard ones defined: * lh_ptr_hash and lh_char_hash for comparing pointer values * and C strings respectively. - * @return a pointer onto the linkhash table. + * @return On success, a pointer to the new linkhash table is returned. + * On error, a null pointer is returned. */ extern struct lh_table* lh_table_new(int size, const char *name, lh_entry_free_fn *free_fn, @@ -195,7 +196,8 @@ extern struct lh_table* lh_table_new(int size, const char *name, * @param size initial table size. * @param name table name. * @param free_fn callback function used to free memory for entries. - * @return a pointer onto the linkhash table. + * @return On success, a pointer to the new linkhash table is returned. + * On error, a null pointer is returned. */ extern struct lh_table* lh_kchar_table_new(int size, const char *name, lh_entry_free_fn *free_fn); @@ -207,7 +209,8 @@ extern struct lh_table* lh_kchar_table_new(int size, const char *name, * @param size initial table size. * @param name table name. * @param free_fn callback function used to free memory for entries. - * @return a pointer onto the linkhash table. + * @return On success, a pointer to the new linkhash table is returned. + * On error, a null pointer is returned. */ extern struct lh_table* lh_kptr_table_new(int size, const char *name, lh_entry_free_fn *free_fn); @@ -227,6 +230,9 @@ extern void lh_table_free(struct lh_table *t); * @param t the table to insert into. * @param k a pointer to the key to insert. * @param v a pointer to the value to insert. + * + * @return On success, 0 is returned. + * On error, a negative value is returned. */ extern int lh_table_insert(struct lh_table *t, void *k, const void *v); @@ -280,9 +286,31 @@ extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e); */ extern int lh_table_delete(struct lh_table *t, const void *k); - +/** + * Prints a message to stdout, + * then exits the program with an exit code of 1. + * + * @param msg Message format string, like for printf. + * @param ... Format args. + * + * @deprecated Since it is not a good idea to exit the entire program + * because of an internal library failure, json-c will no longer + * use this function internally. + * However, because its interface is public, it will remain part of + * the API on the off chance of legacy software using it externally. + */ void lh_abort(const char *msg, ...); -void lh_table_resize(struct lh_table *t, int new_size); + +/** + * Resizes the specified table. + * + * @param t Pointer to table to resize. + * @param new_size New table size. Must be positive. + * + * @return On success, 0 is returned. + * On error, a negative value is returned. + */ +int lh_table_resize(struct lh_table *t, int new_size); #ifdef __cplusplus }