void namedPropertyQueryCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) { if (!name->IsString()) return; const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); TestInterface2V8Internal::namedPropertyQuery(propertyName, info); }
void namedPropertySetterCallback(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!name->IsString()) return; const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); V8TestIntegerIndexedGlobal::namedPropertySetterCustom(propertyName, v8Value, info); }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (info.Holder()->HasRealNamedProperty(name)) return; if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) return; TestInterface* impl = V8TestInterface::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); bool result0Enabled = false; RefPtr<Node> result0; bool result1Enabled = false; RefPtr<NodeList> result1; impl->getItem(propertyName, result0Enabled, result0, result1Enabled, result1); if (!result0Enabled && !result1Enabled) return; if (result0Enabled) { v8SetReturnValueFast(info, WTF::getPtr(result0.release()), impl); return; } if (result1Enabled) { v8SetReturnValueFast(info, WTF::getPtr(result1.release()), impl); return; } v8SetReturnValueNull(info); }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) return; if (info.Holder()->HasRealNamedCallbackProperty(name)) return; if (info.Holder()->HasRealNamedProperty(name)) return; TestInterface* collection = V8TestInterface::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); bool element0Enabled = false; RefPtr<Node> element0; bool element1Enabled = false; RefPtr<NodeList> element1; collection->getItem(propertyName, element0Enabled, element0, element1Enabled, element1); if (element0Enabled) { v8SetReturnValueFast(info, element0.release(), collection); return; } if (element1Enabled) { v8SetReturnValueFast(info, element1.release(), collection); return; } return; }
// We lazy create interfaces like testRunner and internals on first access // inside layout tests since creating the bindings is expensive. Then we store // them in a hidden Map on the window so that later accesses will reuse the same // wrapper. static bool installTestInterfaceIfNeeded(LocalFrame& frame, v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!LayoutTestSupport::isRunningLayoutTest()) return false; v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); AtomicString propName = toCoreAtomicString(name); v8::Local<v8::Value> interfaces = V8HiddenValue::getHiddenValue(isolate, info.Holder(), V8HiddenValue::testInterfaces(isolate)); if (interfaces.IsEmpty()) { interfaces = v8::Map::New(isolate); V8HiddenValue::setHiddenValue(isolate, info.Holder(), V8HiddenValue::testInterfaces(isolate), interfaces); } v8::Local<v8::Map> interfacesMap = interfaces.As<v8::Map>(); v8::Local<v8::Value> result = v8CallOrCrash(interfacesMap->Get(context, name)); if (!result->IsUndefined()) { v8SetReturnValue(info, result); return true; } v8::Local<v8::Value> interface = frame.loader().client()->createTestInterface(propName); if (!interface.IsEmpty()) { v8CallOrCrash(interfacesMap->Set(context, name, interface)); v8SetReturnValue(info, interface); return true; } return false; }
static void namedPropertyDeleter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) { TestEventTarget* collection = V8TestEventTarget::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); bool result = collection->anonymousNamedDeleter(propertyName); return v8SetReturnValueBool(info, result); }
void namedPropertyGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!name->IsString()) return; const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); TestSpecialOperationsV8Internal::namedPropertyGetter(propertyName, info); }
void namedPropertyQueryCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) { if (!name->IsString()) return; const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); V8TestIntegerIndexedPrimaryGlobal::namedPropertyQueryCustom(propertyName, info); }
static void namedPropertyDeleter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) { TestEventTarget* imp = V8TestEventTarget::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); DeleteResult result = imp->anonymousNamedDeleter(propertyName); if (result != DeleteUnknownProperty) return v8SetReturnValueBool(info, result == DeleteSuccess); }
static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info) { TestInterface* collection = V8TestInterface::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); ExceptionState exceptionState(info.Holder(), info.GetIsolate()); bool result = collection->namedPropertyQuery(propertyName, exceptionState); if (exceptionState.throwIfNeeded()) return; if (!result) return; v8SetReturnValueInt(info, v8::None); }
static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info) { TestSpecialOperations* impl = V8TestSpecialOperations::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); v8::String::Utf8Value namedProperty(name); ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "TestSpecialOperations", info.Holder(), info.GetIsolate()); bool result = impl->namedPropertyQuery(propertyName, exceptionState); if (exceptionState.throwIfNeeded()) return; if (!result) return; v8SetReturnValueInt(info, v8::None); }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (info.Holder()->HasRealNamedProperty(name)) return; if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) return; TestSpecialOperationsNotEnumerable* impl = V8TestSpecialOperationsNotEnumerable::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); String result = impl->anonymousNamedGetter(propertyName); if (result.isNull()) return; v8SetReturnValueString(info, result, info.GetIsolate()); }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (info.Holder()->HasRealNamedProperty(name)) return; if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) return; TestEventTarget* imp = V8TestEventTarget::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); RefPtr<Node> result = imp->namedItem(propertyName); if (!result) return; v8SetReturnValueFast(info, result.release(), imp); }
static void namedPropertyDeleter(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) { if (!name->IsString()) return; TestInterface2* impl = V8TestInterface2::toImpl(info.Holder()); AtomicString propertyName = toCoreAtomicString(name.As<v8::String>()); v8::String::Utf8Value namedProperty(name); ExceptionState exceptionState(ExceptionState::DeletionContext, *namedProperty, "TestInterface2", info.Holder(), info.GetIsolate()); DeleteResult result = impl->deleteNamedItem(propertyName, exceptionState); if (exceptionState.throwIfNeeded()) return; if (result != DeleteUnknownProperty) return v8SetReturnValueBool(info, result == DeleteSuccess); }
static void namedPropertyGetter(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!name->IsString()) return; auto nameString = name.As<v8::String>(); TestInterface2* impl = V8TestInterface2::toImpl(info.Holder()); AtomicString propertyName = toCoreAtomicString(nameString); v8::String::Utf8Value namedProperty(nameString); ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "TestInterface2", info.Holder(), info.GetIsolate()); TestInterfaceEmpty* result = impl->namedItem(propertyName, exceptionState); if (exceptionState.throwIfNeeded()) return; if (!result) return; v8SetReturnValueFast(info, result, impl); }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty()) return; if (info.Holder()->HasRealNamedCallbackProperty(name)) return; if (info.Holder()->HasRealNamedProperty(name)) return; ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); TestEventTarget* collection = V8TestEventTarget::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); RefPtr<Node> element = collection->namedItem(propertyName); if (!element) return; v8SetReturnValueFast(info, element.release(), collection); }
static void getter(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) { // FIXME: Consider passing StringImpl directly. AtomicString name = toCoreAtomicString(property); HTMLDocument* htmlDocument = V8HTMLDocument::toNative(info.Holder()); ASSERT(htmlDocument); v8::Handle<v8::Value> result = getNamedProperty(htmlDocument, name, info.Holder(), info.GetIsolate()); if (!result.IsEmpty()) { v8SetReturnValue(info, result); return; } v8::Handle<v8::Value> prototype = info.Holder()->GetPrototype(); if (prototype->IsObject()) { v8SetReturnValue(info, prototype.As<v8::Object>()->Get(property)); return; } }
static void getter(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { if (!property->IsString()) return; // FIXME: Consider passing StringImpl directly. AtomicString name = toCoreAtomicString(property.As<v8::String>()); HTMLDocument* htmlDocument = V8HTMLDocument::toImpl(info.Holder()); ASSERT(htmlDocument); v8::Local<v8::Value> result = getNamedProperty(htmlDocument, name, info.Holder(), info.GetIsolate()); if (!result.IsEmpty()) { v8SetReturnValue(info, result); return; } v8::Local<v8::Value> value; if (info.Holder()->GetRealNamedPropertyInPrototypeChain(info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()).ToLocal(&value)) v8SetReturnValue(info, value); }
void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* window = V8Window::toNative(info.Holder()); if (!window) return; LocalFrame* frame = window->frame(); // window is detached from a frame. if (!frame) return; // Search sub-frames. AtomicString propName = toCoreAtomicString(name); Frame* child = frame->tree().scopedChild(propName); if (child) { v8SetReturnValueFast(info, child->domWindow(), window); return; } // Search IDL functions defined in the prototype if (!info.Holder()->GetRealNamedProperty(name).IsEmpty()) return; // Search named items in the document. Document* doc = frame->document(); if (doc && doc->isHTMLDocument()) { if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName.impl())) { RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName); if (!items->isEmpty()) { if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items.release(), window); return; } } } }
static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { TestSpecialOperations* impl = V8TestSpecialOperations::toNative(info.Holder()); AtomicString propertyName = toCoreAtomicString(name); bool result0Enabled = false; RefPtrWillBeRawPtr<Node> result0; bool result1Enabled = false; RefPtrWillBeRawPtr<NodeList> result1; impl->getItem(propertyName, result0Enabled, result0, result1Enabled, result1); if (!result0Enabled && !result1Enabled) return; if (result0Enabled) { v8SetReturnValueFast(info, WTF::getPtr(result0.release()), impl); return; } if (result1Enabled) { v8SetReturnValueFast(info, WTF::getPtr(result1.release()), impl); return; } v8SetReturnValueNull(info); }
ScriptCustomElementDefinition* ScriptCustomElementDefinition::forConstructor( ScriptState* scriptState, CustomElementRegistry* registry, const v8::Local<v8::Value>& constructor) { v8::Local<v8::Map> map = ensureCustomElementRegistryMap(scriptState, registry); v8::Local<v8::Value> nameValue = map->Get(scriptState->context(), constructor).ToLocalChecked(); if (!nameValue->IsString()) return nullptr; AtomicString name = toCoreAtomicString(nameValue.As<v8::String>()); // This downcast is safe because only // ScriptCustomElementDefinitions have a name associated with a V8 // constructor in the map; see // ScriptCustomElementDefinition::create. This relies on three // things: // // 1. Only ScriptCustomElementDefinition adds entries to the map. // Audit the use of V8HiddenValue/hidden values in general and // how the map is handled--it should never be leaked to script. // // 2. CustomElementRegistry does not overwrite definitions with a // given name--see the CHECK in CustomElementRegistry::define // --and adds ScriptCustomElementDefinitions to the map without // fail. // // 3. The relationship between the CustomElementRegistry and its // map is never mixed up; this is guaranteed by the bindings // system which provides a stable wrapper, and the map hangs // off the wrapper. // // At a meta-level, this downcast is safe because there is // currently only one implementation of CustomElementDefinition in // product code and that is ScriptCustomElementDefinition. But // that may change in the future. CustomElementDefinition* definition = registry->definitionForName(name); CHECK(definition); return static_cast<ScriptCustomElementDefinition*>(definition); }
bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate); if (window.IsEmpty()) return false; // the frame is gone. LocalDOMWindow* targetWindow = V8Window::toNative(window); ASSERT(targetWindow); LocalFrame* target = targetWindow->frame(); if (!target) return false; // Notify the loader's client if the initial document has been accessed. if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument()) target->loader().didAccessInitialDocument(); if (key->IsString()) { DEFINE_STATIC_LOCAL(const AtomicString, nameOfProtoProperty, ("__proto__", AtomicString::ConstructFromLiteral)); AtomicString name = toCoreAtomicString(key.As<v8::String>()); Frame* childFrame = target->tree().scopedChild(name); // Notice that we can't call HasRealNamedProperty for ACCESS_HAS // because that would generate infinite recursion. if (type == v8::ACCESS_HAS && childFrame) return true; // We need to explicitly compare against nameOfProtoProperty because // V8's JSObject::LocalLookup finds __proto__ before // interceptors and even when __proto__ isn't a "real named property". v8::Handle<v8::String> keyString = key.As<v8::String>(); if (type == v8::ACCESS_GET && childFrame && !host->HasRealNamedProperty(keyString) && !window->HasRealNamedProperty(keyString) && name != nameOfProtoProperty) return true; }
void V8Window::namedPropertyGetterCustom(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { auto nameString = name.As<v8::String>(); DOMWindow* window = V8Window::toImpl(info.Holder()); if (!window) return; Frame* frame = window->frame(); // window is detached from a frame. if (!frame) return; AtomicString propName = toCoreAtomicString(nameString); // Note that the spec doesn't allow any cross-origin named access to the window object. However, // UAs have traditionally allowed named access to named child browsing contexts, even across // origins. So first, search child frames for a frame with a matching name. Frame* child = frame->tree().scopedChild(propName); if (child) { v8SetReturnValueFast(info, child->domWindow(), window); return; } // If the frame is remote, the caller will never be able to access further named results. if (!frame->isLocalFrame()) return; if (installTestInterfaceIfNeeded(toLocalFrame(*frame), nameString, info)) return; // Search named items in the document. Document* doc = toLocalFrame(frame)->document(); if (!doc || !doc->isHTMLDocument()) return; // This is an AllCanRead interceptor. Check that the caller has access to the named results. if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, DoNotReportSecurityError)) return; bool hasNamedItem = toHTMLDocument(doc)->hasNamedItem(propName); bool hasIdItem = doc->hasElementWithId(propName); if (!hasNamedItem && !hasIdItem) return; if (!hasNamedItem && hasIdItem && !doc->containsMultipleElementsWithId(propName)) { v8SetReturnValueFast(info, doc->getElementById(propName), window); return; } RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName); if (!items->isEmpty()) { // TODO(esprehn): Firefox doesn't return an HTMLCollection here if there's // multiple with the same name, but Chrome and Safari does. What's the // right behavior? if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items.release(), window); return; } }