koffi 2.8.3 → 2.8.5
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 +11 -1
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm32hf/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_riscv64hf64/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.exp +0 -0
- package/build/koffi/win32_arm64/koffi.lib +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.exp +0 -0
- package/build/koffi/win32_ia32/koffi.lib +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.exp +0 -0
- package/build/koffi/win32_x64/koffi.lib +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/index.js +2 -2
- package/indirect.js +2 -2
- package/package.json +2 -2
- package/src/core/libcc/libcc.cc +1 -1
- package/src/koffi/src/ffi.cc +53 -39
- package/src/koffi/src/win32.cc +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
### Koffi 2.8
|
|
6
6
|
|
|
7
|
-
#### Koffi 2.8.
|
|
7
|
+
#### Koffi 2.8.5 (2024-04-11)
|
|
8
|
+
|
|
9
|
+
- Prevent obviously invalid type and member names
|
|
10
|
+
- Fix possible infinite loop / UB for `koffi.load()` errors on POSIX systems
|
|
11
|
+
- Fix null return value instead of exception for some errors in `koffi.load()` on Windows
|
|
12
|
+
|
|
13
|
+
#### Koffi 2.8.4 (2024-04-09)
|
|
8
14
|
|
|
9
15
|
- Use simpler workaround for Node 20.12+ and 21.6+ to avoid excessive memory use
|
|
10
16
|
|
|
17
|
+
```{warning}
|
|
18
|
+
Some pre-built binaries are missing in Koffi 2.8.3, skip this version.
|
|
19
|
+
```
|
|
20
|
+
|
|
11
21
|
#### Koffi 2.8.2 (2024-04-07)
|
|
12
22
|
|
|
13
23
|
- Support [loading library](functions.md#loading-options) with RTLD_GLOBAL on POSIX platforms
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.js
CHANGED
|
@@ -378,8 +378,8 @@ var require_package = __commonJS({
|
|
|
378
378
|
"build/dist/src/koffi/package.json"(exports2, module2) {
|
|
379
379
|
module2.exports = {
|
|
380
380
|
name: "koffi",
|
|
381
|
-
version: "2.8.
|
|
382
|
-
stable: "2.8.
|
|
381
|
+
version: "2.8.5",
|
|
382
|
+
stable: "2.8.5",
|
|
383
383
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
384
384
|
keywords: [
|
|
385
385
|
"foreign",
|
package/indirect.js
CHANGED
|
@@ -378,8 +378,8 @@ var require_package = __commonJS({
|
|
|
378
378
|
"build/dist/src/koffi/package.json"(exports2, module2) {
|
|
379
379
|
module2.exports = {
|
|
380
380
|
name: "koffi",
|
|
381
|
-
version: "2.8.
|
|
382
|
-
stable: "2.8.
|
|
381
|
+
version: "2.8.5",
|
|
382
|
+
stable: "2.8.5",
|
|
383
383
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
384
384
|
keywords: [
|
|
385
385
|
"foreign",
|
package/package.json
CHANGED
package/src/core/libcc/libcc.cc
CHANGED
|
@@ -1935,7 +1935,7 @@ bool GetDebugFlag(const char *name)
|
|
|
1935
1935
|
#ifndef NDEBUG
|
|
1936
1936
|
const char *DebugLogContext(const char *filename, int line)
|
|
1937
1937
|
{
|
|
1938
|
-
static
|
|
1938
|
+
static thread_local LocalArray<char, 1024> buf;
|
|
1939
1939
|
|
|
1940
1940
|
buf.len = Fmt(buf.data, " [%1:%2] ", filename, line).len;
|
|
1941
1941
|
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -200,6 +200,38 @@ static inline bool CheckAlignment(int64_t align)
|
|
|
200
200
|
return valid;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
// Prevent simple mistakes but don't be too strict, the world is bigger than the US!
|
|
204
|
+
static bool IsNameValid(const char *name)
|
|
205
|
+
{
|
|
206
|
+
if (!name[0] || IsAsciiWhite(name[0]) || IsAsciiDigit(name[0])) [[unlikely]]
|
|
207
|
+
return false;
|
|
208
|
+
|
|
209
|
+
for (Size i = 1; name[i]; i++) {
|
|
210
|
+
if (IsAsciiWhite(name[i])) [[unlikely]]
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static bool MapType(Napi::Env env, InstanceData *instance, const TypeInfo *type, const char *name)
|
|
218
|
+
{
|
|
219
|
+
if (!IsNameValid(name)) {
|
|
220
|
+
ThrowError<Napi::Error>(env, "Invalid type name '%1'", name);
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
bool inserted;
|
|
225
|
+
instance->types_map.TrySet(name, type, &inserted);
|
|
226
|
+
|
|
227
|
+
if (!inserted) {
|
|
228
|
+
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", name);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
203
235
|
static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
204
236
|
{
|
|
205
237
|
Napi::Env env = info.Env();
|
|
@@ -245,13 +277,8 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
245
277
|
if (named) {
|
|
246
278
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
247
279
|
|
|
248
|
-
|
|
249
|
-
instance->types_map.TrySet(type->name, type, &inserted);
|
|
250
|
-
|
|
251
|
-
if (!inserted) {
|
|
252
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
280
|
+
if (!MapType(env, instance, type, type->name))
|
|
253
281
|
return env.Null();
|
|
254
|
-
}
|
|
255
282
|
} else {
|
|
256
283
|
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.len).ptr;
|
|
257
284
|
}
|
|
@@ -312,6 +339,11 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
312
339
|
return env.Null();
|
|
313
340
|
}
|
|
314
341
|
|
|
342
|
+
if (!IsNameValid(member.name)) {
|
|
343
|
+
ThrowError<Napi::Error>(env, "Invalid member name '%1'", member.name);
|
|
344
|
+
return env.Null();
|
|
345
|
+
}
|
|
346
|
+
|
|
315
347
|
bool inserted;
|
|
316
348
|
members.TrySet(member.name, &inserted);
|
|
317
349
|
|
|
@@ -391,13 +423,8 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
391
423
|
if (named) {
|
|
392
424
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
393
425
|
|
|
394
|
-
|
|
395
|
-
instance->types_map.TrySet(type->name, type, &inserted);
|
|
396
|
-
|
|
397
|
-
if (!inserted) {
|
|
398
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
426
|
+
if (!MapType(env, instance, type, type->name))
|
|
399
427
|
return env.Null();
|
|
400
|
-
}
|
|
401
428
|
} else {
|
|
402
429
|
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.len).ptr;
|
|
403
430
|
}
|
|
@@ -449,6 +476,11 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
449
476
|
size = std::max(size, member.type->size);
|
|
450
477
|
type->align = std::max(type->align, align);
|
|
451
478
|
|
|
479
|
+
if (!IsNameValid(member.name)) {
|
|
480
|
+
ThrowError<Napi::Error>(env, "Invalid member name '%1'", member.name);
|
|
481
|
+
return env.Null();
|
|
482
|
+
}
|
|
483
|
+
|
|
452
484
|
bool inserted;
|
|
453
485
|
members.TrySet(member.name, &inserted);
|
|
454
486
|
|
|
@@ -530,15 +562,8 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
|
530
562
|
type->align = 0;
|
|
531
563
|
|
|
532
564
|
// If the insert succeeds, we cannot fail anymore
|
|
533
|
-
if (named)
|
|
534
|
-
|
|
535
|
-
instance->types_map.TrySet(type->name, type, &inserted);
|
|
536
|
-
|
|
537
|
-
if (!inserted) {
|
|
538
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
539
|
-
return env.Null();
|
|
540
|
-
}
|
|
541
|
-
}
|
|
565
|
+
if (named && !MapType(env, instance, type, type->name))
|
|
566
|
+
return env.Null();
|
|
542
567
|
err_guard.Disable();
|
|
543
568
|
|
|
544
569
|
return WrapType(env, instance, type);
|
|
@@ -594,14 +619,9 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
594
619
|
memcpy((void *)copy, type, RG_SIZE(*type));
|
|
595
620
|
copy->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
|
|
596
621
|
|
|
597
|
-
bool inserted;
|
|
598
|
-
instance->types_map.TrySet(copy->name, copy, &inserted);
|
|
599
|
-
|
|
600
622
|
// If the insert succeeds, we cannot fail anymore
|
|
601
|
-
if (!
|
|
602
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", copy->name);
|
|
623
|
+
if (!MapType(env, instance, copy, copy->name))
|
|
603
624
|
return env.Null();
|
|
604
|
-
}
|
|
605
625
|
err_guard.Disable();
|
|
606
626
|
|
|
607
627
|
type = copy;
|
|
@@ -1090,15 +1110,8 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
|
|
|
1090
1110
|
return env.Null();
|
|
1091
1111
|
|
|
1092
1112
|
// Alias the type
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
instance->types_map.TrySet(alias, type, &inserted);
|
|
1096
|
-
|
|
1097
|
-
if (!inserted) {
|
|
1098
|
-
ThrowError<Napi::Error>(env, "Type name '%1' already exists", alias);
|
|
1099
|
-
return env.Null();
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1113
|
+
if (!MapType(env, instance, type, alias))
|
|
1114
|
+
return env.Null();
|
|
1102
1115
|
|
|
1103
1116
|
return WrapType(env, instance, type);
|
|
1104
1117
|
}
|
|
@@ -1757,9 +1770,10 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1757
1770
|
|
|
1758
1771
|
if (StartsWith(msg, filename.c_str())) {
|
|
1759
1772
|
msg += filename.length();
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1773
|
+
|
|
1774
|
+
while (strchr(": ", msg[0]) && msg[0]) {
|
|
1775
|
+
msg++;
|
|
1776
|
+
}
|
|
1763
1777
|
}
|
|
1764
1778
|
|
|
1765
1779
|
ThrowError<Napi::Error>(env, "Failed to load shared library: %1", msg);
|
package/src/koffi/src/win32.cc
CHANGED
|
@@ -74,8 +74,10 @@ HANDLE LoadWindowsLibrary(Napi::Env env, Span<const char> path)
|
|
|
74
74
|
|
|
75
75
|
Span<wchar_t> filename_w = AllocateSpan<wchar_t>(&temp_alloc, path.len + 1);
|
|
76
76
|
|
|
77
|
-
if (ConvertUtf8ToWin32Wide(path, filename_w) < 0)
|
|
77
|
+
if (ConvertUtf8ToWin32Wide(path, filename_w) < 0) {
|
|
78
|
+
ThrowError<Napi::Error>(env, "Invalid path string");
|
|
78
79
|
return nullptr;
|
|
80
|
+
}
|
|
79
81
|
|
|
80
82
|
HMODULE module = LoadLibraryW(filename_w.ptr);
|
|
81
83
|
|
|
@@ -85,8 +87,10 @@ HANDLE LoadWindowsLibrary(Napi::Env env, Span<const char> path)
|
|
|
85
87
|
Span<const char> filename = NormalizePath(path, GetWorkingDirectory(), &temp_alloc);
|
|
86
88
|
Span<wchar_t> filename_w = AllocateSpan<wchar_t>(&temp_alloc, filename.len + 1);
|
|
87
89
|
|
|
88
|
-
if (ConvertUtf8ToWin32Wide(filename, filename_w) < 0)
|
|
90
|
+
if (ConvertUtf8ToWin32Wide(filename, filename_w) < 0) {
|
|
91
|
+
ThrowError<Napi::Error>(env, "Invalid path string");
|
|
89
92
|
return nullptr;
|
|
93
|
+
}
|
|
90
94
|
|
|
91
95
|
module = LoadLibraryExW(filename_w.ptr, nullptr, flags);
|
|
92
96
|
}
|