diff options
author | Ivan Komissarov <abbapoh@gmail.com> | 2023-05-16 01:32:37 +0300 |
---|---|---|
committer | Ivan Komissarov <ABBAPOH@gmail.com> | 2023-05-16 10:37:54 +0000 |
commit | ce626e5e919cabb32a7fa1be35025837196b8204 (patch) | |
tree | b96320c45b1b2d460a37694977a4777169c30735 /src/lib | |
parent | 4e8e1b2719b84a7371acafc311fc74b10ff36362 (diff) |
js: represent QByteArray as JsArrayBuffer
On macOS, Info.plist can (rarely) contain binary data which is parsed
into a QByteArray. However, since byte arrays were discarded when
converting from variant, such keys were lost e.g. when doing plist
merging.
Fix that by converting QByteArray to a JS ArrayBuffer object.
Using such types is a bit awkward as seen in the testcase, but conforms
JS type system.
Change-Id: I7a680aa7943ba3bde1ddf4ac84e3485fb0ba01d8
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/corelib/language/scriptengine.cpp | 6 | ||||
-rw-r--r-- | src/lib/corelib/language/scriptengine.h | 1 | ||||
-rw-r--r-- | src/lib/corelib/tools/scripttools.cpp | 17 | ||||
-rw-r--r-- | src/lib/corelib/tools/scripttools.h | 1 |
4 files changed, 22 insertions, 3 deletions
diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index 58c2817c6..6a67c1228 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -481,6 +481,12 @@ void ScriptEngine::addInternalExtension(const char *name, JSValue ext) m_internalExtensions.insert(QLatin1String(name), JS_DupValue(m_context, ext)); } +JSValue ScriptEngine::asJsValue(const QByteArray &s) +{ + return JS_NewArrayBufferCopy( + m_context, reinterpret_cast<const uint8_t *>(s.constData()), s.size()); +} + JSValue ScriptEngine::asJsValue(const QString &s) { const auto it = m_stringCache.constFind(s); diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h index 8c97e3079..4d797dd43 100644 --- a/src/lib/corelib/language/scriptengine.h +++ b/src/lib/corelib/language/scriptengine.h @@ -283,6 +283,7 @@ public: JSValue getInternalExtension(const char *name) const; void addInternalExtension(const char *name, JSValue ext); + JSValue asJsValue(const QByteArray &s); JSValue asJsValue(const QString &s); JSValue asJsValue(const QStringList &l); JSValue asJsValue(const QVariantList &l); diff --git a/src/lib/corelib/tools/scripttools.cpp b/src/lib/corelib/tools/scripttools.cpp index 109b74486..4953bbbb5 100644 --- a/src/lib/corelib/tools/scripttools.cpp +++ b/src/lib/corelib/tools/scripttools.cpp @@ -179,6 +179,11 @@ bool getJsBoolProperty(JSContext *ctx, JSValue obj, const QString &prop) return JS_VALUE_GET_BOOL(getJsProperty(ctx, obj, prop)); } +JSValue makeJsArrayBuffer(JSContext *ctx, const QByteArray &s) +{ + return ScriptEngine::engineForContext(ctx)->asJsValue(s); +} + JSValue makeJsString(JSContext *ctx, const QString &s) { return ScriptEngine::engineForContext(ctx)->asJsValue(s); @@ -212,6 +217,8 @@ QStringList getJsStringList(JSContext *ctx, JSValue val) JSValue makeJsVariant(JSContext *ctx, const QVariant &v) { switch (static_cast<QMetaType::Type>(v.userType())) { + case QMetaType::QByteArray: + return makeJsArrayBuffer(ctx, v.toByteArray()); case QMetaType::QString: return makeJsString(ctx, v.toString()); case QMetaType::QStringList: @@ -230,9 +237,6 @@ JSValue makeJsVariant(JSContext *ctx, const QVariant &v) return JS_NewBool(ctx, v.toBool()); case QMetaType::QVariantMap: return makeJsVariantMap(ctx, v.toMap()); - case QMetaType::QByteArray: - QBS_ASSERT(!"QByteArray is not a valid type for JS variant", return JS_UNDEFINED); - [[fallthrough]]; default: return JS_UNDEFINED; } @@ -254,6 +258,13 @@ static QVariant getJsVariantImpl(JSContext *ctx, JSValue val, QList<JSValue> pat return getJsString(ctx, val); if (JS_IsBool(val)) return bool(JS_VALUE_GET_BOOL(val)); + if (JS_IsArrayBuffer(val)) { + size_t size = 0; + const auto data = JS_GetArrayBuffer(ctx, &size, val); + if (!data || !size) + return QByteArray(); + return QByteArray(reinterpret_cast<const char *>(data), size); + } if (JS_IsArray(ctx, val)) { if (path.contains(val)) return {}; diff --git a/src/lib/corelib/tools/scripttools.h b/src/lib/corelib/tools/scripttools.h index 1af7b2b9e..ea7993485 100644 --- a/src/lib/corelib/tools/scripttools.h +++ b/src/lib/corelib/tools/scripttools.h @@ -72,6 +72,7 @@ QVariant getJsVariantProperty(JSContext *ctx, JSValueConst obj, const QString &p QString getJsString(JSContext *ctx, JSValueConst val); QString getJsString(JSContext *ctx, JSAtom atom); QBS_AUTOTEST_EXPORT QVariant getJsVariant(JSContext *ctx, JSValueConst val); +JSValue makeJsArrayBuffer(JSContext *ctx, const QByteArray &s); JSValue makeJsString(JSContext *ctx, const QString &s); JSValue makeJsStringList(JSContext *ctx, const QStringList &l); JSValue makeJsVariant(JSContext *ctx, const QVariant &v); |