static EncodedJSValue jsDOMWindowWebKit(ExecState* exec, EncodedJSValue thisValue, PropertyName) { JSDOMWindow* castedThis = toJSDOMWindow(JSValue::decode(thisValue)); if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, castedThis->wrapped())) return JSValue::encode(jsUndefined()); return JSValue::encode(toJS(exec, castedThis->globalObject(), castedThis->wrapped().webkitNamespace())); }
void JSDOMWindow::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); // Only allow the window to enumerated by frames in the same origin. if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped())) return; Base::getPropertyNames(thisObject, exec, propertyNames, mode); }
JSValue JSDOMWindow::getPrototype(JSObject* object, ExecState* exec) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped(), DoNotReportSecurityError)) return jsNull(); return Base::getPrototype(object, exec); }
uint32_t JSDOMWindow::getEnumerableLength(ExecState* exec, JSObject* object) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); // Only allow the window to enumerated by frames in the same origin. if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped())) return 0; return Base::getEnumerableLength(exec, thisObject); }
bool JSDOMWindow::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell); // Only allow deleting properties by frames in the same origin. if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped(), ThrowSecurityError)) return false; return Base::deletePropertyByIndex(thisObject, exec, propertyName); }
bool InspectorController::canAccessInspectedScriptState(JSC::ExecState* scriptState) const { JSLockHolder lock(scriptState); JSDOMWindow* inspectedWindow = toJSDOMWindow(scriptState->lexicalGlobalObject()); if (!inspectedWindow) return false; return BindingSecurity::shouldAllowAccessToDOMWindow(scriptState, inspectedWindow->wrapped(), DoNotReportSecurityError); }
void JSDOMWindow::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped(), DoNotReportSecurityError)) { if (mode.includeDontEnumProperties()) addCrossOriginWindowPropertyNames(*exec, propertyNames); return; } Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode); }
bool JSDOMWindow::defineOwnProperty(JSC::JSObject* object, JSC::ExecState* exec, JSC::PropertyName propertyName, const JSC::PropertyDescriptor& descriptor, bool shouldThrow) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); // Only allow defining properties in this way by frames in the same origin, as it allows setters to be introduced. if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped(), ThrowSecurityError)) return false; // Don't allow shadowing location using accessor properties. if (descriptor.isAccessorDescriptor() && propertyName == Identifier::fromString(exec, "location")) return false; return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow); }
void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { ASSERT(scriptExecutionContext); if (!scriptExecutionContext || scriptExecutionContext->isJSExecutionForbidden()) return; VM& vm = scriptExecutionContext->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); // See https://dom.spec.whatwg.org/#dispatching-events spec on calling handleEvent. // "If this throws an exception, report the exception." It should not propagate the // exception. JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, *m_isolatedWorld); if (!globalObject) return; if (scriptExecutionContext->isDocument()) { JSDOMWindow* window = jsCast<JSDOMWindow*>(globalObject); if (!window->wrapped().isCurrentlyDisplayedInFrame()) return; if (wasCreatedFromMarkup() && !scriptExecutionContext->contentSecurityPolicy()->allowInlineEventHandlers(sourceURL(), sourcePosition().m_line)) return; // FIXME: Is this check needed for other contexts? ScriptController& script = window->wrapped().frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return; } ExecState* exec = globalObject->globalExec(); JSValue handleEventFunction = jsFunction; CallData callData; CallType callType = getCallData(handleEventFunction, callData); // If jsFunction is not actually a function, see if it implements the EventListener interface and use that if (callType == CallType::None) { handleEventFunction = jsFunction->get(exec, Identifier::fromString(exec, "handleEvent")); if (UNLIKELY(scope.exception())) { auto* exception = scope.exception(); scope.clearException(); event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); return; } callType = getCallData(handleEventFunction, callData); } if (callType != CallType::None) { Ref<JSEventListener> protectedThis(*this); MarkedArgumentBuffer args; args.append(toJS(exec, globalObject, event)); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(scriptExecutionContext, callType, callData); JSValue thisValue = handleEventFunction == jsFunction ? toJS(exec, globalObject, event->currentTarget()) : jsFunction; NakedPtr<JSC::Exception> exception; JSValue retval = scriptExecutionContext->isDocument() ? JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception) : JSC::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception); InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext); globalObject->setCurrentEvent(savedEvent); if (is<WorkerGlobalScope>(*scriptExecutionContext)) { auto scriptController = downcast<WorkerGlobalScope>(*scriptExecutionContext).script(); bool terminatorCausedException = (scope.exception() && isTerminatedExecutionException(scope.exception())); if (terminatorCausedException || scriptController->isTerminatingExecution()) scriptController->forbidExecution(); } if (exception) { event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); } else { if (!retval.isUndefinedOrNull() && is<BeforeUnloadEvent>(*event)) downcast<BeforeUnloadEvent>(*event).setReturnValue(retval.toWTFString(exec)); if (m_isAttribute) { if (retval.isFalse()) event->preventDefault(); } } } }