1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsapi-tests/testOriginPrincipals.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,109 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "js/OldDebugAPI.h" 1.9 +#include "jsapi-tests/tests.h" 1.10 + 1.11 +static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr; 1.12 +static TestJSPrincipals prin1(1); 1.13 +static TestJSPrincipals prin2(1); 1.14 + 1.15 +BEGIN_TEST(testOriginPrincipals) 1.16 +{ 1.17 + /* 1.18 + * Currently, the only way to set a non-trivial originPrincipal is to use 1.19 + * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the 1.20 + * compiled script, so we can only test nested scripts. 1.21 + */ 1.22 + 1.23 + CHECK(testOuter("function f() {return 1}; f;")); 1.24 + CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();")); 1.25 + CHECK(testOuter("eval('(function() {return 3})');")); 1.26 + CHECK(testOuter("(function (){ return eval('(function() {return 4})'); })()")); 1.27 + CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()")); 1.28 + CHECK(testOuter("new Function('return 6')")); 1.29 + CHECK(testOuter("function f() { return new Function('return 7') }; f();")); 1.30 + CHECK(testOuter("eval('new Function(\"return 8\")')")); 1.31 + CHECK(testOuter("(new Function('return eval(\"(function(){return 9})\")'))()")); 1.32 + CHECK(testOuter("(function(){return function(){return 10}}).bind()()")); 1.33 + CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()")); 1.34 + 1.35 + JS_SetErrorReporter(cx, ErrorReporter); 1.36 + CHECK(testError("eval(-)")); 1.37 + CHECK(testError("-")); 1.38 + CHECK(testError("new Function('x', '-')")); 1.39 + CHECK(testError("eval('new Function(\"x\", \"-\")')")); 1.40 + 1.41 + /* 1.42 + * NB: uncaught exceptions, when reported, have nothing on the stack so 1.43 + * both the filename and originPrincipals are null. E.g., this would fail: 1.44 + * 1.45 + * CHECK(testError("throw 3")); 1.46 + */ 1.47 + return true; 1.48 +} 1.49 + 1.50 +static void 1.51 +ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) 1.52 +{ 1.53 + sOriginPrincipalsInErrorReporter = report->originPrincipals; 1.54 +} 1.55 + 1.56 +bool 1.57 +eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval) 1.58 +{ 1.59 + size_t len = strlen(asciiChars); 1.60 + jschar *chars = new jschar[len+1]; 1.61 + for (size_t i = 0; i < len; ++i) 1.62 + chars[i] = asciiChars[i]; 1.63 + chars[len] = 0; 1.64 + 1.65 + JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook)); 1.66 + CHECK(global); 1.67 + JSAutoCompartment ac(cx, global); 1.68 + CHECK(JS_InitStandardClasses(cx, global)); 1.69 + 1.70 + 1.71 + JS::CompileOptions options(cx); 1.72 + options.setOriginPrincipals(originPrincipals) 1.73 + .setFileAndLine("", 0); 1.74 + 1.75 + bool ok = JS::Evaluate(cx, global, options, chars, len, rval); 1.76 + 1.77 + delete[] chars; 1.78 + return ok; 1.79 +} 1.80 + 1.81 +bool 1.82 +testOuter(const char *asciiChars) 1.83 +{ 1.84 + CHECK(testInner(asciiChars, &prin1, &prin1)); 1.85 + CHECK(testInner(asciiChars, &prin1, &prin2)); 1.86 + return true; 1.87 +} 1.88 + 1.89 +bool 1.90 +testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal) 1.91 +{ 1.92 + JS::RootedValue rval(cx); 1.93 + CHECK(eval(asciiChars, principal, originPrincipal, &rval)); 1.94 + 1.95 + JS::RootedFunction fun(cx, &rval.toObject().as<JSFunction>()); 1.96 + JSScript *script = JS_GetFunctionScript(cx, fun); 1.97 + CHECK(JS_GetScriptPrincipals(script) == principal); 1.98 + CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal); 1.99 + 1.100 + return true; 1.101 +} 1.102 + 1.103 +bool 1.104 +testError(const char *asciiChars) 1.105 +{ 1.106 + JS::RootedValue rval(cx); 1.107 + CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval)); 1.108 + CHECK(JS_ReportPendingException(cx)); 1.109 + CHECK(sOriginPrincipalsInErrorReporter == &prin2); 1.110 + return true; 1.111 +} 1.112 +END_TEST(testOriginPrincipals)