2011-05-18 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>
authorcaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 May 2011 14:12:56 +0000 (14:12 +0000)
committercaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 May 2011 14:12:56 +0000 (14:12 +0000)
        Reviewed by Andreas Kling.

        [Qt] Fix tst_QWebFrame::getSetStaticProperty() autotest
        https://bugs.webkit.org/show_bug.cgi?id=60984

        The code for converting objects to QVariantMap was causing exception,
        that was "leaking" to the next evaluation. One situation was reading
        the property 'localStorage' when we do not have a proper security
        origin, which throws a SECURITY_ERR.

        Now, we will simply not include on the QVariantMap those properties,
        and make sure that we clean the exception if necessary.

        * bridge/qt/qt_runtime.cpp:
        (JSC::Bindings::convertValueToQVariantMap):
        Extracted function that performs conversion from JSObject to a QVariantMap. This
        functions makes sure that exception is clean after its execution.

        (JSC::Bindings::convertValueToQVariant):
        Use the previous function. Add a comment explaining the choice of distance value.

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

Source/WebCore/ChangeLog
Source/WebCore/bridge/qt/qt_runtime.cpp

index 9ed5650..5cf9a33 100644 (file)
@@ -1,3 +1,26 @@
+2011-05-18  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
+
+        Reviewed by Andreas Kling.
+
+        [Qt] Fix tst_QWebFrame::getSetStaticProperty() autotest
+        https://bugs.webkit.org/show_bug.cgi?id=60984
+
+        The code for converting objects to QVariantMap was causing exception,
+        that was "leaking" to the next evaluation. One situation was reading
+        the property 'localStorage' when we do not have a proper security
+        origin, which throws a SECURITY_ERR.
+
+        Now, we will simply not include on the QVariantMap those properties,
+        and make sure that we clean the exception if necessary.
+
+        * bridge/qt/qt_runtime.cpp:
+        (JSC::Bindings::convertValueToQVariantMap):
+        Extracted function that performs conversion from JSObject to a QVariantMap. This
+        functions makes sure that exception is clean after its execution.
+
+        (JSC::Bindings::convertValueToQVariant):
+        Use the previous function. Add a comment explaining the choice of distance value.
+
 2011-05-18  Ilya Tikhonovsky  <loislo@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index 7e2bf20..62d4417 100644 (file)
@@ -180,6 +180,37 @@ static JSRealType valueRealType(ExecState* exec, JSValue val)
     return String; // I don't know.
 }
 
+QVariant convertValueToQVariant(ExecState*, JSValue, QMetaType::Type, int*, HashSet<JSObject*>*, int);
+
+static QVariantMap convertValueToQVariantMap(ExecState* exec, JSObject* object, HashSet<JSObject*>* visitedObjects, int recursionLimit)
+{
+    Q_ASSERT(!exec->hadException());
+
+    PropertyNameArray properties(exec);
+    object->getPropertyNames(exec, properties);
+    PropertyNameArray::const_iterator it = properties.begin();
+    QVariantMap result;
+    int objdist = 0;
+
+    while (it != properties.end()) {
+        if (object->propertyIsEnumerable(exec, *it)) {
+            JSValue val = object->get(exec, *it);
+            if (exec->hadException())
+                exec->clearException();
+            else {
+                QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects, recursionLimit);
+                if (objdist >= 0) {
+                    UString ustring = (*it).ustring();
+                    QString id = QString((const QChar*)ustring.impl()->characters(), ustring.length());
+                    result.insert(id, v);
+                }
+            }
+        }
+        ++it;
+    }
+    return result;
+}
+
 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance, HashSet<JSObject*>* visitedObjects, int recursionLimit)
 {
     --recursionLimit;
@@ -354,27 +385,9 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
 
         case QMetaType::QVariantMap:
             if (type == Object || type == Array || type == RTArray) {
-                // Enumerate the contents of the object
-                PropertyNameArray properties(exec);
-                object->getPropertyNames(exec, properties);
-                PropertyNameArray::const_iterator it = properties.begin();
-
-                QVariantMap result;
-                int objdist = 0;
-                while(it != properties.end()) {
-                    if (object->propertyIsEnumerable(exec, *it)) {
-                        JSValue val = object->get(exec, *it);
-                        QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects, recursionLimit);
-                        if (objdist >= 0) {
-                            UString ustring = (*it).ustring();
-                            QString id = QString((const QChar*)ustring.impl()->characters(), ustring.length());
-                            result.insert(id, v);
-                        }
-                    }
-                    ++it;
-                }
+                ret = QVariant(convertValueToQVariantMap(exec, object, visitedObjects, recursionLimit));
+                // Those types can still have perfect matches, e.g. 'bool' if value is a Boolean Object.
                 dist = 1;
-                ret = QVariant(result);
             }
             break;