koffi 2.16.1 → 2.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@
7
7
 
8
8
  ### Koffi 2.16
9
9
 
10
+ #### Koffi 2.16.2
11
+
12
+ *Released on 2026-05-06*
13
+
14
+ - Fix string truncation bugs when passing some kinds of long V8 strings (see [Koromix/koffi#266](https://github.com/Koromix/koffi/issues/266))
15
+
10
16
  #### Koffi 2.16.1
11
17
 
12
18
  *Released on 2026-04-17*
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -398,7 +398,7 @@ var require_package = __commonJS({
398
398
  "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
399
399
  module2.exports = {
400
400
  name: "koffi",
401
- version: "2.16.1",
401
+ version: "2.16.2",
402
402
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
403
403
  keywords: [
404
404
  "foreign",
package/indirect.js CHANGED
@@ -398,7 +398,7 @@ var require_package = __commonJS({
398
398
  "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
399
399
  module2.exports = {
400
400
  name: "koffi",
401
- version: "2.16.1",
401
+ version: "2.16.2",
402
402
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
403
403
  keywords: [
404
404
  "foreign",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.16.1",
3
+ "version": "2.16.2",
4
4
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -151,14 +151,22 @@ Size CallData::PushStringValue(Napi::Value value, const char **out_str)
151
151
  napi_status status;
152
152
 
153
153
  buf.ptr = (char *)mem->heap.ptr;
154
- buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
154
+ buf.len = mem->heap.len;
155
155
 
156
156
  status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
157
157
  K_ASSERT(status == napi_ok);
158
158
 
159
159
  len++;
160
160
 
161
- if (len < (size_t)buf.len) [[likely]] {
161
+ // V8 can truncate the string and return a length that is less than the real string
162
+ // length in several cases, such as when it flattens string ropes.
163
+ // This was the cause of a truncation bug (see https://github.com/Koromix/koffi/issues/266),
164
+ // which went unnoticed for a long time.
165
+ // We don't want to query the length beforehand, because it's slow. Instead, check that the
166
+ // returned lengfth is much shorter than the available buffer capacity, and if so, we know
167
+ // we're okay because V8 flattens strings ~32 KiB at a time.
168
+
169
+ if ((Size)len < buf.len - Kibibytes(64)) [[likely]] {
162
170
  mem->heap.ptr += (Size)len;
163
171
  mem->heap.len -= (Size)len;
164
172
  } else {
@@ -186,14 +194,14 @@ Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
186
194
 
187
195
  mem->heap.ptr = AlignUp(mem->heap.ptr, 2);
188
196
  buf.ptr = (char16_t *)mem->heap.ptr;
189
- buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
197
+ buf.len = mem->heap.len / 2;
190
198
 
191
199
  status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
192
200
  K_ASSERT(status == napi_ok);
193
201
 
194
202
  len++;
195
203
 
196
- if (len < (size_t)buf.len) [[likely]] {
204
+ if ((Size)len < buf.len - Kibibytes(64) / 2) [[likely]] {
197
205
  mem->heap.ptr += (Size)len * 2;
198
206
  mem->heap.len -= (Size)len * 2;
199
207
  } else {
@@ -226,7 +234,7 @@ Size CallData::PushString32Value(Napi::Value value, const char32_t **out_str32)
226
234
 
227
235
  mem->heap.ptr = AlignUp(mem->heap.ptr, 4);
228
236
  buf.ptr = (char32_t *)mem->heap.ptr;
229
- buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 4;
237
+ buf.len = mem->heap.len / 4;
230
238
 
231
239
  if (buf16.len < buf.len) [[likely]] {
232
240
  mem->heap.ptr += buf16.len * 4;