Fix unreliable behavior of array methods on qml list properties
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 9 Apr 2014 11:32:39 +0000 (13:32 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 9 Apr 2014 14:49:05 +0000 (16:49 +0200)
Array methods such as forEach rely on the hasProperty boolean of getIndexed to
be set appropriately. Some getIndexed implementation - such as the
QQmlListProperty one - didn't initialize it correctly and therefore the
behavior was undefined.

Task-number: QTBUG-38088
Change-Id: I34bc3136d8cc2bc280397d0c4d5051e7d72269e8
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/qml/qqmlcontextwrapper.cpp
src/qml/qml/qqmllistwrapper.cpp
src/qml/qml/qqmlxmlhttprequest.cpp
src/quick/items/context2d/qquickcontext2d.cpp

index 1c210b5..987b228 100644 (file)
@@ -160,6 +160,8 @@ ReturnedValue ArgumentsObject::getIndexed(Managed *m, uint index, bool *hasPrope
             *hasProperty = true;
         return args->context->callData->args[index].asReturnedValue();
     }
+    if (hasProperty)
+        *hasProperty = false;
     return Encode::undefined();
 }
 
index 54bf986..a5574b7 100644 (file)
@@ -461,6 +461,9 @@ ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasPr
         return Encode::undefined();
     }
 
+    if (hasProperty)
+        *hasProperty = true;
+
     ExecutionEngine *v4 = m->engine();
     QQmlEnginePrivate *ep = v4->v8Engine->engine() ? QQmlEnginePrivate::get(v4->v8Engine->engine()) : 0;
     if (ep)
index 0d60fee..fd50e2d 100644 (file)
@@ -129,13 +129,21 @@ ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProper
 
     QV4::ExecutionEngine *e = m->engine();
     QmlListWrapper *w = m->as<QmlListWrapper>();
-    if (!w)
+    if (!w) {
+        if (hasProperty)
+            *hasProperty = false;
         return e->currentContext()->throwTypeError();
+    }
 
     quint32 count = w->property.count ? w->property.count(&w->property) : 0;
-    if (index < count && w->property.at)
+    if (index < count && w->property.at) {
+        if (hasProperty)
+            *hasProperty = true;
         return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index));
+    }
 
+    if (hasProperty)
+        *hasProperty = false;
     return Primitive::undefinedValue().asReturnedValue();
 }
 
index 184a9fe..d89dc92 100644 (file)
@@ -905,8 +905,11 @@ ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty
 {
     QV4::ExecutionEngine *v4 = m->engine();
     NamedNodeMap *r = m->as<NamedNodeMap>();
-    if (!r)
+    if (!r) {
+        if (hasProperty)
+            *hasProperty = false;
         return v4->currentContext()->throwTypeError();
+    }
 
     QV8Engine *engine = v4->v8Engine;
 
@@ -960,8 +963,11 @@ ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
 {
     QV4::ExecutionEngine *v4 = m->engine();
     NodeList *r = m->as<NodeList>();
-    if (!r)
+    if (!r) {
+        if (hasProperty)
+            *hasProperty = false;
         return v4->currentContext()->throwTypeError();
+    }
 
     QV8Engine *engine = v4->v8Engine;
 
index 567ed64..2a6eae7 100644 (file)
@@ -3175,8 +3175,11 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint
     QV4::ExecutionEngine *v4 = m->engine();
     QV4::Scope scope(v4);
     QV4::Scoped<QQuickJSContext2DPixelData> r(scope, m->as<QQuickJSContext2DPixelData>());
-    if (!m)
+    if (!m) {
+        if (hasProperty)
+            *hasProperty = false;
         return m->engine()->currentContext()->throwTypeError();
+    }
 
     if (r && index < static_cast<quint32>(r->image.width() * r->image.height() * 4)) {
         if (hasProperty)