Don't enumerate Function.prototype.{connect,disconnect}
authorKent Hansen <kent.hansen@nokia.com>
Thu, 25 Aug 2011 10:51:03 +0000 (12:51 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 26 Aug 2011 05:54:35 +0000 (07:54 +0200)
QML/JS adds connect and disconnect methods to the standard
Function.prototype object.
Follow the convention of ECMA-262: Function properties should
be non-enumerable.
In particular, we don't want such built-in properties to show
up in user code "for-in" statements.

Task-number: QTBUG-21120
Change-Id: I416106badf35daddf32e16f757d37b2b09e58310
Reviewed-on: http://codereview.qt.nokia.com/3587
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
src/declarative/qml/v8/qv8qobjectwrapper.cpp
tests/auto/declarative/qjsengine/tst_qjsengine.cpp

index c7ed011..f59e995 100644 (file)
@@ -280,8 +280,8 @@ void QV8QObjectWrapper::init(QV8Engine *engine)
 
     {
     v8::Local<v8::Object> prototype = engine->global()->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject();
-    prototype->Set(v8::String::New("connect"), V8FUNCTION(Connect, engine));
-    prototype->Set(v8::String::New("disconnect"), V8FUNCTION(Disconnect, engine));
+    prototype->Set(v8::String::New("connect"), V8FUNCTION(Connect, engine), v8::DontEnum);
+    prototype->Set(v8::String::New("disconnect"), V8FUNCTION(Disconnect, engine), v8::DontEnum);
     }
 }
 
index d2f4b3b..a6b4251 100644 (file)
@@ -325,6 +325,7 @@ private slots:
     void dateRoundtripQtJSQt();
     void dateConversionJSQt();
     void dateConversionQtJS();
+    void functionPrototypeExtensions();
 };
 
 tst_QJSEngine::tst_QJSEngine()
@@ -6478,6 +6479,24 @@ void tst_QJSEngine::scriptValueFromQMetaObject()
 }
 #endif
 
+void tst_QJSEngine::functionPrototypeExtensions()
+{
+    // QJS adds connect and disconnect properties to Function.prototype.
+    QJSEngine eng;
+    QJSValue funProto = eng.globalObject().property("Function").property("prototype");
+    QVERIFY(funProto.isFunction());
+    QVERIFY(funProto.property("connect").isFunction());
+    QCOMPARE(funProto.propertyFlags("connect"), QJSValue::SkipInEnumeration);
+    QVERIFY(funProto.property("disconnect").isFunction());
+    QCOMPARE(funProto.propertyFlags("disconnect"), QJSValue::SkipInEnumeration);
+
+    // No properties should appear in for-in statements.
+    QJSValue props = eng.evaluate("props = []; for (var p in Function.prototype) props.push(p); props");
+    QVERIFY(!eng.hasUncaughtException());
+    QVERIFY(props.isArray());
+    QCOMPARE(props.property("length").toInt32(), 0);
+}
+
 QTEST_MAIN(tst_QJSEngine)
 
 #include "tst_qjsengine.moc"