1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "jsfriendapi.h"
6 #include "js/CompilationAndEvaluation.h"
7 #include "js/Exception.h"
8 #include "js/GlobalObject.h"
9 #include "js/SourceText.h"
10 #include "jsapi-tests/tests.h"
12 BEGIN_TEST(testMutedErrors
) {
13 CHECK(testOuter("function f() {return 1}; f;"));
15 "function outer() { return (function () {return 2}); }; outer();"));
16 CHECK(testOuter("eval('(function() {return 3})');"));
18 testOuter("(function (){ return eval('(function() {return 4})'); })()"));
20 testOuter("(function (){ return eval('(function() { return "
21 "eval(\"(function(){return 5})\") })()'); })()"));
22 CHECK(testOuter("new Function('return 6')"));
23 CHECK(testOuter("function f() { return new Function('return 7') }; f();"));
24 CHECK(testOuter("eval('new Function(\"return 8\")')"));
26 testOuter("(new Function('return eval(\"(function(){return 9})\")'))()"));
27 CHECK(testOuter("(function(){return function(){return 10}}).bind()()"));
29 "var e = eval; (function() { return e('(function(){return 11})') })()"));
31 CHECK(testError("eval(-)"));
32 CHECK(testError("-"));
33 CHECK(testError("new Function('x', '-')"));
34 CHECK(testError("eval('new Function(\"x\", \"-\")')"));
37 * NB: uncaught exceptions, when reported, have nothing on the stack so
38 * both the filename and mutedErrors are empty. E.g., this would fail:
40 * CHECK(testError("throw 3"));
45 bool eval(const char* asciiChars
, bool mutedErrors
,
46 JS::MutableHandleValue rval
) {
47 size_t len
= strlen(asciiChars
);
48 mozilla::UniquePtr
<char16_t
[]> chars(new char16_t
[len
+ 1]);
49 for (size_t i
= 0; i
< len
; ++i
) {
50 chars
[i
] = asciiChars
[i
];
54 JS::RealmOptions globalOptions
;
55 JS::RootedObject
global(
56 cx
, JS_NewGlobalObject(cx
, getGlobalClass(), nullptr,
57 JS::FireOnNewGlobalHook
, globalOptions
));
59 JSAutoRealm
ar(cx
, global
);
61 JS::CompileOptions
options(cx
);
62 options
.setMutedErrors(mutedErrors
).setFileAndLine("", 0);
64 JS::SourceText
<char16_t
> srcBuf
;
65 CHECK(srcBuf
.init(cx
, chars
.get(), len
, JS::SourceOwnership::Borrowed
));
67 return JS::Evaluate(cx
, options
, srcBuf
, rval
);
70 bool testOuter(const char* asciiChars
) {
71 CHECK(testInner(asciiChars
, false));
72 CHECK(testInner(asciiChars
, true));
76 bool testInner(const char* asciiChars
, bool mutedErrors
) {
77 JS::RootedValue
rval(cx
);
78 CHECK(eval(asciiChars
, mutedErrors
, &rval
));
80 JS::RootedFunction
fun(cx
, &rval
.toObject().as
<JSFunction
>());
81 JSScript
* script
= JS_GetFunctionScript(cx
, fun
);
82 CHECK(JS_ScriptHasMutedErrors(script
) == mutedErrors
);
87 bool testError(const char* asciiChars
) {
88 JS::RootedValue
rval(cx
);
89 CHECK(!eval(asciiChars
, true, &rval
));
91 JS::ExceptionStack
exnStack(cx
);
92 CHECK(JS::StealPendingExceptionStack(cx
, &exnStack
));
94 JS::ErrorReportBuilder
report(cx
);
95 CHECK(report
.init(cx
, exnStack
, JS::ErrorReportBuilder::WithSideEffects
));
96 CHECK(report
.report()->isMuted
== true);
99 END_TEST(testMutedErrors
)