JavaScriptCore:
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Dec 2007 18:03:43 +0000 (18:03 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Dec 2007 18:03:43 +0000 (18:03 +0000)
        Reviewed by Darin.

        - Rename isSafeScript to allowsAccess.

        * bindings/NP_jsobject.cpp:
        (_isSafeScript):
        * kjs/JSGlobalObject.h:
        (KJS::JSGlobalObject::allowsAccessFrom): Reverse caller/argument of allowsAccessFrom to match
        the new call.

WebCore:

        Reviewed by Darin.

        - Removes the faulty isSafeScript implementation that was only
          used for plugins.
        - Renames isSafeScript to allowsAccessFrom.

        * bindings/js/JSDOMWindowCustom.cpp:
        (WebCore::JSDOMWindow::customGetOwnPropertySlot):
        (WebCore::JSDOMWindow::customPut):
        * bindings/js/kjs_dom.cpp:
        (WebCore::checkNodeSecurity):
        * bindings/js/kjs_window.cpp:
        (KJS::createWindow):
        (KJS::Window::getValueProperty):
        (KJS::Window::namedItemGetter):
        (KJS::Window::getOwnPropertySlot):
        (KJS::Window::put):
        (KJS::Window::allowsAccessFrom):
        (KJS::Window::setListener):
        (KJS::Window::getListener):
        (KJS::WindowProtoFuncOpen::callAsFunction):
        (KJS::WindowProtoFuncSetTimeout::callAsFunction):
        (KJS::WindowProtoFuncClearTimeout::callAsFunction):
        (KJS::WindowProtoFuncSetInterval::callAsFunction):
        (KJS::WindowProtoFuncAddEventListener::callAsFunction):
        (KJS::WindowProtoFuncRemoveEventListener::callAsFunction):
        (KJS::WindowProtoFuncNotImplemented::callAsFunction):
        (KJS::Location::getOwnPropertySlot):
        (KJS::Location::put):
        (KJS::LocationProtoFuncReplace::callAsFunction):
        (KJS::LocationProtoFuncReload::callAsFunction):
        (KJS::LocationProtoFuncAssign::callAsFunction):
        (KJS::LocationProtoFuncToString::callAsFunction):
        * bindings/js/kjs_window.h:
        (KJS::Window::allowsAccessFrom):
        * bindings/objc/WebScriptObject.mm:
        (-[WebScriptObject _isSafeScript]): Reverse caller/argument of allowsAccessFrom to match
        the new call.
        * bindings/scripts/CodeGeneratorJS.pm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28565 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/bindings/NP_jsobject.cpp
JavaScriptCore/kjs/JSGlobalObject.h
WebCore/ChangeLog
WebCore/bindings/js/JSDOMWindowCustom.cpp
WebCore/bindings/js/kjs_dom.cpp
WebCore/bindings/js/kjs_window.cpp
WebCore/bindings/js/kjs_window.h
WebCore/bindings/objc/WebScriptObject.mm
WebCore/bindings/scripts/CodeGeneratorJS.pm

index f951d0752f3009c047d4697bc9fd0ce9070157c6..4754100e3caa828b44e2deaa97e84df5be8cf257 100644 (file)
@@ -1,3 +1,15 @@
+2007-12-07  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Darin.
+
+        - Rename isSafeScript to allowsAccess.
+
+        * bindings/NP_jsobject.cpp:
+        (_isSafeScript):
+        * kjs/JSGlobalObject.h:
+        (KJS::JSGlobalObject::allowsAccessFrom): Reverse caller/argument of allowsAccessFrom to match
+        the new call.
+
 2007-12-07  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Sam Weinig.
index ab841c0ca75b4077a8ecf623b4d20a29055ebaad..a5878a68e55d821e1c26ab66105ec16ebaff4a36 100644 (file)
@@ -78,11 +78,11 @@ static bool _isSafeScript(JavaScriptObject* obj)
 {
     if (!obj->originRootObject || !obj->rootObject)
         return true;
-    
+
     if (!obj->originRootObject->isValid() || !obj->rootObject->isValid())
         return false;
-        
-    return obj->originRootObject->globalObject()->isSafeScript(obj->rootObject->globalObject());
+
+    return obj->rootObject->globalObject()->allowsAccessFrom(obj->originRootObject->globalObject());
 }
 
 NPObject* _NPN_CreateScriptObject(NPP npp, JSObject* imp, PassRefPtr<RootObject> originRootObject, PassRefPtr<RootObject> rootObject)
index 0ffedebddcd900edd0c56c99684b5a4bd020beae..eb43b0088508639f88bb87955c5e3ecb0beea8ee 100644 (file)
@@ -222,7 +222,7 @@ namespace KJS {
 
         virtual bool shouldInterruptScript() const { return true; }
 
-        virtual bool isSafeScript(const JSGlobalObject*) const { return true; }
+        virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
     private:
         void init();
index 76d2237f3208625d454d5ba2d1321c8e5062d929..6d3b3a918e823aa24624271185eba4cc2c8e534d 100644 (file)
@@ -1,3 +1,45 @@
+2007-12-07  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Darin.
+
+        - Removes the faulty isSafeScript implementation that was only
+          used for plugins.
+        - Renames isSafeScript to allowsAccessFrom.
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::customGetOwnPropertySlot):
+        (WebCore::JSDOMWindow::customPut):
+        * bindings/js/kjs_dom.cpp:
+        (WebCore::checkNodeSecurity):
+        * bindings/js/kjs_window.cpp:
+        (KJS::createWindow):
+        (KJS::Window::getValueProperty):
+        (KJS::Window::namedItemGetter):
+        (KJS::Window::getOwnPropertySlot):
+        (KJS::Window::put):
+        (KJS::Window::allowsAccessFrom):
+        (KJS::Window::setListener):
+        (KJS::Window::getListener):
+        (KJS::WindowProtoFuncOpen::callAsFunction):
+        (KJS::WindowProtoFuncSetTimeout::callAsFunction):
+        (KJS::WindowProtoFuncClearTimeout::callAsFunction):
+        (KJS::WindowProtoFuncSetInterval::callAsFunction):
+        (KJS::WindowProtoFuncAddEventListener::callAsFunction):
+        (KJS::WindowProtoFuncRemoveEventListener::callAsFunction):
+        (KJS::WindowProtoFuncNotImplemented::callAsFunction):
+        (KJS::Location::getOwnPropertySlot):
+        (KJS::Location::put):
+        (KJS::LocationProtoFuncReplace::callAsFunction):
+        (KJS::LocationProtoFuncReload::callAsFunction):
+        (KJS::LocationProtoFuncAssign::callAsFunction):
+        (KJS::LocationProtoFuncToString::callAsFunction):
+        * bindings/js/kjs_window.h:
+        (KJS::Window::allowsAccessFrom):
+        * bindings/objc/WebScriptObject.mm:
+        (-[WebScriptObject _isSafeScript]): Reverse caller/argument of allowsAccessFrom to match
+        the new call.
+        * bindings/scripts/CodeGeneratorJS.pm:
+
 2007-12-08  Rob Buis  <buis@kde.org>
 
         Reviewed by Darin.
index 479965f5aef1d26aada900ba711ff72aec1d291a..daeba628140bde105280797256637702f04c1358 100644 (file)
@@ -56,7 +56,7 @@ bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Iden
     // Look for overrides first
     KJS::JSValue** val = getDirectLocation(propertyName);
     if (val) {
-        if (!isSafeScript(exec)) {
+        if (!allowsAccessFrom(exec)) {
             slot.setUndefined(this);
             return true;
         }
@@ -69,7 +69,7 @@ bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Iden
         return true;
     }
 
-    // FIXME: We need this to work around the blanket isSafeScript check in KJS::Window.  Once we remove that, we
+    // FIXME: We need this to work around the blanket same origin (allowsAccessFrom) check in KJS::Window.  Once we remove that, we
     // can move this to JSDOMWindowPrototype.
     KJS::JSValue* proto = prototype();
     if (proto->isObject()) {
@@ -81,7 +81,7 @@ bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Iden
                     || entry->value.functionValue == &JSDOMWindowPrototypeFunctionClose::create)
                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
                 else {
-                    if (!isSafeScript(exec))
+                    if (!allowsAccessFrom(exec))
                         slot.setUndefined(this);
                     else
                         slot.setStaticEntry(this, entry, KJS::staticFunctionGetter);
@@ -107,7 +107,7 @@ bool JSDOMWindow::customPut(KJS::ExecState* exec, const KJS::Identifier& propert
 
     // We have a local override (e.g. "var location"), save time and jump directly to JSObject.
     if (KJS::JSObject::getDirect(propertyName)) {
-        if (isSafeScript(exec))
+        if (allowsAccessFrom(exec))
             KJS::JSObject::put(exec, propertyName, value, attr);
         return true;
     }
index a67b3b11b9c188e7717c8fb145a3510abc853b80..dd49987263b0c6bb880af9710cd20165a83f7a3c 100644 (file)
@@ -58,12 +58,12 @@ Attr* toAttr(JSValue* val, bool& ok)
 
 bool checkNodeSecurity(ExecState* exec, Node* n)
 {
-  if (!n) 
+  if (!n)
     return false;
 
   // Check to see if the currently executing interpreter is allowed to access the specified node
   Window* win = Window::retrieveWindow(n->document()->frame());
-  return win && win->isSafeScript(exec);
+  return win && win->allowsAccessFrom(exec);
 }
 
 JSValue* toJS(ExecState* exec, EventTarget* target)
index 2b1577fe183749bf802229ea58ae7296053843a1..908d31527f8262e97e923b0a51796bb0f2ca20af 100644 (file)
@@ -390,7 +390,7 @@ static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& ur
     if (dialogArgs)
         newWindow->putDirect("dialogArguments", dialogArgs);
 
-    if (!url.startsWith("javascript:", false) || newWindow->isSafeScript(exec)) {
+    if (!url.startsWith("javascript:", false) || newWindow->allowsAccessFrom(exec)) {
         String completedURL = url.isEmpty() ? url : activeFrame->document()->completeURL(url);
         bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
         
@@ -507,15 +507,15 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
 
    switch (token) {
    case Crypto:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       return jsUndefined(); // FIXME: implement this
    case DOMException:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       return getDOMExceptionConstructor(exec);
     case Event_:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       if (!d->m_evt)
         return jsUndefined();
@@ -524,7 +524,7 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
       return location();
     case Navigator_:
     case ClientInformation: {
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       // Store the navigator in the object so we get the same one each time.
       Navigator *n = new Navigator(exec, impl()->frame());
@@ -535,17 +535,17 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
       return n;
     }
     case Image:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       // FIXME: this property (and the few below) probably shouldn't create a new object every
       // time
       return new ImageConstructorImp(exec, impl()->frame()->document());
     case Option:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       return new JSHTMLOptionElementConstructor(exec, impl()->frame()->document());
     case XMLHttpRequest:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       return new JSXMLHttpRequestConstructorImp(exec, impl()->frame()->document());
     case Audio:
@@ -556,7 +556,7 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
 #endif
 #if ENABLE(XSLT)
     case XSLTProcessor_:
-      if (!isSafeScript(exec))
+      if (!allowsAccessFrom(exec))
         return jsUndefined();
       return new XSLTProcessorConstructorImp(exec);
 #else
@@ -565,7 +565,7 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
 #endif
    }
 
-   if (!isSafeScript(exec))
+   if (!allowsAccessFrom(exec))
      return jsUndefined();
 
    switch (token) {
@@ -638,7 +638,7 @@ JSValue *Window::namedItemGetter(ExecState *exec, JSObject *originalObject, cons
 {
   Window *thisObj = static_cast<Window *>(slot.slotBase());
   Document *doc = thisObj->impl()->frame()->document();
-  ASSERT(thisObj->isSafeScript(exec) && doc && doc->isHTMLDocument());
+  ASSERT(thisObj->allowsAccessFrom(exec) && doc && doc->isHTMLDocument());
 
   String name = propertyName;
   RefPtr<WebCore::HTMLCollection> collection = doc->windowNamedItems(name);
@@ -666,7 +666,7 @@ bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName,
         if (!canShowModalDialog(this))
           return false;
       }
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         slot.setStaticEntry(this, entry, staticFunctionGetter);
       else
         slot.setUndefined(this);
@@ -689,7 +689,7 @@ bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName,
   // allow shortcuts like 'Image1' instead of document.images.Image1
   Document* doc = impl()->frame()->document();
   if (doc && doc->isHTMLDocument()) {
-    if (!isSafeScript(exec)) {
+    if (!allowsAccessFrom(exec)) {
       slot.setUndefined(this);
       return true;
     }
@@ -701,7 +701,7 @@ bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName,
     }
   }
 
-  if (!isSafeScript(exec)) {
+  if (!allowsAccessFrom(exec)) {
     slot.setUndefined(this);
     return true;
   }
@@ -714,7 +714,7 @@ void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value
   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
   if (entry) {
      if (entry->attr & Function) {
-       if (isSafeScript(exec))
+       if (allowsAccessFrom(exec))
          JSObject::put(exec, propertyName, value, attr);
        return;
     }
@@ -728,7 +728,7 @@ void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value
         if (!p->loader()->shouldAllowNavigation(impl()->frame()))
           return;
         DeprecatedString dstUrl = p->loader()->completeURL(DeprecatedString(value->toString(exec))).url();
-        if (!dstUrl.startsWith("javascript:", false) || isSafeScript(exec)) {
+        if (!dstUrl.startsWith("javascript:", false) || allowsAccessFrom(exec)) {
           bool userGesture = p->scriptProxy()->processingUserGesture();
           // We want a new history item if this JS was called via a user gesture
           impl()->frame()->loader()->scheduleLocationChange(dstUrl, p->loader()->outgoingReferrer(), false, userGesture);
@@ -737,172 +737,156 @@ void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value
       return;
     }
     case Onabort:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, abortEvent,value);
       return;
     case Onblur:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, blurEvent,value);
       return;
     case Onchange:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, changeEvent,value);
       return;
     case Onclick:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,clickEvent,value);
       return;
     case Ondblclick:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, dblclickEvent,value);
       return;
     case Onerror:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, errorEvent, value);
       return;
     case Onfocus:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,focusEvent,value);
       return;
     case Onkeydown:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,keydownEvent,value);
       return;
     case Onkeypress:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,keypressEvent,value);
       return;
     case Onkeyup:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,keyupEvent,value);
       return;
     case Onload:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,loadEvent,value);
       return;
     case Onmousedown:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,mousedownEvent,value);
       return;
     case Onmousemove:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,mousemoveEvent,value);
       return;
     case Onmouseout:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,mouseoutEvent,value);
       return;
     case Onmouseover:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,mouseoverEvent,value);
       return;
     case Onmouseup:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,mouseupEvent,value);
       return;
     case OnWindowMouseWheel:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, mousewheelEvent,value);
       return;
     case Onreset:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,resetEvent,value);
       return;
     case Onresize:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,resizeEvent,value);
       return;
     case Onscroll:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,scrollEvent,value);
       return;
     case Onsearch:
-        if (isSafeScript(exec))
+        if (allowsAccessFrom(exec))
             setListener(exec,searchEvent,value);
         return;
     case Onselect:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,selectEvent,value);
       return;
     case Onsubmit:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec,submitEvent,value);
       return;
     case Onbeforeunload:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, beforeunloadEvent, value);
       return;
     case Onunload:
-      if (isSafeScript(exec))
+      if (allowsAccessFrom(exec))
         setListener(exec, unloadEvent, value);
       return;
     default:
       break;
     }
   }
-  if (isSafeScript(exec))
+  if (allowsAccessFrom(exec))
     JSObject::put(exec, propertyName, value, attr);
 }
 
-static bool shouldLoadAsEmptyDocument(const KURL &url)
+bool Window::allowsAccessFrom(const JSGlobalObject* other) const
 {
-  return url.protocol().lower() == "about" || url.isEmpty();
-}
+    const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame();
+    if (!originFrame)
+        return false;
 
-bool Window::isSafeScript(const JSGlobalObject *origin, const JSGlobalObject *target)
-{
-    if (origin == target)
+    const Frame* targetFrame = impl()->frame();
+    if (!targetFrame)
+        return false;
+
+    if (originFrame == targetFrame)
         return true;
         
-    Frame* originFrame = static_cast<const Window*>(origin)->impl()->frame();
-    Frame* targetFrame = static_cast<const Window*>(target)->impl()->frame();
+    WebCore::Document* targetDocument = targetFrame->document();
 
     // JS may be attempting to access the "window" object, which should be valid,
     // even if the document hasn't been constructed yet.  If the document doesn't
     // exist yet allow JS to access the window object.
-    if (!targetFrame->document())
+    if (!targetDocument)
         return true;
 
-    WebCore::Document *originDocument = originFrame->document();
-    WebCore::Document *targetDocument = targetFrame->document();
+    WebCore::Document* originDocument = originFrame->document();
 
-    if (!targetDocument) {
-        return false;
-    }
-
-    WebCore::String targetDomain = targetDocument->domain();
+    const SecurityOrigin& originSecurityOrigin = originDocument->securityOrigin();
+    const SecurityOrigin& targetSecurityOrigin = targetDocument->securityOrigin();
 
-    // Always allow local pages to execute any JS.
-    if (targetDomain.isNull())
+    if (originSecurityOrigin.canAccess(targetSecurityOrigin))
         return true;
 
-    WebCore::String originDomain = originDocument->domain();
-
-    // if this document is being initially loaded as empty by its parent
-    // or opener, allow access from any document in the same domain as
-    // the parent or opener.
-    if (shouldLoadAsEmptyDocument(targetFrame->loader()->url())) {
-        Frame* ancestorFrame = targetFrame->loader()->opener() ? targetFrame->loader()->opener() : targetFrame->tree()->parent();
-        while (ancestorFrame && shouldLoadAsEmptyDocument(ancestorFrame->loader()->url()))
-            ancestorFrame = ancestorFrame->tree()->parent();
-        if (ancestorFrame)
-            originDomain = ancestorFrame->document()->domain();
-    }
-
-    if (targetDomain == originDomain)
-        return true;
+    if (!targetFrame->settings()->privateBrowsingEnabled()) {
+        // FIXME: this error message should contain more specifics of why the same origin check has failed.
+        String message = String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n",
+                                        targetDocument->URL().utf8().data(), originDocument->URL().utf8().data());
 
-    if (!originFrame->settings()->privateBrowsingEnabled()) {
         if (Interpreter::shouldPrintExceptions())
-            printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n", 
-                   targetDocument->URL().latin1(), originDocument->URL().latin1());
-        String message = String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n", 
-                                        targetDocument->URL().latin1(), originDocument->URL().latin1());
+            printf("%s", message.utf8().data());
+
         if (Page* page = targetFrame->page())
             page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
     }
 
     return false;
+    
 }
 
 ExecState* Window::globalExec()
@@ -932,51 +916,9 @@ bool Window::shouldInterruptScript() const
     return page->chrome()->shouldInterruptJavaScript();
 }
 
-bool Window::isSafeScript(ExecState *exec) const
-{
-  Frame* frame = impl()->frame();
-  if (!frame)
-    return false;
-  Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
-  if (!activeFrame)
-    return false;
-  if (activeFrame == frame)
-    return true;
-
-  WebCore::Document* thisDocument = frame->document();
-
-  // JS may be attempting to access the "window" object, which should be valid,
-  // even if the document hasn't been constructed yet.  If the document doesn't
-  // exist yet allow JS to access the window object.
-  if (!thisDocument)
-      return true;
-
-  WebCore::Document* actDocument = activeFrame->document();
-
-  const SecurityOrigin& actSecurityOrigin = actDocument->securityOrigin();
-  const SecurityOrigin& thisSecurityOrigin = thisDocument->securityOrigin();
-
-  if (actSecurityOrigin.canAccess(thisSecurityOrigin))
-    return true;
-
-    if (!frame->settings()->privateBrowsingEnabled()) {
-        // FIXME: this error message should contain more specifics of why the same origin check has failed.
-        String message = String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n",
-                                        thisDocument->URL().utf8().data(), actDocument->URL().utf8().data());
-        
-        if (Interpreter::shouldPrintExceptions())
-            printf("%s", message.utf8().data());
-        
-        if (Page* page = frame->page())
-            page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 1, String());
-    }
-
-  return false;
-}
-
 void Window::setListener(ExecState *exec, const AtomicString &eventType, JSValue *func)
 {
-  if (!isSafeScript(exec))
+  if (!allowsAccessFrom(exec))
     return;
   Frame* frame = impl()->frame();
   if (!frame)
@@ -990,7 +932,7 @@ void Window::setListener(ExecState *exec, const AtomicString &eventType, JSValue
 
 JSValue *Window::getListener(ExecState *exec, const AtomicString &eventType) const
 {
-  if (!isSafeScript(exec))
+  if (!allowsAccessFrom(exec))
     return jsUndefined();
   Frame* frame = impl()->frame();
   if (!frame)
@@ -1362,7 +1304,7 @@ JSValue* WindowProtoFuncOpen::callAsFunction(ExecState* exec, JSObject* thisObj,
             completedURL = activeFrame->document()->completeURL(urlString);
 
         const Window* window = Window::retrieveWindow(frame);
-        if (!completedURL.isEmpty() && (!completedURL.startsWith("javascript:", false) || (window && window->isSafeScript(exec)))) {
+        if (!completedURL.isEmpty() && (!completedURL.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec)))) {
             bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
             frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
         }
@@ -1525,7 +1467,7 @@ JSValue* WindowProtoFuncSetTimeout::callAsFunction(ExecState* exec, JSObject* th
     JSValue *v = args[0];
     UString s = v->toString(exec);
 
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     if (v->isString()) {
       int i = args[1]->toInt32(exec);
@@ -1559,7 +1501,7 @@ JSValue* WindowProtoFuncClearTimeout::callAsFunction(ExecState* exec, JSObject*
 
     JSValue *v = args[0];
 
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     (const_cast<Window*>(window))->clearTimeout(v->toInt32(exec));
     return jsUndefined();
@@ -1577,7 +1519,7 @@ JSValue* WindowProtoFuncSetInterval::callAsFunction(ExecState* exec, JSObject* t
     JSValue *v = args[0];
     UString s = v->toString(exec);
 
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     if (args.size() >= 2 && v->isString()) {
       int i = args[1]->toInt32(exec);
@@ -1608,7 +1550,7 @@ JSValue* WindowProtoFuncAddEventListener::callAsFunction(ExecState* exec, JSObje
     if (!frame)
         return jsUndefined();
 
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     if (JSEventListener* listener = window->findOrCreateJSEventListener(args[1]))
         if (Document *doc = frame->document())
@@ -1625,7 +1567,7 @@ JSValue* WindowProtoFuncRemoveEventListener::callAsFunction(ExecState* exec, JSO
     if (!frame)
         return jsUndefined();
 
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     if (JSEventListener* listener = window->findJSEventListener(args[1]))
         if (Document *doc = frame->document())
@@ -1655,7 +1597,7 @@ JSValue* WindowProtoFuncNotImplemented::callAsFunction(ExecState* exec, JSObject
         return jsUndefined();
 
     // If anyone implements these, they need the safe script security check.
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
     // Not implemented.
     return jsUndefined();
@@ -1958,7 +1900,7 @@ bool Location::getOwnPropertySlot(ExecState *exec, const Identifier& propertyNam
   if (!entry || !(entry->attr & KJS::Function) || (entry->value.functionValue != &LocationProtoFuncReplace::create
                                                    && entry->value.functionValue != &LocationProtoFuncReload::create
                                                    && entry->value.functionValue != &LocationProtoFuncAssign::create))  {
-    if (!window || !window->isSafeScript(exec)) {
+    if (!window || !window->allowsAccessFrom(exec)) {
       slot.setUndefined(this);
       return true;
     }
@@ -1975,7 +1917,7 @@ void Location::put(ExecState *exec, const Identifier &p, JSValue *v, int attr)
   DeprecatedString str = v->toString(exec);
   KURL url = m_frame->loader()->url();
   const Window* window = Window::retrieveWindow(m_frame);
-  bool sameDomainAccess = window && window->isSafeScript(exec);
+  bool sameDomainAccess = window && window->allowsAccessFrom(exec);
 
   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
 
@@ -2058,7 +2000,7 @@ JSValue* LocationProtoFuncReplace::callAsFunction(ExecState* exec, JSObject* thi
         return jsUndefined();
       DeprecatedString str = args[0]->toString(exec);
       const Window* window = Window::retrieveWindow(frame);
-      if (!str.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
+      if (!str.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
         bool userGesture = p->scriptProxy()->processingUserGesture();
         frame->loader()->scheduleLocationChange(p->loader()->completeURL(str).url(), p->loader()->outgoingReferrer(), true, userGesture);
       }
@@ -2077,10 +2019,10 @@ JSValue* LocationProtoFuncReload::callAsFunction(ExecState* exec, JSObject* this
         return jsUndefined();
 
     Window* window = Window::retrieveWindow(frame);
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
 
-    if (!frame->loader()->url().url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
+    if (!frame->loader()->url().url().startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
       bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture();
       frame->loader()->scheduleRefresh(userGesture);
     }
@@ -2102,7 +2044,7 @@ JSValue* LocationProtoFuncAssign::callAsFunction(ExecState* exec, JSObject* this
           return jsUndefined();
         const Window *window = Window::retrieveWindow(frame);
         DeprecatedString dstUrl = p->loader()->completeURL(DeprecatedString(args[0]->toString(exec))).url();
-        if (!dstUrl.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
+        if (!dstUrl.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
             bool userGesture = p->scriptProxy()->processingUserGesture();
             // We want a new history item if this JS was called via a user gesture
             frame->loader()->scheduleLocationChange(dstUrl, p->loader()->outgoingReferrer(), false, userGesture);
@@ -2122,10 +2064,10 @@ JSValue* LocationProtoFuncToString::callAsFunction(ExecState* exec, JSObject* th
         return jsUndefined();
 
     Window* window = Window::retrieveWindow(frame);
-    if (!window->isSafeScript(exec))
+    if (!window->allowsAccessFrom(exec))
         return jsUndefined();
 
-    if (!frame || !Window::retrieveWindow(frame)->isSafeScript(exec))
+    if (!frame || !Window::retrieveWindow(frame)->allowsAccessFrom(exec))
         return jsString();
 
     if (!frame->loader()->url().hasPath())
@@ -2168,5 +2110,5 @@ JSValue* toJS(ExecState*, DOMWindow* domWindow)
         return jsNull();
     return Window::retrieve(frame);
 }
-    
+
 } // namespace WebCore
index 3cc7b5b497d4e8c97dfc6cdf9ba211cd71ea4c0d..be9ec31901eea96cfb1d75ecbf94cb2e19eecbfd 100644 (file)
@@ -103,10 +103,6 @@ namespace KJS {
     void resumeTimeouts(PausedTimeouts*);
 
     void timerFired(DOMWindowTimer*);
-    
-    static bool isSafeScript(const JSGlobalObject *origin, const JSGlobalObject *target);
-    virtual bool isSafeScript(const JSGlobalObject* other) const { return Window::isSafeScript(this, other); }
-    bool isSafeScript(ExecState*) const;
 
     Location* location() const;
 
@@ -140,10 +136,14 @@ namespace KJS {
     
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
-    
+
     virtual ExecState* globalExec();
+
     virtual bool shouldInterruptScript() const;
 
+    virtual bool allowsAccessFrom(const JSGlobalObject*) const;
+    bool allowsAccessFrom(ExecState* exec) const { return allowsAccessFrom(exec->dynamicGlobalObject()); }
+
     enum {
         // Attributes
         Crypto, Event_, Location_, Navigator_,
index 920b31dd7947a5a0651dcc1105469a124d4d569b..d9fbaf9e01f567b85ba20dcebd5687bf05e54a1e 100644 (file)
@@ -207,7 +207,7 @@ static void _didExecute(WebScriptObject *obj)
     if (!_private->originRootObject->isValid())
         return false;
 
-    return _private->originRootObject->globalObject()->isSafeScript(root->globalObject());
+    return root->globalObject()->allowsAccessFrom(_private->originRootObject->globalObject());
 }
 
 - (void)dealloc
index aee89eb6a159746fcdb4a2ad7692644390b590f0..6ade73b9661e1667e3443beeedd08779a93f2f74 100644 (file)
@@ -921,7 +921,7 @@ sub GenerateImplementation
             }
 
             if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
-                push(@implContent, "        if (!isSafeScript(exec))\n");
+                push(@implContent, "        if (!allowsAccessFrom(exec))\n");
                 push(@implContent, "            return jsUndefined();\n");
             }
 
@@ -1025,7 +1025,7 @@ sub GenerateImplementation
                     }
 
                     if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
-                        push(@implContent, "        if (!isSafeScript(exec))\n");
+                        push(@implContent, "        if (!allowsAccessFrom(exec))\n");
                         push(@implContent, "            return;\n");
                     }