feat: Add support for SpiderMonkey v140
Tried to add SM v140. There are again some internal SpiderMonkey API changes.
Tried to compile against SpiderMonkey v140 and got following errors:
==> couch (compile)
Compiling /Users/big-r/Documents/Developer/CouchDB/couchdb/src/couch/priv/couch_js/140/main.cpp
In file included from /Users/big-r/Documents/Developer/CouchDB/couchdb/src/couch/priv/couch_js/140/main.cpp:24:
In file included from /usr/local/include/mozjs-140/jsapi.h:30:
In file included from /usr/local/include/mozjs-140/js/CallAndConstruct.h:15:
/usr/local/include/mozjs-140/js/RootingAPI.h:1169:34: warning: unknown warning group '-Wdangling-pointer', ignored [-Wunknown-warning-option]
1169 | # pragma GCC diagnostic ignored "-Wdangling-pointer"
| ^
/Users/big-r/Documents/Developer/CouchDB/couchdb/src/couch/priv/couch_js/140/main.cpp:241:5: error: cannot initialize a member subobject of type 'JSCSPEvalChecker' (aka 'bool (*)(JSContext *, JS::RuntimeCode, JS::Handle<JSString *>, JS::CompilationType, JS::Handle<JS::StackGCVector<JSString *>>, JS::Handle<JSString *>, JS::Handle<JS::StackGCVector<JS::Value>>, JS::Handle<JS::Value>, bool *)') with an lvalue of type 'bool (JSContext *, JS::RuntimeCode, JS::HandleString)' (aka 'bool (JSContext *, JS::RuntimeCode, Handle<JSString *>)'): different number of parameters (9 vs 3)
241 | csp_allows,
| ^~~~~~~~~~
1 warning and 1 error generated.
ERROR: compile failed while processing /Users/big-r/Documents/Developer/CouchDB/couchdb/src/couch: rebar_abort
make: *** [couch] Error 1
I changed the csp_allow method signature to fit the typedef in js/public/Principals.h. I don't know if there is a better solution.
Before:
static bool
csp_allows(JSContext* cx, JS::RuntimeCode kind, JS::HandleString code)
{
couch_args* args = static_cast<couch_args*>(JS_GetContextPrivate(cx));
if(args->eval) {
return true;
} else {
return false;
}
}
static JSSecurityCallbacks security_callbacks = {
csp_allows,
nullptr
};
After:
static bool
csp_allows(JSContext* cx,
JS::RuntimeCode kind, JS::Handle<JSString*> codeString,
JS::CompilationType compilationType,
JS::Handle<JS::StackGCVector<JSString*>> parameterStrings,
JS::Handle<JSString*> bodyString,
JS::Handle<JS::StackGCVector<JS::Value>> parameterArgs,
JS::Handle<JS::Value> bodyArg, bool* outCanCompileStrings)
{
couch_args* args = static_cast<couch_args*>(JS_GetContextPrivate(cx));
if(args->eval) {
return true;
} else {
return false;
}
}
static JSSecurityCallbacks security_callbacks = {
csp_allows, //JSCSPEvalChecker contentSecurityPolicyAllows;
nullptr, //JSCodeForEvalOp codeForEvalGets;
nullptr //JSSubsumesOp subsumes;
};
Here are some additional infos what changed in SpiderMonkey from 128 -> 140.
The “problem” is, it’s not active in any CI run yet, so the tests are misleading 😉. I tried it with macOS, but got some errors (don’t know if it has todo with SpiderMonkey) …
Oops, @big-r81, good point. Maybe we can kick the macos runner again and see it can run with the latest 140.
If there are compilation errors, then I retract my +1
Compilation is fine, there were two Elixir errors, one UTF-8 test and the other I don’t remember. Will paste it here. But maybe it’s good to test this by others…
These Elixir test fail:
ViewSandboxingTest [test/elixir/test/view_sandboxing_test.exs]
* test view cannot invoke interpreter internals (83.2ms) [L#38]
* test view cannot access the map_funs and map_results array (98.0ms) [L#56]
* test COUCHDB-925 - altering 'doc' variable in map function affects other map functions (83.0ms) [L#82]
* test runtime code evaluation can be prevented (54.4ms) [L#177]
1) test runtime code evaluation can be prevented (ViewSandboxingTest)
test/elixir/test/view_sandboxing_test.exs:177
Assertion with == failed
code: assert resp.status_code == 200
left: 500
right: 200
stacktrace:
(couchdbtest 0.1.0) test/elixir/lib/couch/dbtest.ex:296: Couch.DBTest.query/6
test/elixir/test/view_sandboxing_test.exs:188: (test)
UTF8Test [test/elixir/test/utf8_test.exs]
* test UTF8 support (72.5ms) [L#12]
2) test UTF8 support (UTF8Test)
test/elixir/test/utf8_test.exs:12
Assertion with in failed
code: assert status in [201, 202]
left: 400
right: [201, 202]
stacktrace:
(elixir 1.18.4) lib/enum.ex:987: Enum."-each/2-lists^foreach/1-0-"/2
test/elixir/test/utf8_test.exs:25: (test)
Failed EUnit tests (idk if it has something todo with SM140):
module 'couch_bt_engine_cache_test'
couch_bt_engine_cache_test:23: -couch_bt_engine_cache_test_/0-fun-6- (t_created)...ok
couch_bt_engine_cache_test:24: -couch_bt_engine_cache_test_/0-fun-4- (t_insert_and_lookup)...*failed*
in function couch_bt_engine_cache_test:t_insert_and_lookup/1 (test/eunit/couch_bt_engine_cache_test.erl, line 73)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 83)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 554)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 379)
in call from eunit_proc:handle_test/2 (eunit_proc.erl, line 537)
in call from eunit_proc:tests_inorder/3 (eunit_proc.erl, line 479)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 369)
in call from eunit_proc:run_group/2 (eunit_proc.erl, line 593)
**error:{assert,[{module,couch_bt_engine_cache_test},
{line,73},
{expression,"couch_bt_engine_cache : insert ( { pid , 42 } , term )"},
{expected,false},
{value,true}]}
output:<<"">>
cpse_test_purge_docs
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_simple)...[0.003 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_simple_info_check)...[0.003 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_empty_db)...[0.001 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_single_docid)...[0.004 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_multiple_docids)...[0.004 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_no_docids)...[0.002 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_rev_path)...[0.005 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_deep_revision_path)...[0.241 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_partial_revs)...*failed*
in function couch_util:json_decode/2 (src/couch_util.erl, line 486)
in call from cpse_util:'-save_docs/3-fun-0-'/1 (src/cpse_util.erl, line 128)
in call from lists:map/2 (lists.erl, line 2385)
in call from cpse_util:save_docs/3 (src/cpse_util.erl, line 126)
in call from cpse_test_purge_docs:cpse_purge_partial_revs/1 (src/cpse_test_purge_docs.erl, line 253)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 83)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 554)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 379)
**throw:{invalid_json,{55,invalid_string}}
output:<<"">>
cpse_test_purge_seqs
cpse_gather: -make_test_fun/3-fun-2- (cpse_increment_purge_seq_on_complete_purge)...[0.007 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_increment_purge_multiple_times)...[0.005 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_increment_purge_seq_on_partial_purge)...*failed*
in function couch_util:json_decode/2 (src/couch_util.erl, line 486)
in call from cpse_util:'-save_docs/3-fun-0-'/1 (src/cpse_util.erl, line 128)
in call from lists:map/2 (lists.erl, line 2385)
in call from cpse_util:save_docs/3 (src/cpse_util.erl, line 126)
in call from cpse_test_purge_seqs:cpse_increment_purge_seq_on_partial_purge/1 (src/cpse_test_purge_seqs.erl, line 103)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 83)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 554)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 379)
**throw:{invalid_json,{56,invalid_string}}
output:<<"">>
Hey, did a test with QuickJS and I got 3 of the 4 errors too!
Failing Elixir tests:
UTF8Test [test/elixir/test/utf8_test.exs]
* test UTF8 support (39.7ms) [L#12]
1) test UTF8 support (UTF8Test)
test/elixir/test/utf8_test.exs:12
Assertion with in failed
code: assert status in [201, 202]
left: 400
right: [201, 202]
stacktrace:
(elixir 1.18.4) lib/enum.ex:987: Enum."-each/2-lists^foreach/1-0-"/2
test/elixir/test/utf8_test.exs:25: (test)
Failing EUnit tests:
cpse_test_purge_docs
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_simple)...[0.005 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_simple_info_check)...[0.005 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_empty_db)...[0.002 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_single_docid)...[0.005 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_multiple_docids)...[0.006 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_no_docids)...[0.002 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_rev_path)...[0.010 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_deep_revision_path)...[0.346 s] ok
cpse_gather: -make_test_fun/3-fun-2- (cpse_purge_partial_revs)...*failed*
in function couch_util:json_decode/2 (src/couch_util.erl, line 486)
in call from cpse_util:'-save_docs/3-fun-0-'/1 (src/cpse_util.erl, line 128)
in call from lists:map/2 (lists.erl, line 2385)
in call from cpse_util:save_docs/3 (src/cpse_util.erl, line 126)
in call from cpse_test_purge_docs:cpse_purge_partial_revs/1 (src/cpse_test_purge_docs.erl, line 253)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 83)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 554)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 379)
**throw:{invalid_json,{55,invalid_string}}
output:<<"">>
cpse_gather: -make_test_fun/3-fun-2- (cpse_increment_purge_seq_on_partial_purge)...*failed*
in function couch_util:json_decode/2 (src/couch_util.erl, line 486)
in call from cpse_util:'-save_docs/3-fun-0-'/1 (src/cpse_util.erl, line 128)
in call from lists:map/2 (lists.erl, line 2385)
in call from cpse_util:save_docs/3 (src/cpse_util.erl, line 126)
in call from cpse_test_purge_seqs:cpse_increment_purge_seq_on_partial_purge/1 (src/cpse_test_purge_seqs.erl, line 103)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 83)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 554)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 379)
**throw:{invalid_json,{56,invalid_string}}
output:<<"">>
This three failing tests have nothing to do with the SM140 it seems.
The test test runtime code evaluation can be prevented could be through the failing SM API, but I'm only guessing...