You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2024/08/23 06:52:20 UTC
(couchdb) branch main updated: Fix json order false positives in quickjs scanner plugin
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 34cb3bf7b Fix json order false positives in quickjs scanner plugin
34cb3bf7b is described below
commit 34cb3bf7b25c84d42f8ba51ddc2f432cebd56a0a
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Thu Aug 22 19:25:20 2024 -0400
Fix json order false positives in quickjs scanner plugin
After scanning some production clusters, noticed that QuickJS and SM 91 seems
to be using a different json order than SM 1.8.5. A KV proplist ejson prompt
result could show up as a compatibility issue when the JSON key order is
different.
To fix it, use maps instead of ejson KVs. Could have just used a
jiffy:encode/decode pair, but it seemed wasteful to serialize everything when
we just want to transform the proplists so created a small utility function.
---
src/couch/src/couch_util.erl | 10 ++++++++++
src/couch/test/eunit/couch_util_tests.erl | 13 +++++++++++++
src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl | 5 ++++-
.../test/couch_quickjs_scanner_plugin_tests.erl | 9 ++++++++-
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl
index 18faa9695..ee3c3fc4c 100644
--- a/src/couch/src/couch_util.erl
+++ b/src/couch/src/couch_util.erl
@@ -46,6 +46,7 @@
-export([verify_hash_names/2]).
-export([get_config_hash_algorithms/0]).
-export([remove_sensitive_data/1]).
+-export([ejson_to_map/1]).
-include_lib("couch/include/couch_db.hrl").
@@ -852,3 +853,12 @@ remove_sensitive_data(KVList) ->
KVList1 = lists:keyreplace(<<"password">>, 1, KVList, {<<"password">>, <<"****">>}),
% some KVList entries are atoms, so test fo this too
lists:keyreplace(password, 1, KVList1, {password, <<"****">>}).
+
+ejson_to_map(#{} = Val) ->
+ maps:map(fun(_, V) -> ejson_to_map(V) end, Val);
+ejson_to_map(Val) when is_list(Val) ->
+ lists:map(fun(V) -> ejson_to_map(V) end, Val);
+ejson_to_map({Val}) when is_list(Val) ->
+ maps:from_list(lists:map(fun({K, V}) -> {K, ejson_to_map(V)} end, Val));
+ejson_to_map(Val) ->
+ Val.
diff --git a/src/couch/test/eunit/couch_util_tests.erl b/src/couch/test/eunit/couch_util_tests.erl
index 62ec20775..5f8f1ce43 100644
--- a/src/couch/test/eunit/couch_util_tests.erl
+++ b/src/couch/test/eunit/couch_util_tests.erl
@@ -193,3 +193,16 @@ json_decode_test_() ->
?_assertEqual({[]}, couch_util:json_decode(<<"{}">>, [])),
?_assertEqual(#{}, couch_util:json_decode(<<"{}">>, [return_maps]))
].
+
+ejson_to_map_test() ->
+ ?assertEqual(0, couch_util:ejson_to_map(0)),
+ ?assertEqual(true, couch_util:ejson_to_map(true)),
+ ?assertEqual(0.1, couch_util:ejson_to_map(0.1)),
+ ?assertEqual(#{}, couch_util:ejson_to_map(#{})),
+ ?assertEqual(#{a => b}, couch_util:ejson_to_map(#{a => b})),
+ ?assertEqual([], couch_util:ejson_to_map([])),
+ ?assertEqual([1], couch_util:ejson_to_map([1])),
+ ?assertEqual(#{}, couch_util:ejson_to_map({[]})),
+ ?assertEqual(#{a => 1, b => 2}, couch_util:ejson_to_map({[{b, 2}, {a, 1}]})),
+ ?assertEqual(#{<<"a">> => [1, #{}]}, couch_util:ejson_to_map({[{<<"a">>, [1, {[]}]}]})),
+ ?assertEqual([#{true => 1}], couch_util:ejson_to_map([{[{true, 1}]}])).
diff --git a/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl b/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
index 005488430..fafa6bc33 100644
--- a/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
+++ b/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
@@ -581,8 +581,11 @@ proc(Pid) ->
}.
prompt(#proc{} = Proc, Prompt) ->
+ % Make sure to transform ejson with key values {[{K, V}, ...]} to
+ % one containing maps to avoid false positives resulting from
+ % differences in json key encoding order
try
- couch_query_servers:proc_prompt(Proc, Prompt)
+ couch_util:ejson_to_map(couch_query_servers:proc_prompt(Proc, Prompt))
catch
Tag:Err ->
{error, {Tag, Err}}
diff --git a/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl b/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
index 231b9b76c..ad5d7ce91 100644
--- a/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
+++ b/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
@@ -421,6 +421,13 @@ ddoc_view(Doc) ->
v_expr_fun1 => #{map => <<"(function(doc) {emit(1,2)})\n">>},
v_expr_fun2 => #{map => <<"(function(doc) {emit(3,4)});">>},
v_expr_fun3 => #{map => <<"y=9;\n(function(doc) {emit(5,y)})">>},
- v_expr_fun4 => #{map => <<"x=10; function(doc) {emit(x,6)}\n">>}
+ v_expr_fun4 => #{map => <<"x=10; function(doc) {emit(x,6)}\n">>},
+ v_emit_map1 => #{
+ map => <<
+ "function(doc){ \n",
+ " emit(42, {NaN:1, \"2\": 1}); \n"
+ "};\n"
+ >>
+ }
}
}.