Browse Source

Issue #236: Add -Wcast-qual and fix casts to retain constness.

To better distinguish between entry->k and entry->v being const within linkhash, but non-const outside, add lh_entry_v() and lh_entry_k() accessors.
Make lh_entry->k const.
tags/json-c-0.13-20171207
Eric Haszlakiewicz 9 years ago
parent
commit
595891729e
7 changed files with 61 additions and 33 deletions
  1. +1
    -1
      configure.ac
  2. +13
    -13
      json_object.c
  3. +7
    -5
      json_object.h
  4. +3
    -3
      json_object_iterator.c
  5. +5
    -5
      linkhash.c
  6. +31
    -5
      linkhash.h
  7. +1
    -1
      tests/test4.c

+ 1
- 1
configure.ac View File

@@ -103,7 +103,7 @@ AS_IF([test "x$enable_Bsymbolic" = "xcheck"],
AS_IF([test "x$enable_Bsymbolic" = "xyes"], [JSON_BSYMBOLIC_LDFLAGS=-Wl[,]-Bsymbolic-functions]) AS_IF([test "x$enable_Bsymbolic" = "xyes"], [JSON_BSYMBOLIC_LDFLAGS=-Wl[,]-Bsymbolic-functions])
AC_SUBST(JSON_BSYMBOLIC_LDFLAGS) AC_SUBST(JSON_BSYMBOLIC_LDFLAGS)


AX_APPEND_COMPILE_FLAGS([-Wall -Werror -Wno-error=deprecated-declarations])
AX_APPEND_COMPILE_FLAGS([-Wall -Werror -Wcast-qual -Wno-error=deprecated-declarations])
AX_APPEND_COMPILE_FLAGS([-Wextra -Wwrite-string -Wno-unused-parameter]) AX_APPEND_COMPILE_FLAGS([-Wextra -Wwrite-string -Wno-unused-parameter])
AX_APPEND_COMPILE_FLAGS([-D_GNU_SOURCE -D_REENTRANT]) AX_APPEND_COMPILE_FLAGS([-D_GNU_SOURCE -D_REENTRANT])




+ 13
- 13
json_object.c View File

@@ -84,7 +84,7 @@ static void json_object_fini(void)
json_object_table->count); json_object_table->count);
lh_foreach(json_object_table, ent) lh_foreach(json_object_table, ent)
{ {
struct json_object* obj = (struct json_object*)ent->v;
struct json_object* obj = (struct json_object*)lh_entry_v(ent);
MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj); MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
} }
} }
@@ -385,8 +385,8 @@ static int json_object_object_to_json_string(struct json_object* jso,
static void json_object_lh_entry_free(struct lh_entry *ent) static void json_object_lh_entry_free(struct lh_entry *ent)
{ {
if (!ent->k_is_constant) if (!ent->k_is_constant)
free(ent->k);
json_object_put((struct json_object*)ent->v);
free(lh_entry_k(ent));
json_object_put((struct json_object*)lh_entry_v(ent));
} }


static void json_object_object_delete(struct json_object* jso) static void json_object_object_delete(struct json_object* jso)
@@ -435,17 +435,17 @@ void json_object_object_add_ex(struct json_object* jso,
// and re-adding it, so the existing key remains valid. // and re-adding it, so the existing key remains valid.
json_object *existing_value = NULL; json_object *existing_value = NULL;
struct lh_entry *existing_entry; struct lh_entry *existing_entry;
const unsigned long hash = lh_get_hash(jso->o.c_object, (void*)key);
const unsigned long hash = lh_get_hash(jso->o.c_object, (const void *)key);
existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL : existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL :
lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
lh_table_lookup_entry_w_hash(jso->o.c_object, (const void *)key, hash);
if (!existing_entry) if (!existing_entry)
{ {
void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
(void*)key : strdup(key);
const void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
(const void *)key : strdup(key);
lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts); lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts);
return; return;
} }
existing_value = (json_object *)existing_entry->v;
existing_value = (json_object *)lh_entry_v(existing_entry);
if (existing_value) if (existing_value)
json_object_put(existing_value); json_object_put(existing_value);
existing_entry->v = val; existing_entry->v = val;
@@ -458,8 +458,8 @@ int json_object_object_add(struct json_object* jso, const char *key,
// and re-adding it, so the existing key remains valid. // and re-adding it, so the existing key remains valid.
json_object *existing_value = NULL; json_object *existing_value = NULL;
struct lh_entry *existing_entry; struct lh_entry *existing_entry;
const unsigned long hash = lh_get_hash(jso->o.c_object, (void*)key);
existing_entry = lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
const unsigned long hash = lh_get_hash(jso->o.c_object, (const void *)key);
existing_entry = lh_table_lookup_entry_w_hash(jso->o.c_object, (const void *)key, hash);
if (!existing_entry) if (!existing_entry)
{ {
char *keydup = strdup(key); char *keydup = strdup(key);
@@ -468,7 +468,7 @@ int json_object_object_add(struct json_object* jso, const char *key,


return lh_table_insert_w_hash(jso->o.c_object, keydup, val, hash, 0); return lh_table_insert_w_hash(jso->o.c_object, keydup, val, hash, 0);
} }
existing_value = (json_object *)existing_entry->v;
existing_value = (json_object *)lh_entry_v(existing_entry);
if (existing_value) if (existing_value)
json_object_put(existing_value); json_object_put(existing_value);
existing_entry->v = val; existing_entry->v = val;
@@ -500,7 +500,7 @@ json_bool json_object_object_get_ex(const struct json_object* jso, const char *k
switch(jso->o_type) switch(jso->o_type)
{ {
case json_type_object: case json_type_object:
return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
return lh_table_lookup_ex(jso->o.c_object, (const void *)key, (void**)value);
default: default:
if (value != NULL) if (value != NULL)
*value = NULL; *value = NULL;
@@ -865,7 +865,7 @@ struct json_object* json_object_new_string_len(const char *s, int len)
} }
dstbuf = jso->o.c_string.str.ptr; dstbuf = jso->o.c_string.str.ptr;
} }
memcpy(dstbuf, (void *)s, len);
memcpy(dstbuf, (const void *)s, len);
dstbuf[len] = '\0'; dstbuf[len] = '\0';
jso->o.c_string.len = len; jso->o.c_string.len = len;
return jso; return jso;


+ 7
- 5
json_object.h View File

@@ -455,8 +455,8 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
struct json_object *val __attribute__((__unused__)) = NULL; \ struct json_object *val __attribute__((__unused__)) = NULL; \
for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \ for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
({ if(entry ## key) { \ ({ if(entry ## key) { \
key = (char*)entry ## key->k; \
val = (struct json_object*)entry ## key->v; \
key = (char*)lh_entry_k(entry ## key); \
val = (struct json_object*)lh_entry_v(entry ## key); \
entry_next ## key = entry ## key->next; \ entry_next ## key = entry ## key->next; \
} ; entry ## key; }); \ } ; entry ## key; }); \
entry ## key = entry_next ## key ) entry ## key = entry_next ## key )
@@ -470,8 +470,8 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
struct lh_entry *entry_next ## key = NULL; \ struct lh_entry *entry_next ## key = NULL; \
for(entry ## key = json_object_get_object(obj)->head; \ for(entry ## key = json_object_get_object(obj)->head; \
(entry ## key ? ( \ (entry ## key ? ( \
key = (char*)entry ## key->k, \
val = (struct json_object*)entry ## key->v, \
key = (char*)lh_entry_k(entry ## key), \
val = (struct json_object*)lh_entry_v(entry ## key), \
entry_next ## key = entry ## key->next, \ entry_next ## key = entry ## key->next, \
entry ## key) : 0); \ entry ## key) : 0); \
entry ## key = entry_next ## key) entry ## key = entry_next ## key)
@@ -483,7 +483,9 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
* @param iter the object iterator * @param iter the object iterator
*/ */
#define json_object_object_foreachC(obj,iter) \ #define json_object_object_foreachC(obj,iter) \
for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next)
for(iter.entry = json_object_get_object(obj)->head; \
(iter.entry ? (iter.key = (char*)lh_entry_k(iter.entry), iter.val = (struct json_object*)lh_entry_v(iter.entry), iter.entry) : 0); \
iter.entry = iter.entry->next)


/* Array type methods */ /* Array type methods */




+ 3
- 3
json_object_iterator.c View File

@@ -105,7 +105,7 @@ json_object_iter_next(struct json_object_iterator* iter)
JASSERT(NULL != iter); JASSERT(NULL != iter);
JASSERT(kObjectEndIterValue != iter->opaque_); JASSERT(kObjectEndIterValue != iter->opaque_);


iter->opaque_ = ((struct lh_entry *)iter->opaque_)->next;
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
} }




@@ -118,7 +118,7 @@ json_object_iter_peek_name(const struct json_object_iterator* iter)
JASSERT(NULL != iter); JASSERT(NULL != iter);
JASSERT(kObjectEndIterValue != iter->opaque_); JASSERT(kObjectEndIterValue != iter->opaque_);


return (const char*)(((struct lh_entry *)iter->opaque_)->k);
return (const char*)(((const struct lh_entry *)iter->opaque_)->k);
} }




@@ -131,7 +131,7 @@ json_object_iter_peek_value(const struct json_object_iterator* iter)
JASSERT(NULL != iter); JASSERT(NULL != iter);
JASSERT(kObjectEndIterValue != iter->opaque_); JASSERT(kObjectEndIterValue != iter->opaque_);


return (struct json_object*)(((struct lh_entry *)iter->opaque_)->v);
return (struct json_object*)lh_entry_v((const struct lh_entry *)iter->opaque_);
} }






+ 5
- 5
linkhash.c View File

@@ -441,7 +441,7 @@ static uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
*/ */
static unsigned long lh_perllike_str_hash(const void *k) static unsigned long lh_perllike_str_hash(const void *k)
{ {
const char *rkey = (char*) k;
const char *rkey = (const char *)k;
unsigned hashval = 1; unsigned hashval = 1;


while (*rkey) while (*rkey)
@@ -572,7 +572,7 @@ void lh_table_free(struct lh_table *t)
} }




int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts)
int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts)
{ {
unsigned long n; unsigned long n;


@@ -604,7 +604,7 @@ int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const uns


return 0; return 0;
} }
int lh_table_insert(struct lh_table *t, void *k, const void *v)
int lh_table_insert(struct lh_table *t, const void *k, const void *v)
{ {
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0); return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
} }
@@ -641,11 +641,11 @@ json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
{ {
struct lh_entry *e = lh_table_lookup_entry(t, k); struct lh_entry *e = lh_table_lookup_entry(t, k);
if (e != NULL) { if (e != NULL) {
if (v != NULL) *v = (void *)e->v;
if (v != NULL) *v = lh_entry_v(e);
return TRUE; /* key found */ return TRUE; /* key found */
} }
if (v != NULL) *v = NULL; if (v != NULL) *v = NULL;
return FALSE; /* key not found */
return FALSE; /* key not found */
} }


int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)


+ 31
- 5
linkhash.h View File

@@ -78,12 +78,16 @@ typedef int (lh_equal_fn) (const void *k1, const void *k2);
*/ */
struct lh_entry { struct lh_entry {
/** /**
* The key.
* The key. Use lh_entry_k() instead of accessing this directly.
*/
const void *k;
/**
* A flag for users of linkhash to know whether or not they
* need to free k.
*/ */
void *k;
int k_is_constant; int k_is_constant;
/** /**
* The value.
* The value. Use lh_entry_v() instead of accessing this directly.
*/ */
const void *v; const void *v;
/** /**
@@ -211,7 +215,7 @@ extern void lh_table_free(struct lh_table *t);
* @return On success, <code>0</code> is returned. * @return On success, <code>0</code> is returned.
* On error, a negative value is returned. * On error, a negative value is returned.
*/ */
extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);




/** /**
@@ -226,7 +230,7 @@ extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
* @param h hash value of the key to insert * @param h hash value of the key to insert
* @param opts opts, a subset of JSON_OBJECT_ADD_* flags is supported * @param opts opts, a subset of JSON_OBJECT_ADD_* flags is supported
*/ */
extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts);
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts);




/** /**
@@ -335,6 +339,28 @@ static inline unsigned long lh_get_hash(const struct lh_table *t, const void *k)
return t->hash_fn(k); return t->hash_fn(k);
} }


/* Don't use this outside of linkhash.h: */
#ifdef __UNCONST
#define _LH_UNCONST(a) __UNCONST(a)
#else
#define _LH_UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#endif

/**
* Return a non-const version of lh_entry->k.
* k is const to indicate and help ensure that linkhash itself doesn't modify
* it, but callers are allowed to do what they want with it.
* See also lh_entry->k_is_constant
*/
#define lh_entry_k(entry) _LH_UNCONST((entry)->k)

/**
* Return a non-const version of lh_entry->v.
* v is const to indicate and help ensure that linkhash itself doesn't modify
* it, but callers are allowed to do what they want with it.
*/
#define lh_entry_v(entry) _LH_UNCONST((entry)->v)

#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif


+ 1
- 1
tests/test4.c View File

@@ -28,7 +28,7 @@ int main()
{ {
const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\""; const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7"; const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7";
struct json_object *parse_result = json_tokener_parse((char*)input);
struct json_object *parse_result = json_tokener_parse(input);
const char *unjson = json_object_get_string(parse_result); const char *unjson = json_object_get_string(parse_result);


printf("input: %s\n", input); printf("input: %s\n", input);


Loading…
Cancel
Save