aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib
diff options
context:
space:
mode:
authorIvan Komissarov <abbapoh@gmail.com>2023-05-16 01:32:37 +0300
committerIvan Komissarov <ABBAPOH@gmail.com>2023-05-16 10:37:54 +0000
commitce626e5e919cabb32a7fa1be35025837196b8204 (patch)
treeb96320c45b1b2d460a37694977a4777169c30735 /src/lib/corelib
parent4e8e1b2719b84a7371acafc311fc74b10ff36362 (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/corelib')
-rw-r--r--src/lib/corelib/language/scriptengine.cpp6
-rw-r--r--src/lib/corelib/language/scriptengine.h1
-rw-r--r--src/lib/corelib/tools/scripttools.cpp17
-rw-r--r--src/lib/corelib/tools/scripttools.h1
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);