diff options
author | Yann Ylavic <ylavic@apache.org> | 2018-08-31 17:56:40 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2018-08-31 17:56:40 +0000 |
commit | f087568bbb9c32e618bc8efdd884182eb0ce5ab7 (patch) | |
tree | f34c98d06928751750de2f36ec25edb34c3ca4d8 /json | |
parent | a96abdc33f63b2057f42566b3d250541bb0ffff7 (diff) | |
download | apr-f087568bbb9c32e618bc8efdd884182eb0ce5ab7.tar.gz |
apr_json: follow up to r1839755: preserve formatting when decoding object keys.
The object key-value pair parsed by the JSON decoder contained pre/post spaces
which we lost by changing the key type (to a C string) in apr_json_object_set().
Add a new/private apr__json_object_set() helper taking an apr_json_value_t key
and use it in both apr_json_object_set() and apr_json_decode_object().
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1839779 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'json')
-rw-r--r-- | json/apr_json.c | 54 | ||||
-rw-r--r-- | json/apr_json_decode.c | 6 |
2 files changed, 43 insertions, 17 deletions
diff --git a/json/apr_json.c b/json/apr_json.c index d3bc8329d..3ce2b87b4 100644 --- a/json/apr_json.c +++ b/json/apr_json.c @@ -129,21 +129,50 @@ apr_json_value_t *apr_json_null_create(apr_pool_t *pool) return json; } -apr_status_t apr_json_object_set(apr_json_value_t *object, const char *key, - apr_ssize_t klen, apr_json_value_t *val, apr_pool_t *pool) +apr_status_t apr__json_object_set(apr_json_value_t *object, + apr_json_value_t *key, apr_json_value_t *val, apr_pool_t *pool); + +apr_status_t apr__json_object_set(apr_json_value_t *object, + apr_json_value_t *key, apr_json_value_t *val, apr_pool_t *pool) { apr_json_kv_t *kv; apr_hash_t *hash; - if (object->type != APR_JSON_OBJECT) { - return APR_EINVAL; + hash = object->value.object->hash; + + kv = apr_hash_get(hash, key->value.string.p, key->value.string.len); + if (!kv) { + kv = apr_palloc(pool, sizeof(apr_json_kv_t)); + if (!kv) { + return APR_ENOMEM; + } + + APR_RING_ELEM_INIT(kv, link); + APR_JSON_OBJECT_INSERT_TAIL(object->value.object, kv); + apr_hash_set(hash, key->value.string.p, key->value.string.len, kv); } - hash = object->value.object->hash; + kv->k = key; + kv->v = val; - kv = apr_hash_get(hash, key, klen); + return APR_SUCCESS; +} + +apr_status_t apr_json_object_set(apr_json_value_t *object, const char *key, + apr_ssize_t klen, apr_json_value_t *val, apr_pool_t *pool) +{ + apr_json_value_t *k; + + if (object->type != APR_JSON_OBJECT) { + return APR_EINVAL; + } if (!val) { + apr_hash_t *hash; + apr_json_kv_t *kv; + + hash = object->value.object->hash; + kv = apr_hash_get(hash, key, klen); if (kv) { apr_hash_set(hash, key, klen, NULL); APR_RING_REMOVE((kv), link); @@ -151,17 +180,12 @@ apr_status_t apr_json_object_set(apr_json_value_t *object, const char *key, return APR_SUCCESS; } - if (!kv) { - kv = apr_palloc(pool, sizeof(apr_json_kv_t)); - APR_RING_ELEM_INIT(kv, link); - APR_JSON_OBJECT_INSERT_TAIL(object->value.object, kv); - kv->k = apr_json_string_create(pool, key, klen); - apr_hash_set(hash, kv->k->value.string.p, kv->k->value.string.len, kv); + k = apr_json_string_create(pool, key, klen); + if (!k) { + return APR_ENOMEM; } - kv->v = val; - - return APR_SUCCESS; + return apr__json_object_set(object, k, val, pool); } apr_json_kv_t *apr_json_object_get(apr_json_value_t *object, const char *key, apr_ssize_t klen) diff --git a/json/apr_json_decode.c b/json/apr_json_decode.c index d4b8b315d..1a03f2d63 100644 --- a/json/apr_json_decode.c +++ b/json/apr_json_decode.c @@ -424,6 +424,9 @@ static apr_status_t apr_json_decode_array(apr_json_scanner_t * self, return status; } +apr_status_t apr__json_object_set(apr_json_value_t *object, + apr_json_value_t *key, apr_json_value_t *val, apr_pool_t *pool); + static apr_status_t apr_json_decode_object(apr_json_scanner_t * self, apr_json_value_t *json, apr_json_object_t ** retval) { @@ -500,8 +503,7 @@ static apr_status_t apr_json_decode_object(apr_json_scanner_t * self, if ((status = apr_json_decode_value(self, &value))) goto out; - apr_json_object_set(json, key->value.string.p, key->value.string.len, - value, self->pool); + apr__json_object_set(json, key, value, self->pool); if (self->p == self->e) { status = APR_EOF; |