aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compileddata_p.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-08-17 14:54:56 +0200
committerLars Knoll <lars.knoll@digia.com>2013-08-18 12:30:11 +0200
commitca2b4d1ccabc3bccde4d146284b1cac39058e711 (patch)
treea1212508a9ba63935801254a278ade73ff0ac819 /src/qml/compiler/qv4compileddata_p.h
parent45dacdaa788eeac64148465658b6af2d2fa552cf (diff)
Fix invalid reads with strings
It may happen that a dynamically created compilation unit disappears before any QV4::Strings it created. Those strings would still have a reference to the QString data in the compilation unit. I don't see a choice other than making a copy of the string data ;(. But this patch adds a flag that would allow for avoiding it if we happen to know that the compilation unit data is static. Change-Id: Ib35a4d2a566b301a25ffe56e392809e44e7b4ae8 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4compileddata_p.h')
-rw-r--r--src/qml/compiler/qv4compileddata_p.h43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 379766f6de..fa139d36e6 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -108,6 +108,18 @@ struct JSClass
static int calculateSize(int nMembers) { return (sizeof(JSClass) + nMembers * sizeof(JSClassMember) + 7) & ~7; }
};
+struct String
+{
+ quint32 hash;
+ quint32 flags; // isArrayIndex
+ QArrayData str;
+ // uint16 strdata[]
+
+ static int calculateSize(const QString &str) {
+ return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
+ }
+};
+
static const char magic_str[] = "qv4cdata";
struct Unit
@@ -118,7 +130,8 @@ struct Unit
enum {
IsJavascript = 0x1,
- IsQml = 0x2
+ IsQml = 0x2,
+ StaticData = 0x4 // Unit data persistent in memory?
};
quint32 flags;
uint stringTableSize;
@@ -134,10 +147,15 @@ struct Unit
uint indexOfRootFunction;
quint32 sourceFileIndex;
- const String *stringAt(int idx) const {
+ QString stringAt(int idx) const {
const uint *offsetTable = reinterpret_cast<const uint*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
const uint offset = offsetTable[idx];
- return reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
+ const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
+ QStringDataPtr holder = { const_cast<QStringData *>(static_cast<const QStringData*>(&str->str)) };
+ QString qstr(holder);
+ if (flags & StaticData)
+ return qstr;
+ return QString(qstr.constData(), qstr.length());
}
const Function *functionAt(int idx) const {
@@ -203,23 +221,6 @@ struct Function
}
};
-struct String
-{
- quint32 hash;
- quint32 flags; // isArrayIndex
- QArrayData str;
- // uint16 strdata[]
-
- QString qString() const {
- QStringDataPtr holder { const_cast<QStringData *>(static_cast<const QStringData*>(&str)) };
- return QString(holder);
- }
-
- static int calculateSize(const QString &str) {
- return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
- }
-};
-
// Qml data structures
struct Value
@@ -322,7 +323,7 @@ struct CompilationUnit
ExecutionEngine *engine;
Unit *data;
- QString fileName() const { return data->stringAt(data->sourceFileIndex)->qString(); }
+ QString fileName() const { return data->stringAt(data->sourceFileIndex); }
QV4::String **runtimeStrings; // Array
QV4::Lookup *runtimeLookups;