mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
debfadcca4
- Bug 751387 - Fix crash caused by out-of-bounds accesses in command line options handling. r=bholley (240670c35) - Bug 1162187 - Pass around AutoJSAPI instead of cx to give us more control over error handling. r=glandium (702954016) - Bug 1162187 - Factor out single line argument processing into a helper. r=glandium (56efce591) - Bug 1162187 - Use the AutoJSAPI machinery to handle xpcshell exceptions. r=glandium (162309001) - Bug 1162187 - Remove the custom XPCShell error reporter. r=glandium (523d84539) - Bug 1162187 - Remove ignoreReportedErrors. r=glandium (072f247a3) - Bug 1161590 - xpcshell needs to initialize graphics prefs so that GfxInfo::GetFeatureStatus can check preferences. r=ehsan (5a8415817) - Bug 1166243 - Remove build() function from js and xpc shells. r=bholley,r=efaust (8537f2259) - Bug 1182357 - Implement support for optional size_is for arrays passed from JS. r=mrbkap (0d22d3f34) - missing profiler parts of Bug 1092311 - Fix IndexedDB profiler markers and logging (a68567bbb) - Bug 1086999 - CSP: Asterisk (*) wildcard should not allow blob:, data:, or filesystem: when matching source expressions (r=fabrice,pauljt) (7757a92ae) - Bug 1105827 - Part 1: Add stub PermissionStatus implementation. r=baku (2bd4c1dd3) - Bug 635134 - Adds X11 run-time check for Gtk3 backend. r=karlt (7e9304f5e) - Bug 994541 - Enable BasicCompositor OMTC on linux. r=Bas (c9a266beb) - Bug 1105827 - Part 2: Add stub Permissions implementation. r=baku (751f5e9e6) - Bug 1105827 - Part 3: Implement Permissions.query. r=baku (a30a48cbe) - Bug 1105827 - Part 4: Add Navigator.permissions. r=baku (0d70fc5e6) - Bug 1174861 - Remove unnecessary Rooted from Prefable::isEnabled(). r=bholley (a0893081d)
182 lines
5.2 KiB
C++
182 lines
5.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
*/
|
|
/* 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/. */
|
|
|
|
#include "jsapi-tests/tests.h"
|
|
|
|
/*
|
|
* Test that resolve hook recursion for the same object and property is
|
|
* prevented.
|
|
*/
|
|
BEGIN_TEST(testResolveRecursion)
|
|
{
|
|
static const JSClass my_resolve_class = {
|
|
"MyResolve",
|
|
JSCLASS_HAS_PRIVATE,
|
|
nullptr, // add
|
|
nullptr, // delete
|
|
nullptr, // get
|
|
nullptr, // set
|
|
nullptr, // enumerate
|
|
my_resolve
|
|
};
|
|
|
|
obj1.init(cx, JS_NewObject(cx, &my_resolve_class));
|
|
CHECK(obj1);
|
|
obj2.init(cx, JS_NewObject(cx, &my_resolve_class));
|
|
CHECK(obj2);
|
|
JS_SetPrivate(obj1, this);
|
|
JS_SetPrivate(obj2, this);
|
|
|
|
JS::RootedValue obj1Val(cx, JS::ObjectValue(*obj1));
|
|
JS::RootedValue obj2Val(cx, JS::ObjectValue(*obj2));
|
|
CHECK(JS_DefineProperty(cx, global, "obj1", obj1Val, 0));
|
|
CHECK(JS_DefineProperty(cx, global, "obj2", obj2Val, 0));
|
|
|
|
resolveEntryCount = 0;
|
|
resolveExitCount = 0;
|
|
|
|
/* Start the essence of the test via invoking the first resolve hook. */
|
|
JS::RootedValue v(cx);
|
|
EVAL("obj1.x", &v);
|
|
CHECK(v.isFalse());
|
|
CHECK_EQUAL(resolveEntryCount, 4);
|
|
CHECK_EQUAL(resolveExitCount, 4);
|
|
|
|
obj1 = nullptr;
|
|
obj2 = nullptr;
|
|
return true;
|
|
}
|
|
|
|
JS::PersistentRootedObject obj1;
|
|
JS::PersistentRootedObject obj2;
|
|
int resolveEntryCount;
|
|
int resolveExitCount;
|
|
|
|
struct AutoIncrCounters {
|
|
|
|
explicit AutoIncrCounters(cls_testResolveRecursion* t) : t(t) {
|
|
t->resolveEntryCount++;
|
|
}
|
|
|
|
~AutoIncrCounters() {
|
|
t->resolveExitCount++;
|
|
}
|
|
|
|
cls_testResolveRecursion* t;
|
|
};
|
|
|
|
bool
|
|
doResolve(JS::HandleObject obj, JS::HandleId id, bool* resolvedp)
|
|
{
|
|
CHECK_EQUAL(resolveExitCount, 0);
|
|
AutoIncrCounters incr(this);
|
|
CHECK(obj == obj1 || obj == obj2);
|
|
|
|
CHECK(JSID_IS_STRING(id));
|
|
|
|
JSFlatString* str = JS_FlattenString(cx, JSID_TO_STRING(id));
|
|
CHECK(str);
|
|
JS::RootedValue v(cx);
|
|
if (JS_FlatStringEqualsAscii(str, "x")) {
|
|
if (obj == obj1) {
|
|
/* First resolve hook invocation. */
|
|
CHECK_EQUAL(resolveEntryCount, 1);
|
|
EVAL("obj2.y = true", &v);
|
|
CHECK(v.isTrue());
|
|
CHECK(JS_DefinePropertyById(cx, obj, id, JS::FalseHandleValue, JSPROP_RESOLVING));
|
|
*resolvedp = true;
|
|
return true;
|
|
}
|
|
if (obj == obj2) {
|
|
CHECK_EQUAL(resolveEntryCount, 4);
|
|
*resolvedp = false;
|
|
return true;
|
|
}
|
|
} else if (JS_FlatStringEqualsAscii(str, "y")) {
|
|
if (obj == obj2) {
|
|
CHECK_EQUAL(resolveEntryCount, 2);
|
|
CHECK(JS_DefinePropertyById(cx, obj, id, JS::NullHandleValue, JSPROP_RESOLVING));
|
|
EVAL("obj1.x", &v);
|
|
CHECK(v.isUndefined());
|
|
EVAL("obj1.y", &v);
|
|
CHECK(v.isInt32(0));
|
|
*resolvedp = true;
|
|
return true;
|
|
}
|
|
if (obj == obj1) {
|
|
CHECK_EQUAL(resolveEntryCount, 3);
|
|
EVAL("obj1.x", &v);
|
|
CHECK(v.isUndefined());
|
|
EVAL("obj1.y", &v);
|
|
CHECK(v.isUndefined());
|
|
EVAL("obj2.y", &v);
|
|
CHECK(v.isNull());
|
|
EVAL("obj2.x", &v);
|
|
CHECK(v.isUndefined());
|
|
EVAL("obj1.y = 0", &v);
|
|
CHECK(v.isInt32(0));
|
|
*resolvedp = true;
|
|
return true;
|
|
}
|
|
}
|
|
CHECK(false);
|
|
return false;
|
|
}
|
|
|
|
static bool
|
|
my_resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp)
|
|
{
|
|
return static_cast<cls_testResolveRecursion*>(JS_GetPrivate(obj))->
|
|
doResolve(obj, id, resolvedp);
|
|
}
|
|
END_TEST(testResolveRecursion)
|
|
|
|
/*
|
|
* Test that JS_InitStandardClasses does not cause resolve hooks to be called.
|
|
*
|
|
* (XPConnect apparently does have global classes, such as the one created by
|
|
* nsMessageManagerScriptExecutor::InitChildGlobalInternal(), that have resolve
|
|
* hooks which can call back into JS, and on which JS_InitStandardClasses is
|
|
* called. Calling back into JS in the middle of resolving `undefined` is bad.)
|
|
*/
|
|
BEGIN_TEST(testResolveRecursion_InitStandardClasses)
|
|
{
|
|
CHECK(JS_InitStandardClasses(cx, global));
|
|
return true;
|
|
}
|
|
|
|
const JSClass* getGlobalClass() override {
|
|
static const JSClass myGlobalClass = {
|
|
"testResolveRecursion_InitStandardClasses_myGlobalClass",
|
|
JSCLASS_GLOBAL_FLAGS,
|
|
nullptr, // add
|
|
nullptr, // delete
|
|
nullptr, // get
|
|
nullptr, // set
|
|
nullptr, // enumerate
|
|
my_resolve,
|
|
nullptr, // mayResolve
|
|
nullptr, // convert
|
|
nullptr, // finalize
|
|
nullptr, // call
|
|
nullptr, // hasInstance
|
|
nullptr, // construct
|
|
JS_GlobalObjectTraceHook
|
|
};
|
|
|
|
return &myGlobalClass;
|
|
}
|
|
|
|
static bool
|
|
my_resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp)
|
|
{
|
|
MOZ_ASSERT_UNREACHABLE("resolve hook should not be called from InitStandardClasses");
|
|
JS_ReportError(cx, "FAIL");
|
|
return false;
|
|
}
|
|
END_TEST(testResolveRecursion_InitStandardClasses)
|