/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * * Tests that the column number of error reports is properly copied over from * other reports when invoked from the C++ api.
*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Other arguments are returned as is by eval.
EVAL("eval({myProp: 41});", &v);
CHECK(v.isObject());
JS::RootedObject obj(cx, &v.toObject());
JS::RootedValue myProp(cx);
CHECK(JS_GetProperty(cx, obj, "myProp", &myProp));
CHECK(myProp.isNumber() && myProp.toNumber() == 41);
staticbool ExtractTrustedCodeStringProperty(
JSContext* aCx, JS::Handle<JSObject*> aCode,
JS::MutableHandle<JSString*> outCode) {
JS::RootedValue value(aCx); if (!JS_GetProperty(aCx, aCode, "trustedCode", &value)) { returnfalse;
} if (value.isUndefined()) { // If the property is undefined, return NO-CODE.
outCode.set(nullptr); returntrue;
} if (value.isString()) { // If the property is a string, return it.
outCode.set(value.toString()); returntrue;
} // Otherwise, emulate a failure.
JS_ReportErrorASCII(aCx, "Unsupported value for trustedCode property"); returnfalse;
}
// Other arguments are returned as is by eval...
EVAL("eval({myProp: 41});", &v);
CHECK(v.isObject());
JS::RootedObject obj(cx, &v.toObject());
JS::RootedValue myProp(cx);
CHECK(JS_GetProperty(cx, obj, "myProp", &myProp));
CHECK(myProp.isNumber() && myProp.toNumber() == 41);
// ... but Objects are first tentatively converted to String by the // codeForEvalGets callback.
EVAL("eval({trustedCode: '6*7'});", &v);
CHECK(v.isNumber() && v.toNumber() == 6 * 7);
// And if that codeForEvalGets callback fails, then so does the eval call.
CHECK(!execDontReport("eval({trustedCode: 6*7});", __FILE__, __LINE__));
cx->clearPendingException();
// This snippet defines a TrustedType that wraps some trustedCode string and // stringifies to that string, as well as a helper to create a fake instance // that can stringify to a different string. constchar* customTypesSnippet = "function TrustedType(aTrustedCode) { this.trustedCode = aTrustedCode; };" "TrustedType.prototype.toString = function() { return this.trustedCode; };" "function CreateFakeTrustedType(aTrustedCode, aString) {" " let fake = new TrustedType(aTrustedCode);" " fake.toString = () => { return aString; };" " return fake;" "};";
// The same works with TrustedType wrappers.
EVAL("eval(new TrustedType('5*8'));", &v);
CHECK(v.isNumber() && v.toNumber() == 40);
EVAL( "(new Function(new TrustedType('a'), new TrustedType('b'), new " "TrustedType('return a * b')))(6, 7);",
&v);
CHECK(v.isNumber() && v.toNumber() == 42);
// new Function fails if one of the stringified argument does not match the // trustedCode property.
CHECK(!execDontReport( "new Function(CreateFakeTrustedType('a', 'c'), 'b', 'return b');",
__FILE__, __LINE__));
cx->clearPendingException();
CHECK(!execDontReport( "new Function('a', CreateFakeTrustedType('b', 'c'), 'return a');",
__FILE__, __LINE__));
cx->clearPendingException();
CHECK(
!execDontReport("new Function('a', 'b', CreateFakeTrustedType('return a " "* b', 'return a + b'));",
__FILE__, __LINE__));
cx->clearPendingException();
// new Function also fails if StringifiedObjectsMatchTrustedCodeProperties // returns false.
CHECK(!execDontReport("new Function('a', 'b', new TrustedType(undefined));",
__FILE__, __LINE__));
cx->clearPendingException();
// PerformEval relies on ExtractTrustedCodeProperty rather than toString() to // obtain the code to execute, so StringifiedObjectsMatchTrustedCodeProperties // will always allow the code execution for the specified security callbacks.
EVAL("eval(CreateFakeTrustedType('5*8', '6*7'));", &v);
CHECK(v.isNumber() && v.toNumber() == 40);
EVAL("eval(new TrustedType(undefined));", &v);
CHECK(v.isObject());
JS::RootedObject obj(cx, &v.toObject());
JS::RootedValue trustedCode(cx);
CHECK(JS_GetProperty(cx, obj, "trustedCode", &trustedCode));
CHECK(trustedCode.isUndefined());
returntrue;
}
// This is a HostEnsureCanCompileStrings() implementation similar to some checks // described in the CSP spec: verify that aBodyString and aParameterStrings // match the corresponding trustedCode property on aBodyArg and aParameterArgs // objects. See https://w3c.github.io/webappsec-csp/#can-compile-strings staticbool StringifiedObjectsMatchTrustedCodeProperties(
JSContext* aCx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCodeString,
JS::CompilationType aCompilationType,
JS::Handle<JS::StackGCVector<JSString*>> aParameterStrings,
JS::Handle<JSString*> aBodyString,
JS::Handle<JS::StackGCVector<JS::Value>> aParameterArgs,
JS::Handle<JS::Value> aBodyArg, bool* aOutCanCompileStrings) { bool isTrusted = true; auto comparePropertyAndString = [&aCx, &isTrusted](
JS::Handle<JS::Value> aValue,
JS::Handle<JSString*> aString) { if (!aValue.isObject()) { // Just trust non-Objects. returntrue;
}
JS::RootedObject obj(aCx, &aValue.toObject());
JS::RootedString trustedCode(aCx); if (!ExtractTrustedCodeStringProperty(aCx, obj, &trustedCode)) { // Propagate the failure. returnfalse;
} if (!trustedCode) { // Emulate a failure if trustedCode is undefined.
JS_ReportErrorASCII(aCx, "test failed, trustedCode property is undefined"); returnfalse;
} bool equals; if (!EqualStrings(aCx, trustedCode, aString, &equals)) { // Propagate the failure. returnfalse;
} if (!equals) {
isTrusted = false;
} returntrue;
}; if (!comparePropertyAndString(aBodyArg, aBodyString)) { // Propagate the failure. returnfalse;
} if (isTrusted) {
MOZ_ASSERT(aParameterArgs.length() == aParameterStrings.length()); for (size_t index = 0; index < aParameterArgs.length(); index++) { if (!comparePropertyAndString(aParameterArgs[index],
aParameterStrings[index])) { // Propagate the failure. returnfalse;
} if (!isTrusted) { break;
}
}
} // Allow compilation if arguments are trusted.
*aOutCanCompileStrings = isTrusted; returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.