diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-08-17 14:54:56 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2013-08-18 12:30:11 +0200 |
commit | ca2b4d1ccabc3bccde4d146284b1cac39058e711 (patch) | |
tree | a1212508a9ba63935801254a278ade73ff0ac819 /src/qml/compiler/qv4compileddata_p.h | |
parent | 45dacdaa788eeac64148465658b6af2d2fa552cf (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.h | 43 |
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; |