koffi 2.8.6 → 2.8.8

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
@@ -4,6 +4,14 @@
4
4
 
5
5
  ### Koffi 2.8
6
6
 
7
+ #### Koffi 2.8.8 (2024-04-26)
8
+
9
+ - Support use of buffers with mismatched size (truncation or zero-filling)
10
+
11
+ #### Koffi 2.8.7 (2024-04-23)
12
+
13
+ - Improve compatibility with SEHOP on Windows ([@longhun12346](https://github.com/longhun12346))
14
+
7
15
  #### Koffi 2.8.6 (2024-04-12)
8
16
 
9
17
  - Support [loading library](functions.md#loading-options) with RTLD_DEEPBIND where supported
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/doc/contribute.md CHANGED
@@ -60,15 +60,7 @@ Once Koffi is built, you can build the tests and run them with the following com
60
60
  cd src/koffi/test
61
61
  node ../../cnoke/cnoke.js
62
62
 
63
- node sync.js # Run synchronous unit tests
64
- node async.js # Run asynchronous unit tests
65
- node callbacks.js # Run callback unit tests
66
- node union.js # Run union unit tests
67
- node posix.js # Run POSIX-specific unit tests (not for Windows)
68
- node win32.js # Run Windows-specific unit tests (only on Windows)
69
-
70
- node sqlite.js # Run SQLite integration tests
71
- node raylib.js # Run Raylib integration tests
63
+ node test.js
72
64
  ```
73
65
 
74
66
  ### On virtual machines
@@ -153,3 +145,5 @@ Some platforms are emulated so this can take a few minutes until the pre-built b
153
145
  Koffi is programmed in a mix of C++ and assembly code (architecture-specific code). It uses [node-addon-api](https://github.com/nodejs/node-addon-api) (C++ N-API wrapper) to interact with Node.js.
154
146
 
155
147
  My personal preference goes to a rather C-like C++ style, with careful use of templates (mainly for containers) and little object-oriented programming. I strongly prefer tagged unions and code locality over inheritance and virtual methods. Exceptions are disabled.
148
+
149
+ Find more information about code style in the [monorepository README](https://github.com/Koromix/rygel/?tab=readme-ov-file#c-flavor) 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.6",
382
- stable: "2.8.6",
381
+ version: "2.8.8",
382
+ stable: "2.8.8",
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.6",
382
- stable: "2.8.6",
381
+ version: "2.8.8",
382
+ stable: "2.8.8",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.8.6",
4
- "stable": "2.8.6",
3
+ "version": "2.8.8",
4
+ "stable": "2.8.8",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -233,12 +233,14 @@ void CallData::Execute(const FunctionInfo *func, void *native)
233
233
  base = teb->StackBase,
234
234
  limit = teb->StackLimit,
235
235
  dealloc = teb->DeallocationStack,
236
- guaranteed = teb->GuaranteedStackBytes) {
236
+ guaranteed = teb->GuaranteedStackBytes,
237
+ stfs = teb->SameTebFlags) {
237
238
  teb->ExceptionList = exception_list;
238
239
  teb->StackBase = base;
239
240
  teb->StackLimit = limit;
240
241
  teb->DeallocationStack = dealloc;
241
242
  teb->GuaranteedStackBytes = guaranteed;
243
+ teb->SameTebFlags = stfs;
242
244
 
243
245
  instance->last_error = teb->LastErrorValue;
244
246
  };
@@ -249,6 +251,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
249
251
  teb->StackLimit = mem->stack0.ptr;
250
252
  teb->DeallocationStack = mem->stack0.ptr;
251
253
  teb->GuaranteedStackBytes = 0;
254
+ teb->SameTebFlags &= ~0x200;
252
255
 
253
256
  teb->LastErrorValue = instance->last_error;
254
257
 
@@ -330,12 +330,14 @@ void CallData::Execute(const FunctionInfo *func, void *native)
330
330
  base = teb->StackBase,
331
331
  limit = teb->StackLimit,
332
332
  dealloc = teb->DeallocationStack,
333
- guaranteed = teb->GuaranteedStackBytes) {
333
+ guaranteed = teb->GuaranteedStackBytes,
334
+ stfs = teb->SameTebFlags) {
334
335
  teb->ExceptionList = exception_list;
335
336
  teb->StackBase = base;
336
337
  teb->StackLimit = limit;
337
338
  teb->DeallocationStack = dealloc;
338
339
  teb->GuaranteedStackBytes = guaranteed;
340
+ teb->SameTebFlags = stfs;
339
341
 
340
342
  instance->last_error = teb->LastErrorValue;
341
343
  };
@@ -346,6 +348,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
346
348
  teb->StackLimit = mem->stack0.ptr;
347
349
  teb->DeallocationStack = mem->stack0.ptr;
348
350
  teb->GuaranteedStackBytes = 0;
351
+ teb->SameTebFlags &= ~0x200;
349
352
 
350
353
  teb->LastErrorValue = instance->last_error;
351
354
  #endif
@@ -593,9 +593,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
593
593
  return false;
594
594
  } else if (IsRawBuffer(value)) {
595
595
  Span<const uint8_t> buffer = GetRawBuffer(value);
596
-
597
- if (!PushBuffer(buffer, member.type->size, member.type, dest))
598
- return false;
596
+ PushBuffer(buffer, member.type->size, member.type, dest);
599
597
  } else if (value.IsString()) {
600
598
  if (!PushStringArray(value, member.type, dest))
601
599
  return false;
@@ -830,9 +828,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *type
830
828
  return false;
831
829
  } else if (IsRawBuffer(value)) {
832
830
  Span<const uint8_t> buffer = GetRawBuffer(value);
833
-
834
- if (!PushBuffer(buffer, ref->size, ref, dest))
835
- return false;
831
+ PushBuffer(buffer, ref->size, ref, dest);
836
832
  } else if (value.IsString()) {
837
833
  if (!PushStringArray(value, ref, dest))
838
834
  return false;
@@ -896,15 +892,13 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *type
896
892
  return true;
897
893
  }
898
894
 
899
- bool CallData::PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo *type, uint8_t *origin)
895
+ void CallData::PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo *type, uint8_t *origin)
900
896
  {
901
- if (buffer.len != size) [[unlikely]] {
902
- ThrowError<Napi::Error>(env, "Expected array or buffer of size %1, got %2", size, buffer.len);
903
- return false;
904
- }
897
+ buffer.len = std::min(buffer.len, size);
905
898
 
906
- // Go fast yeaaaah :)
899
+ // Go fast brrrrrrr :)
907
900
  memcpy_safe(origin, buffer.ptr, (size_t)buffer.len);
901
+ memset_safe(origin + buffer.len, 0, (size_t)(size - buffer.len));
908
902
 
909
903
  #define SWAP(CType) \
910
904
  do { \
@@ -929,8 +923,6 @@ bool CallData::PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo
929
923
  }
930
924
 
931
925
  #undef SWAP
932
-
933
- return true;
934
926
  }
935
927
 
936
928
  bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *origin)
@@ -119,7 +119,7 @@ public:
119
119
  Size PushString16Value(Napi::Value value, const char16_t **out_str16);
120
120
  bool PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origin);
121
121
  bool PushNormalArray(Napi::Array array, Size len, const TypeInfo *type, uint8_t *origin);
122
- bool PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo *type, uint8_t *origin);
122
+ void PushBuffer(Span<const uint8_t> buffer, Size size, const TypeInfo *type, uint8_t *origin);
123
123
  bool PushStringArray(Napi::Value value, const TypeInfo *type, uint8_t *origin);
124
124
  bool PushPointer(Napi::Value value, const TypeInfo *type, int directions, void **out_ptr);
125
125
  Size PushIndirectString(Napi::Array array, const TypeInfo *ref, uint8_t **out_ptr);
@@ -1446,9 +1446,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1446
1446
  return false;
1447
1447
  } else if (IsRawBuffer(value)) {
1448
1448
  Span<const uint8_t> buffer = GetRawBuffer(value);
1449
-
1450
- if (!call.PushBuffer(buffer, type->size, type, origin))
1451
- return false;
1449
+ call.PushBuffer(buffer, type->size, type, origin);
1452
1450
  } else if (value.IsString()) {
1453
1451
  if (!call.PushStringArray(value, type, origin))
1454
1452
  return false;
@@ -79,9 +79,12 @@ struct TEB {
79
79
  void *DeallocationStack;
80
80
  char _pad3[712];
81
81
  uint32_t GuaranteedStackBytes;
82
+ char _pad4[162];
83
+ uint16_t SameTebFlags;
82
84
  };
83
85
  static_assert(RG_OFFSET_OF(TEB, DeallocationStack) == 0x1478);
84
86
  static_assert(RG_OFFSET_OF(TEB, GuaranteedStackBytes) == 0x1748);
87
+ static_assert(RG_OFFSET_OF(TEB, SameTebFlags) == 0x17EE);
85
88
 
86
89
  #else
87
90
 
@@ -95,9 +98,12 @@ struct TEB {
95
98
  void *DeallocationStack;
96
99
  char _pad3[360];
97
100
  uint32_t GuaranteedStackBytes;
101
+ char _pad4[78];
102
+ uint16_t SameTebFlags;
98
103
  };
99
104
  static_assert(RG_OFFSET_OF(TEB, DeallocationStack) == 0xE0C);
100
105
  static_assert(RG_OFFSET_OF(TEB, GuaranteedStackBytes) == 0x0F78);
106
+ static_assert(RG_OFFSET_OF(TEB, SameTebFlags) == 0xFCA);
101
107
 
102
108
  #endif
103
109