Refactor static getter function prototype to include thisValue in addition to the...
[WebKit-https.git] / Source / WebCore / bindings / js / JSHistoryCustom.cpp
index 9f92612..09b12a2 100644 (file)
@@ -38,19 +38,19 @@ using namespace JSC;
 
 namespace WebCore {
 
-static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
+static EncodedJSValue nonCachingStaticBackFunctionGetter(ExecState* exec, EncodedJSValue, EncodedJSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionBack);
+    return JSValue::encode(JSFunction::create(exec->vm(), exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionBack));
 }
 
-static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
+static EncodedJSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, EncodedJSValue, EncodedJSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionForward);
+    return JSValue::encode(JSFunction::create(exec->vm(), exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionForward));
 }
 
-static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
+static EncodedJSValue nonCachingStaticGoFunctionGetter(ExecState* exec, EncodedJSValue, EncodedJSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.publicName(), jsHistoryPrototypeFunctionGo);
+    return JSValue::encode(JSFunction::create(exec->vm(), exec->lexicalGlobalObject(), 1, propertyName.publicName(), jsHistoryPrototypeFunctionGo));
 }
 
 bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -61,22 +61,23 @@ bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propert
     // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
     // allowed, return false so the normal lookup will take place.
     String message;
-    if (shouldAllowAccessToFrame(exec, impl()->frame(), message))
+    if (shouldAllowAccessToFrame(exec, impl().frame(), message))
         return false;
 
     // Check for the few functions that we allow, even when called cross-domain.
+    // Make these read-only / non-configurable to prevent writes via defineProperty.
     const HashEntry* entry = JSHistoryPrototype::info()->propHashTable(exec)->entry(exec, propertyName);
     if (entry) {
         // Allow access to back(), forward() and go() from any frame.
         if (entry->attributes() & JSC::Function) {
             if (entry->function() == jsHistoryPrototypeFunctionBack) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticBackFunctionGetter);
+                slot.setCustom(this, ReadOnly | DontDelete | DontEnum, nonCachingStaticBackFunctionGetter);
                 return true;
             } else if (entry->function() == jsHistoryPrototypeFunctionForward) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticForwardFunctionGetter);
+                slot.setCustom(this, ReadOnly | DontDelete | DontEnum, nonCachingStaticForwardFunctionGetter);
                 return true;
             } else if (entry->function() == jsHistoryPrototypeFunctionGo) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticGoFunctionGetter);
+                slot.setCustom(this, ReadOnly | DontDelete | DontEnum, nonCachingStaticGoFunctionGetter);
                 return true;
             }
         }
@@ -88,60 +89,15 @@ bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propert
         }
     }
 
-    printErrorMessageForFrame(impl()->frame(), message);
+    printErrorMessageForFrame(impl().frame(), message);
     slot.setUndefined();
     return true;
 }
 
-bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
-{
-    if (!impl()->frame()) {
-        descriptor.setUndefined();
-        return true;
-    }
-
-    // Throw out all cross domain access
-    if (!shouldAllowAccessToFrame(exec, impl()->frame()))
-        return true;
-
-    // Check for the few functions that we allow, even when called cross-domain.
-    const HashEntry* entry = JSHistoryPrototype::info()->propHashTable(exec)->entry(exec, propertyName);
-    if (entry) {
-        PropertySlot slot(this);
-        // Allow access to back(), forward() and go() from any frame.
-        if (entry->attributes() & JSC::Function) {
-            if (entry->function() == jsHistoryPrototypeFunctionBack) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticBackFunctionGetter);
-                descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
-                return true;
-            } else if (entry->function() == jsHistoryPrototypeFunctionForward) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticForwardFunctionGetter);
-                descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
-                return true;
-            } else if (entry->function() == jsHistoryPrototypeFunctionGo) {
-                slot.setCustom(this, entry->attributes(), nonCachingStaticGoFunctionGetter);
-                descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
-                return true;
-            }
-        }
-    } else {
-        // Allow access to toString() cross-domain, but always Object.toString.
-        if (propertyName == exec->propertyNames().toString) {
-            PropertySlot slot(this);
-            slot.setCustom(this, ReadOnly | DontDelete | DontEnum, objectToStringFunctionGetter);
-            descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
-            return true;
-        }
-    }
-
-    descriptor.setUndefined();
-    return true;
-}
-
 bool JSHistory::putDelegate(ExecState* exec, PropertyName, JSValue, PutPropertySlot&)
 {
     // Only allow putting by frames in the same origin.
-    if (!shouldAllowAccessToFrame(exec, impl()->frame()))
+    if (!shouldAllowAccessToFrame(exec, impl().frame()))
         return true;
     return false;
 }
@@ -150,7 +106,7 @@ bool JSHistory::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prope
 {
     JSHistory* thisObject = jsCast<JSHistory*>(cell);
     // Only allow deleting by frames in the same origin.
-    if (!shouldAllowAccessToFrame(exec, thisObject->impl()->frame()))
+    if (!shouldAllowAccessToFrame(exec, thisObject->impl().frame()))
         return false;
     return Base::deleteProperty(thisObject, exec, propertyName);
 }
@@ -159,7 +115,7 @@ bool JSHistory::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned pr
 {
     JSHistory* thisObject = jsCast<JSHistory*>(cell);
     // Only allow deleting by frames in the same origin.
-    if (!shouldAllowAccessToFrame(exec, thisObject->impl()->frame()))
+    if (!shouldAllowAccessToFrame(exec, thisObject->impl().frame()))
         return false;
     return Base::deletePropertyByIndex(thisObject, exec, propertyName);
 }
@@ -168,20 +124,20 @@ void JSHistory::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyN
 {
     JSHistory* thisObject = jsCast<JSHistory*>(object);
     // Only allow the history object to enumerated by frames in the same origin.
-    if (!shouldAllowAccessToFrame(exec, thisObject->impl()->frame()))
+    if (!shouldAllowAccessToFrame(exec, thisObject->impl().frame()))
         return;
     Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
 }
 
 JSValue JSHistory::state(ExecState *exec) const
 {
-    History* history = static_cast<History*>(impl());
+    History& history = impl();
 
     JSValue cachedValue = m_state.get();
-    if (!cachedValue.isEmpty() && !history->stateChanged())
+    if (!cachedValue.isEmpty() && !history.stateChanged())
         return cachedValue;
 
-    RefPtr<SerializedScriptValue> serialized = history->state();
+    RefPtr<SerializedScriptValue> serialized = history.state();
     JSValue result = serialized ? serialized->deserialize(exec, globalObject(), 0) : jsNull();
     const_cast<JSHistory*>(this)->m_state.set(exec->vm(), this, result);
     return result;
@@ -205,7 +161,7 @@ JSValue JSHistory::pushState(ExecState* exec)
     }
 
     ExceptionCode ec = 0;
-    impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
+    impl().stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
     setDOMException(exec, ec);
 
     m_state.clear();
@@ -231,7 +187,7 @@ JSValue JSHistory::replaceState(ExecState* exec)
     }
 
     ExceptionCode ec = 0;
-    impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
+    impl().stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
     setDOMException(exec, ec);
 
     m_state.clear();