Do not cause SegFault when importing empty javascript
authorNobuaki Sukegawa <nsukeg@gmail.com>
Sun, 14 Dec 2014 17:33:05 +0000 (02:33 +0900)
committerNobuaki Sukegawa <nsukeg@gmail.com>
Fri, 2 Jan 2015 14:31:11 +0000 (15:31 +0100)
Change-Id: I31f6571e73b5dd74bf3ade5cadc2daa02475b5cb
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4script.cpp
src/qml/qml/qqmltypeloader.cpp
tests/auto/qml/qqmllanguage/data/importJs.11.errors.txt [new file with mode: 0644]
tests/auto/qml/qqmllanguage/data/importJs.11.qml [new file with mode: 0644]
tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/Empty.js [new file with mode: 0644]
tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/qmldir [new file with mode: 0644]
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp

index 38d2c12..d4eb388 100644 (file)
@@ -199,14 +199,12 @@ Script::Script(ExecutionEngine *v4, Object *qml, CompiledData::CompilationUnit *
 {
     parsed = true;
 
-    if (compilationUnit) {
-        vmFunction = compilationUnit->linkToEngine(v4);
-        Q_ASSERT(vmFunction);
+    vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : 0;
+    if (vmFunction) {
         Scope valueScope(v4);
         ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
         compilationUnitHolder = holder.asReturnedValue();
-    } else
-        vmFunction = 0;
+    }
 }
 
 Script::~Script()
index fb435a5..99247fc 100644 (file)
@@ -2574,6 +2574,11 @@ QQmlScriptData *QQmlScriptBlob::scriptData() const
     return m_scriptData;
 }
 
+struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit
+{
+    virtual void linkBackendToEngine(QV4::ExecutionEngine *) {}
+};
+
 void QQmlScriptBlob::dataReceived(const Data &data)
 {
     QString source = QString::fromUtf8(data.data(), data.size());
@@ -2600,6 +2605,9 @@ void QQmlScriptBlob::dataReceived(const Data &data)
         setError(errors);
         return;
     }
+    if (!unit) {
+        unit.take(new EmptyCompilationUnit);
+    }
     irUnit.javaScriptCompilationUnit = unit;
 
     QmlIR::QmlUnitGenerator qmlGenerator;
diff --git a/tests/auto/qml/qqmllanguage/data/importJs.11.errors.txt b/tests/auto/qml/qqmllanguage/data/importJs.11.errors.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/auto/qml/qqmllanguage/data/importJs.11.qml b/tests/auto/qml/qqmllanguage/data/importJs.11.qml
new file mode 100644 (file)
index 0000000..e76c57b
--- /dev/null
@@ -0,0 +1,10 @@
+import org.qtproject.EmptyJsModule 1.0 as Empty
+import QtQuick 2.0
+
+Item {
+    property bool test: false
+
+    Component.onCompleted: {
+        test = typeof Empty == 'object'
+    }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/Empty.js b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/Empty.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/qmldir b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/EmptyJsModule/qmldir
new file mode 100644 (file)
index 0000000..2a43685
--- /dev/null
@@ -0,0 +1 @@
+EmptyAPI 1.0 Empty.js
index 12d2f53..734c9a4 100644 (file)
@@ -2924,6 +2924,11 @@ void tst_qqmllanguage::importJs_data()
         << "importJs.10.qml"
         << "importJs.10.errors.txt"
         << true;
+
+    QTest::newRow("emptyScript")
+        << "importJs.11.qml"
+        << "importJs.11.errors.txt"
+        << true;
 }
 
 void tst_qqmllanguage::importJs()