summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2017-10-31 19:00:16 +0100
committerJan Lehnardt <jan@apache.org>2017-11-01 08:29:08 +0100
commit3706a77c13a78672e5a3fbde06e7bffd3665f73b (patch)
tree1cec07d2ba1c9c4ebb6e3e15bb354b37b1566353
parenteeef2eec91bbcdea8bd86674604eddb1858cbde1 (diff)
downloadcouchdb-3706a77c13a78672e5a3fbde06e7bffd3665f73b.tar.gz
feat: disallow dupe keys
-rw-r--r--src/ejson/ejson.erl20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/ejson/ejson.erl b/src/ejson/ejson.erl
index 72bb6c157..aff5f3d41 100644
--- a/src/ejson/ejson.erl
+++ b/src/ejson/ejson.erl
@@ -36,6 +36,9 @@ init() ->
decode(undefined) ->
throw({invalid_json, undefined});
decode(IoList) ->
+ dedupe_objs(decode_int(IoList)).
+
+decode_int(IoList) ->
try
nif_decode(IoList)
catch exit:ejson_nif_not_loaded ->
@@ -161,6 +164,23 @@ make_ejson([Value | RevEvs], [Vals | RestStack] = _Stack) ->
make_ejson(RevEvs, [[Value | Vals] | RestStack]).
+dedupe_objs({Props}) when is_list(Props) ->
+ RevProps = lists:reverse(Props),
+ {_, NewProps} = lists:foldl(fun({Key, Val}, {Seen, PropAcc}) ->
+ case sets:is_element(Key, Seen) of
+ true ->
+ {Seen, PropAcc};
+ false ->
+ {sets:add_element(Key, Seen), [{Key, Val} | PropAcc]}
+ end
+ end, {sets:new(), []}, RevProps),
+ {NewProps};
+dedupe_objs(Vals) when is_list(Vals) ->
+ lists:map(fun dedupe_objs/1, Vals);
+dedupe_objs(Val) ->
+ Val.
+
+
reverse_tokens(_) ->
exit(ejson_nif_not_loaded).