@@ -97,18 +97,48 @@ inline JSVariant to_variant(jsi::Runtime &rt, const jsi::Value &value) {
9797 return JSVariant (strVal);
9898 } else if (value.isObject ()) {
9999 auto obj = value.asObject (rt);
100+ size_t byteOffset = 0 ;
101+ size_t byteLength = 0 ;
102+ uint8_t *sourceData = nullptr ;
103+
104+ if (obj.isArrayBuffer (rt)) {
105+ auto buffer = obj.getArrayBuffer (rt);
106+ sourceData = buffer.data (rt);
107+ byteLength = buffer.size (rt);
108+ } else {
109+ jsi::Function arrayBufferCtor =
110+ rt.global ().getPropertyAsFunction (rt, " ArrayBuffer" );
111+ jsi::Function isViewFn =
112+ arrayBufferCtor.getPropertyAsFunction (rt, " isView" );
113+ bool isArrayBufferView = isViewFn.call (rt, obj).getBool ();
114+
115+ if (!isArrayBufferView) {
116+ throw std::runtime_error (
117+ " Object is not an ArrayBuffer or ArrayBuffer view, cannot bind "
118+ " to SQLite" );
119+ }
120+
121+ jsi::Object bufferObject = obj.getPropertyAsObject (rt, " buffer" );
122+ auto buffer = bufferObject.getArrayBuffer (rt);
123+
124+ byteOffset =
125+ static_cast <size_t >(obj.getProperty (rt, " byteOffset" ).asNumber ());
126+ byteLength =
127+ static_cast <size_t >(obj.getProperty (rt, " byteLength" ).asNumber ());
128+
129+ const size_t bufferSize = buffer.size (rt);
130+ if (byteOffset > bufferSize || byteLength > bufferSize - byteOffset) {
131+ throw std::runtime_error (" Invalid ArrayBuffer view range" );
132+ }
100133
101- if (!obj.isArrayBuffer (rt)) {
102- throw std::runtime_error (
103- " Object is not an ArrayBuffer, cannot bind to SQLite" );
134+ sourceData = buffer.data (rt) + byteOffset;
104135 }
105136
106- auto buffer = obj.getArrayBuffer (rt);
107- uint8_t *data = new uint8_t [buffer.size (rt)];
108- memcpy (data, buffer.data (rt), buffer.size (rt));
137+ uint8_t *data = new uint8_t [byteLength];
138+ memcpy (data, sourceData, byteLength);
109139
110140 return JSVariant (ArrayBuffer{.data = std::shared_ptr<uint8_t >{data},
111- .size = buffer. size (rt) });
141+ .size = byteLength });
112142 }
113143
114144 throw std::runtime_error (" Cannot convert JSI value to C++ Variant value" );
0 commit comments