Changeset: 9ebd128754e3 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9ebd128754e3 Modified Files: monetdb5/modules/atoms/json.c Branch: default Log Message:
Handle duplicate keys in JSON object parsing According to the ECMAscript language specification (https://262.ecma-international.org/14.0/#sec-internalizejsonproperty) "In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten." diffs (54 lines): diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c --- a/monetdb5/modules/atoms/json.c +++ b/monetdb5/modules/atoms/json.c @@ -1058,6 +1058,7 @@ JSONtoken(JSON *jt, const char *j, const str msg; int nxt, idx = JSONnew(jt); const char *string_start = j; + int pidx; if (jt->error) return idx; @@ -1095,12 +1096,36 @@ JSONtoken(JSON *jt, const char *j, const int chld = JSONtoken(jt, j, next); if (jt->error) return idx; - jt->elm[nxt].child = chld; - jt->elm[nxt].value++; - jt->elm[nxt].valuelen -= 2; - JSONappend(jt, idx, nxt); - if (jt->error) - return idx; + + /* Search for a duplicate key */ + for(pidx = nxt - 1; pidx > idx; pidx--) { + if (jt->elm[pidx].kind == JSON_ELEMENT && + jt->elm[pidx].valuelen == jt->elm[nxt].valuelen - 2 && + strncmp(jt->elm[pidx].value, jt->elm[nxt].value + 1, + jt->elm[nxt].valuelen) == 0) { + break; + } + } + + /* Duplicate found: Change the value of the previous key. */ + if (pidx > idx) { + jt->elm[pidx].child = chld; + /* Note that we do not call JSONappend here. + * + * Normally we would de-allocate the old child value and the new key, + * but since we are using an arena provided by JSONnew, we don't need to. + * This might get expensive for big objects with lagre values for + * repeated keys. + */ + + } else { + jt->elm[nxt].child = chld; + jt->elm[nxt].value++; + jt->elm[nxt].valuelen -= 2; + JSONappend(jt, idx, nxt); + if (jt->error) + return idx; + } j = *next; skipblancs(j); if (*j == '}') _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org