1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsapi-tests/testLookup.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,98 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "jsfun.h" // for js::IsInternalFunctionObject 1.12 + 1.13 +#include "jsapi-tests/tests.h" 1.14 + 1.15 +#include "jsobjinlines.h" 1.16 + 1.17 +BEGIN_TEST(testLookup_bug522590) 1.18 +{ 1.19 + // Define a function that makes method-bearing objects. 1.20 + JS::RootedValue x(cx); 1.21 + EXEC("function mkobj() { return {f: function () {return 2;}} }"); 1.22 + 1.23 + // Calling mkobj() multiple times must create multiple functions in ES5. 1.24 + EVAL("mkobj().f !== mkobj().f", &x); 1.25 + CHECK_SAME(x, JSVAL_TRUE); 1.26 + 1.27 + // Now make x.f a method. 1.28 + EVAL("mkobj()", &x); 1.29 + JS::RootedObject xobj(cx, JSVAL_TO_OBJECT(x)); 1.30 + 1.31 + // This lookup must not return an internal function object. 1.32 + JS::RootedValue r(cx); 1.33 + CHECK(JS_LookupProperty(cx, xobj, "f", &r)); 1.34 + CHECK(r.isObject()); 1.35 + JSObject *funobj = &r.toObject(); 1.36 + CHECK(funobj->is<JSFunction>()); 1.37 + CHECK(!js::IsInternalFunctionObject(funobj)); 1.38 + 1.39 + return true; 1.40 +} 1.41 +END_TEST(testLookup_bug522590) 1.42 + 1.43 +static const JSClass DocumentAllClass = { 1.44 + "DocumentAll", 1.45 + JSCLASS_EMULATES_UNDEFINED, 1.46 + JS_PropertyStub, 1.47 + JS_DeletePropertyStub, 1.48 + JS_PropertyStub, 1.49 + JS_StrictPropertyStub, 1.50 + JS_EnumerateStub, 1.51 + JS_ResolveStub, 1.52 + JS_ConvertStub 1.53 +}; 1.54 + 1.55 +bool 1.56 +document_resolve(JSContext *cx, JS::HandleObject obj, JS::HandleId id, 1.57 + JS::MutableHandleObject objp) 1.58 +{ 1.59 + // If id is "all", resolve document.all=true. 1.60 + JS::RootedValue v(cx); 1.61 + if (!JS_IdToValue(cx, id, &v)) 1.62 + return false; 1.63 + if (JSVAL_IS_STRING(v)) { 1.64 + JSString *str = JSVAL_TO_STRING(v); 1.65 + JSFlatString *flatStr = JS_FlattenString(cx, str); 1.66 + if (!flatStr) 1.67 + return false; 1.68 + if (JS_FlatStringEqualsAscii(flatStr, "all")) { 1.69 + JS::Rooted<JSObject*> docAll(cx, 1.70 + JS_NewObject(cx, &DocumentAllClass, JS::NullPtr(), JS::NullPtr())); 1.71 + if (!docAll) 1.72 + return false; 1.73 + JS::Rooted<JS::Value> allValue(cx, ObjectValue(*docAll)); 1.74 + bool ok = JS_DefinePropertyById(cx, obj, id, allValue, nullptr, nullptr, 0); 1.75 + objp.set(ok ? obj.get() : nullptr); 1.76 + return ok; 1.77 + } 1.78 + } 1.79 + objp.set(nullptr); 1.80 + return true; 1.81 +} 1.82 + 1.83 +static const JSClass document_class = { 1.84 + "document", JSCLASS_NEW_RESOLVE, 1.85 + JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, 1.86 + JS_EnumerateStub, (JSResolveOp) document_resolve, JS_ConvertStub 1.87 +}; 1.88 + 1.89 +BEGIN_TEST(testLookup_bug570195) 1.90 +{ 1.91 + JS::RootedObject obj(cx, JS_NewObject(cx, &document_class, JS::NullPtr(), JS::NullPtr())); 1.92 + CHECK(obj); 1.93 + CHECK(JS_DefineProperty(cx, global, "document", obj, 0)); 1.94 + JS::RootedValue v(cx); 1.95 + EVAL("document.all ? true : false", &v); 1.96 + CHECK_SAME(v, JSVAL_FALSE); 1.97 + EVAL("document.hasOwnProperty('all')", &v); 1.98 + CHECK_SAME(v, JSVAL_TRUE); 1.99 + return true; 1.100 +} 1.101 +END_TEST(testLookup_bug570195)