Patch json-decode-warnings for JSON related Bug #52829
Patch version 2010-09-14 05:48 UTC
Return to Bug #52829 |
Download this patch
Patch Revisions:
Developer: aharvey@php.net
diff --git a/ext/json/JSON_parser.c b/ext/json/JSON_parser.c
index ef05f3b..a7f0162 100644
--- a/ext/json/JSON_parser.c
+++ b/ext/json/JSON_parser.c
@@ -389,6 +389,31 @@ static void utf16_to_utf8(smart_str *buf, unsigned short utf16)
}
}
+/* Wrapper functions to emit a warning if a JSON object has duplicate names,
+ * which are technically valid under the RFC, but not something we can handle
+ * safely. */
+static void add_assoc_zval_warn(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC) {
+ ulong h = zend_get_hash_value(key, key_len);
+
+ if (zend_hash_quick_exists(Z_ARRVAL_P(arg), key, key_len, h)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Duplicate name '%s' within JSON object; only the last value will be used", key);
+ }
+
+ add_assoc_zval_ex(arg, key, key_len, value TSRMLS_CC);
+}
+
+static void add_property_zval_warn(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC) {
+ ulong h = zend_get_hash_value(key, key_len);
+ HashTable *properties = Z_OBJ_HANDLER_P(arg, get_properties)(arg);
+
+ if (properties && zend_hash_quick_exists(properties, key, key_len, h)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Duplicate name '%s' within JSON object; only the last value will be used", key);
+ }
+
+ add_property_zval_ex(arg, key, key_len, value TSRMLS_CC);
+}
+
+
static void attach_zval(JSON_parser jp, int up, int cur, smart_str *key, int assoc TSRMLS_DC)
{
zval *root = jp->the_zstack[up];
@@ -403,12 +428,12 @@ static void attach_zval(JSON_parser jp, int up, int cur, smart_str *key, int ass
{
if (!assoc)
{
- add_property_zval_ex(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC);
+ add_property_zval_warn(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC);
Z_DELREF_P(child);
}
else
{
- add_assoc_zval_ex(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child);
+ add_assoc_zval_warn(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child);
}
key->len = 0;
}
@@ -550,10 +575,10 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length,
json_create_zval(&mval, &buf, type, options);
if (!assoc) {
- add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
+ add_property_zval_warn(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
Z_DELREF_P(mval);
} else {
- add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
+ add_assoc_zval_warn(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
}
key.len = 0;
buf.len = 0;
@@ -694,10 +719,10 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length,
if (pop(jp, MODE_OBJECT) && push(jp, MODE_KEY)) {
if (type != -1) {
if (!assoc) {
- add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
+ add_property_zval_warn(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
Z_DELREF_P(mval);
} else {
- add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
+ add_assoc_zval_warn(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
}
key.len = 0;
}
|