testMutedErrors.cpp (3324B)
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/. */ 4 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" 11 12 BEGIN_TEST(testMutedErrors) { 13 CHECK(testOuter("function f() {return 1}; f;")); 14 CHECK(testOuter( 15 "function outer() { return (function () {return 2}); }; outer();")); 16 CHECK(testOuter("eval('(function() {return 3})');")); 17 CHECK( 18 testOuter("(function (){ return eval('(function() {return 4})'); })()")); 19 CHECK( 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\")')")); 25 CHECK( 26 testOuter("(new Function('return eval(\"(function(){return 9})\")'))()")); 27 CHECK(testOuter("(function(){return function(){return 10}}).bind()()")); 28 CHECK(testOuter( 29 "var e = eval; (function() { return e('(function(){return 11})') })()")); 30 31 CHECK(testError("eval(-)")); 32 CHECK(testError("-")); 33 CHECK(testError("new Function('x', '-')")); 34 CHECK(testError("eval('new Function(\"x\", \"-\")')")); 35 36 /* 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: 39 * 40 * CHECK(testError("throw 3")); 41 */ 42 return true; 43 } 44 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]; 51 } 52 chars[len] = 0; 53 54 JS::RealmOptions globalOptions; 55 JS::RootedObject global( 56 cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, 57 JS::FireOnNewGlobalHook, globalOptions)); 58 CHECK(global); 59 JSAutoRealm ar(cx, global); 60 61 JS::CompileOptions options(cx); 62 options.setMutedErrors(mutedErrors).setFileAndLine("", 0); 63 64 JS::SourceText<char16_t> srcBuf; 65 CHECK(srcBuf.init(cx, chars.get(), len, JS::SourceOwnership::Borrowed)); 66 67 return JS::Evaluate(cx, options, srcBuf, rval); 68 } 69 70 bool testOuter(const char* asciiChars) { 71 CHECK(testInner(asciiChars, false)); 72 CHECK(testInner(asciiChars, true)); 73 return true; 74 } 75 76 bool testInner(const char* asciiChars, bool mutedErrors) { 77 JS::RootedValue rval(cx); 78 CHECK(eval(asciiChars, mutedErrors, &rval)); 79 80 JS::RootedFunction fun(cx, &rval.toObject().as<JSFunction>()); 81 JSScript* script = JS_GetFunctionScript(cx, fun); 82 CHECK(JS_ScriptHasMutedErrors(script) == mutedErrors); 83 84 return true; 85 } 86 87 bool testError(const char* asciiChars) { 88 JS::RootedValue rval(cx); 89 CHECK(!eval(asciiChars, true, &rval)); 90 91 JS::ExceptionStack exnStack(cx); 92 CHECK(JS::StealPendingExceptionStack(cx, &exnStack)); 93 94 JS::ErrorReportBuilder report(cx); 95 CHECK(report.init(cx, exnStack, JS::ErrorReportBuilder::WithSideEffects)); 96 CHECK(report.report()->isMuted == true); 97 return true; 98 } 99 END_TEST(testMutedErrors)