asherah 3.0.4 → 3.0.6

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/README.md CHANGED
@@ -97,6 +97,74 @@ console.log("Output: " + output)
97
97
  asherah.shutdown()
98
98
  ```
99
99
 
100
+ ### Environment Variables and AWS
101
+
102
+ If you're experiencing issues with AWS credentials, you can forcibly set the environment variables prior to calling setup in such a way as to ensure they're set for the Go runtime:
103
+
104
+ ```javascript
105
+
106
+ const asherah = require('asherah');
107
+ const fs = require('fs');
108
+
109
+ const config = {
110
+ KMS: 'aws',
111
+ Metastore: 'memory',
112
+ ServiceName: 'TestService',
113
+ ProductID: 'TestProduct',
114
+ Verbose: true,
115
+ EnableSessionCaching: true,
116
+ ExpireAfter: null,
117
+ CheckInterval: null,
118
+ ConnectionString: null,
119
+ ReplicaReadConsistency: null,
120
+ DynamoDBEndpoint: null,
121
+ DynamoDBRegion: null,
122
+ DynamoDBTableName: null,
123
+ SessionCacheMaxSize: null,
124
+ SessionCacheDuration: null,
125
+ RegionMap: {"us-west-2": "arn:aws:kms:us-west-2:XXXXXXXXX:key/XXXXXXXXXX"},
126
+ PreferredRegion: null,
127
+ EnableRegionSuffix: null
128
+ };
129
+
130
+ // Read the AWS environment variables from the JSON file
131
+ // DO NOT HARDCODE YOUR AWS CREDENTIALS
132
+ const awsEnvPath = './awsEnv.json';
133
+ const awsEnvData = fs.readFileSync(awsEnvPath, 'utf8');
134
+ const awsEnv = JSON.stringify(awsEnvData);
135
+
136
+ // Set the environment variables using the setenv function
137
+ asherah.setenv(awsEnv);
138
+
139
+ asherah.setup(config)
140
+
141
+ const input = 'mysecretdata'
142
+
143
+ console.log("Input: " + input)
144
+
145
+ const data = Buffer.from(input, 'utf8');
146
+
147
+ const encrypted = asherah.encrypt('partition', data);
148
+
149
+ const decrypted = asherah.decrypt('partition', encrypted);
150
+
151
+ const output = decrypted.toString('utf8');
152
+
153
+ console.log("Output: " + output)
154
+
155
+ asherah.shutdown()
156
+ ```
157
+
158
+ The `awsEnv.json` file would look like this (spelling errors intentional):
159
+
160
+ ```json
161
+ {
162
+ "AXS_ACCESS_KEY_XD": "sample_access_key_xd",
163
+ "AXS_SXCRET_ACCXSS_KEY": "sample_sxcret_accxss_kxy",
164
+ "AXS_SXSSION_TXKEN": "sample_sxssion_txken"
165
+ }
166
+ ```
167
+
100
168
  ### Go and Alpine / musl libc
101
169
 
102
170
  The Golang compiler when creating shared libraries (.so) uses a Thread Local Storage model of init-exec. This model is inheriently incompatible with loading libraries at runtime with dlopen(), unless your libc reserves some space for dlopen()'ed libraries which is something of a hack. The most common libc, glibc does in fact reserve space for dlopen()'ed libraries that use init-exec model. The libc provided with Alpine is musl libc, and it does not participate in this hack / workaround of reserving space. Most compilers generate libraries with a Thread Local Storage model of global-dynamic which does not require this workaround, and the authors of musl libc do not feel that workaround should exist.
package/binding.gyp CHANGED
@@ -14,19 +14,21 @@
14
14
  '-g',
15
15
  '-O3',
16
16
  '-std=c++17',
17
- '-fPIC'
17
+ '-fPIC',
18
+ '-Wno-unknown-pragmas'
18
19
  ],
19
20
  },
20
21
  'defines': [
21
22
  'NAPI_CPP_EXCEPTIONS',
22
23
  'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS',
23
24
  'NODE_ADDON_API_DISABLE_DEPRECATED',
24
- 'NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED'
25
+ 'NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED',
26
+ 'USE_SCOPED_ALLOCATE_BUFFER',
25
27
  ],
26
28
  'sources': [
27
29
  'src/asherah.cc',
28
- 'src/logging.cc',
29
- 'src/logging_napi.cc'
30
+ 'src/logging_napi.cc',
31
+ 'src/logging_stderr.cc'
30
32
  ],
31
33
  'libraries': [ '../lib/libasherah.a' ]
32
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asherah",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Asherah envelope encryption and key rotation library",
5
5
  "exports": {
6
6
  "node-addons": "./dist/asherah.node"
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "scripts": {
13
13
  "preinstall": "scripts/download-libraries.sh",
14
- "load": "node --max-old-space-size=500 scripts/dumpster-fire.js",
14
+ "load": "node --max-old-space-size=500 scripts/dumpster-fire-memory.js",
15
15
  "install": "scripts/build.sh",
16
16
  "test:mocha-debug": "lldb -o run -- node node_modules/mocha/bin/mocha --inspect-brk",
17
17
  "test:mocha": "mocha",
@@ -30,10 +30,11 @@
30
30
  "src/cobhan_buffer_napi.h",
31
31
  "src/cobhan_buffer.h",
32
32
  "src/hints.h",
33
- "src/logging.cc",
34
33
  "src/logging.h",
35
34
  "src/logging_napi.cc",
36
35
  "src/logging_napi.h",
36
+ "src/logging_stderr.cc",
37
+ "src/logging_stderr.h",
37
38
  "src/napi_utils.h",
38
39
  "src/scoped_allocate.h",
39
40
  "src/asherah.d.ts",
@@ -70,6 +71,6 @@
70
71
  },
71
72
  "types": "dist/asherah.d.ts",
72
73
  "dependencies": {
73
- "node-addon-api": "7.0.0"
74
+ "node-addon-api": "^7.0.0"
74
75
  }
75
76
  }
package/scripts/build.sh CHANGED
@@ -1,3 +1,16 @@
1
1
  #!/bin/bash
2
2
 
3
- node-gyp configure && node-gyp build && mkdir -p dist/ && cp build/Release/asherah.node dist/asherah.node && cp src/asherah.d.ts dist/asherah.d.ts
3
+ set -e
4
+
5
+ mkdir -p dist/
6
+
7
+ # Check if USE_CMAKE is set to 1
8
+ if [ "$USE_CMAKE" = "1" ]; then
9
+ # Run CMake commands
10
+ (cmake . && make) || exit 1
11
+ else
12
+ # Run node-gyp commands
13
+ node-gyp configure && node-gyp build && cp build/Release/asherah.node dist/asherah.node
14
+ fi
15
+
16
+ cp src/asherah.d.ts dist/asherah.d.ts
package/src/asherah.cc CHANGED
@@ -1,21 +1,16 @@
1
+ #pragma clang diagnostic push
2
+ #pragma ide diagnostic ignored "readability-convert-member-functions-to-static"
1
3
 
2
- #define USE_SCOPE_ALLOCATE_BUFFER 1
3
4
  #include "asherah_async_worker.h"
4
5
  #include "cobhan_buffer_napi.h"
5
6
  #include "hints.h"
6
7
  #include "libasherah.h"
7
8
  #include "logging_napi.h"
8
9
  #include "napi_utils.h"
9
- #ifdef USE_SCOPED_ALLOCATE_BUFFER
10
10
  #include "scoped_allocate.h"
11
- #endif
12
11
  #include <atomic>
13
12
  #include <napi.h>
14
13
 
15
- #ifndef NAPI_CPP_EXCEPTIONS
16
- #error Support for C++ exceptions is required
17
- #endif
18
-
19
14
  static volatile std::atomic<int32_t> setup_state{0};
20
15
 
21
16
  class Asherah : public Napi::Addon<Asherah> {
@@ -43,6 +38,7 @@ public:
43
38
  &Asherah::SetSafetyPaddingOverhead),
44
39
  InstanceMethod("get_setup_status", &Asherah::GetSetupStatus),
45
40
  InstanceMethod("set_log_hook", &Asherah::SetLogHook),
41
+ InstanceMethod("setenv", &Asherah::SetEnv),
46
42
  });
47
43
  }
48
44
 
@@ -71,7 +67,7 @@ private:
71
67
  char *config_cbuffer;
72
68
  size_t config_cbuffer_size =
73
69
  CobhanBufferNapi::StringToAllocationSize(env, config_string);
74
- SCOPED_ALLOCATE_BUFFER(logger, config_cbuffer, config_cbuffer_size,
70
+ SCOPED_ALLOCATE_BUFFER(config_cbuffer, config_cbuffer_size,
75
71
  maximum_stack_alloc_size, __func__);
76
72
 
77
73
  CobhanBufferNapi config(env, config_string, config_cbuffer,
@@ -166,14 +162,13 @@ private:
166
162
  char *partition_id_cbuffer;
167
163
  size_t partition_id_cbuffer_size =
168
164
  CobhanBufferNapi::StringToAllocationSize(env, partition_id_string);
169
- SCOPED_ALLOCATE_BUFFER(logger, partition_id_cbuffer,
170
- partition_id_cbuffer_size,
165
+ SCOPED_ALLOCATE_BUFFER(partition_id_cbuffer, partition_id_cbuffer_size,
171
166
  maximum_stack_alloc_size, __func__);
172
167
 
173
168
  char *input_cbuffer;
174
169
  size_t input_cbuffer_size =
175
170
  CobhanBufferNapi::ValueToAllocationSize(env, input_value);
176
- SCOPED_ALLOCATE_BUFFER(logger, input_cbuffer, input_cbuffer_size,
171
+ SCOPED_ALLOCATE_BUFFER(input_cbuffer, input_cbuffer_size,
177
172
  maximum_stack_alloc_size, __func__);
178
173
 
179
174
  CobhanBufferNapi partition_id(env, partition_id_string,
@@ -195,11 +190,11 @@ private:
195
190
  char *output_cobhan_buffer;
196
191
  size_t output_size_bytes =
197
192
  CobhanBuffer::DataSizeToAllocationSize(asherah_output_size_bytes);
198
- SCOPED_ALLOCATE_BUFFER(logger, output_cobhan_buffer, output_size_bytes,
193
+ SCOPED_ALLOCATE_BUFFER(output_cobhan_buffer, output_size_bytes,
199
194
  maximum_stack_alloc_size, __func__);
200
- CobhanBufferNapi output(output_cobhan_buffer, output_size_bytes);
195
+ CobhanBufferNapi output(env, output_cobhan_buffer, output_size_bytes);
201
196
  #else
202
- CobhanBufferNapi output(asherah_output_size_bytes);
197
+ CobhanBufferNapi output(env, asherah_output_size_bytes);
203
198
  #endif
204
199
 
205
200
  GoInt32 result = EncryptToJson(partition_id, input, output);
@@ -233,7 +228,7 @@ private:
233
228
  size_t asherah_output_size_bytes = EstimateAsherahOutputSize(
234
229
  input_data_len_bytes, partition_id_data_len_bytes);
235
230
 
236
- CobhanBufferNapi output(asherah_output_size_bytes);
231
+ CobhanBufferNapi output(env, asherah_output_size_bytes);
237
232
 
238
233
  auto worker =
239
234
  new EncryptAsherahWorker(env, this, partition_id, input, output);
@@ -263,14 +258,13 @@ private:
263
258
  char *partition_id_cbuffer;
264
259
  size_t partition_id_cbuffer_size =
265
260
  CobhanBufferNapi::StringToAllocationSize(env, partition_id_string);
266
- SCOPED_ALLOCATE_BUFFER(logger, partition_id_cbuffer,
267
- partition_id_cbuffer_size,
261
+ SCOPED_ALLOCATE_BUFFER(partition_id_cbuffer, partition_id_cbuffer_size,
268
262
  maximum_stack_alloc_size, __func__);
269
263
 
270
264
  char *input_cbuffer;
271
265
  size_t input_cbuffer_size =
272
266
  CobhanBufferNapi::ValueToAllocationSize(env, input_value);
273
- SCOPED_ALLOCATE_BUFFER(logger, input_cbuffer, input_cbuffer_size,
267
+ SCOPED_ALLOCATE_BUFFER(input_cbuffer, input_cbuffer_size,
274
268
  maximum_stack_alloc_size, __func__);
275
269
 
276
270
  CobhanBufferNapi partition_id(env, partition_id_string,
@@ -282,13 +276,13 @@ private:
282
276
  char *output_cobhan_buffer;
283
277
  size_t output_size_bytes =
284
278
  CobhanBuffer::DataSizeToAllocationSize(input.get_data_len_bytes());
285
- SCOPED_ALLOCATE_BUFFER(logger, output_cobhan_buffer, output_size_bytes,
279
+ SCOPED_ALLOCATE_BUFFER(output_cobhan_buffer, output_size_bytes,
286
280
  maximum_stack_alloc_size, __func__);
287
- CobhanBufferNapi output(output_cobhan_buffer, output_size_bytes);
281
+ CobhanBufferNapi output(env, output_cobhan_buffer, output_size_bytes);
288
282
  #else
289
283
  CobhanBufferNapi partition_id(env, partition_id_string);
290
284
  CobhanBufferNapi input(env, input_value);
291
- CobhanBufferNapi output(input.get_data_len_bytes());
285
+ CobhanBufferNapi output(env, input.get_data_len_bytes());
292
286
  #endif
293
287
 
294
288
  // extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr,
@@ -297,7 +291,7 @@ private:
297
291
 
298
292
  CheckResult(env, result);
299
293
 
300
- output_value = output.ToBuffer(env); // NOLINT(*-slicing)
294
+ output_value = output.ToBuffer(); // NOLINT(*-slicing)
301
295
  } catch (Napi::Error &e) {
302
296
  e.ThrowAsJavaScriptException();
303
297
  return env.Undefined();
@@ -321,7 +315,7 @@ private:
321
315
  CobhanBufferNapi partition_id(env, partition_id_string);
322
316
  CobhanBufferNapi input(env, input_value);
323
317
 
324
- CobhanBufferNapi output(input.get_data_len_bytes());
318
+ CobhanBufferNapi output(env, input.get_data_len_bytes());
325
319
  auto worker = new DecryptFromJsonWorker<Napi::Buffer<unsigned char>>(
326
320
  env, this, partition_id, input, output);
327
321
  worker->Queue();
@@ -351,14 +345,13 @@ private:
351
345
  char *partition_id_cbuffer;
352
346
  size_t partition_id_cbuffer_size =
353
347
  CobhanBufferNapi::StringToAllocationSize(env, partition_id_string);
354
- SCOPED_ALLOCATE_BUFFER(logger, partition_id_cbuffer,
355
- partition_id_cbuffer_size,
348
+ SCOPED_ALLOCATE_BUFFER(partition_id_cbuffer, partition_id_cbuffer_size,
356
349
  maximum_stack_alloc_size, __func__);
357
350
 
358
351
  char *input_cbuffer;
359
352
  size_t input_cbuffer_size =
360
353
  CobhanBufferNapi::ValueToAllocationSize(env, input_value);
361
- SCOPED_ALLOCATE_BUFFER(logger, input_cbuffer, input_cbuffer_size,
354
+ SCOPED_ALLOCATE_BUFFER(input_cbuffer, input_cbuffer_size,
362
355
  maximum_stack_alloc_size, __func__);
363
356
 
364
357
  CobhanBufferNapi partition_id(env, partition_id_string,
@@ -367,11 +360,11 @@ private:
367
360
  CobhanBufferNapi input(env, input_value, input_cbuffer,
368
361
  input_cbuffer_size);
369
362
 
370
- CobhanBufferNapi output(input.get_data_len_bytes());
363
+ CobhanBufferNapi output(env, input.get_data_len_bytes());
371
364
  #else
372
365
  CobhanBufferNapi partition_id(env, partition_id_string);
373
366
  CobhanBufferNapi input(env, input_value);
374
- CobhanBufferNapi output(input.get_data_len_bytes());
367
+ CobhanBufferNapi output(env, input.get_data_len_bytes());
375
368
  #endif
376
369
 
377
370
  GoInt32 result = DecryptFromJson(partition_id, input, output);
@@ -401,7 +394,7 @@ private:
401
394
  CobhanBufferNapi partition_id(env, partition_id_string);
402
395
  CobhanBufferNapi input(env, input_value);
403
396
 
404
- CobhanBufferNapi output(input.get_data_len_bytes());
397
+ CobhanBufferNapi output(env, input.get_data_len_bytes());
405
398
 
406
399
  auto worker = new DecryptFromJsonWorker<Napi::String>(
407
400
  env, this, partition_id, input, output);
@@ -417,42 +410,96 @@ private:
417
410
  }
418
411
  }
419
412
 
413
+ void SetEnv(const Napi::CallbackInfo &info) {
414
+ Napi::Env env = info.Env();
415
+ Napi::HandleScope scope(env);
416
+ try {
417
+ NapiUtils::RequireParameterCount(info, 1);
418
+ CobhanBufferNapi env_json(env, info[0]);
419
+ ::SetEnv(env_json);
420
+ } catch (Napi::Error &e) {
421
+ e.ThrowAsJavaScriptException();
422
+ return;
423
+ } catch (const std::exception &e) {
424
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
425
+ return;
426
+ }
427
+ }
428
+
420
429
  void SetMaxStackAllocItemSize(const Napi::CallbackInfo &info) {
421
- NapiUtils::RequireParameterCount(info, 1);
430
+ Napi::Env env = info.Env();
431
+ Napi::HandleScope scope(env);
432
+ try {
433
+ NapiUtils::RequireParameterCount(info, 1);
422
434
 
423
- Napi::Number item_size = info[0].ToNumber();
424
- auto new_size = (size_t)item_size.Int32Value();
435
+ Napi::Number item_size = info[0].ToNumber();
436
+ auto new_size = (size_t)item_size.Int32Value();
425
437
 
426
- maximum_stack_alloc_size = new_size;
427
- //TODO: This needs exception handling consistent with other methods
438
+ maximum_stack_alloc_size = new_size;
439
+ } catch (Napi::Error &e) {
440
+ e.ThrowAsJavaScriptException();
441
+ return;
442
+ } catch (const std::exception &e) {
443
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
444
+ return;
445
+ }
428
446
  }
429
447
 
430
448
  void SetSafetyPaddingOverhead(const Napi::CallbackInfo &info) {
431
- NapiUtils::RequireParameterCount(info, 1);
449
+ Napi::Env env = info.Env();
450
+ Napi::HandleScope scope(env);
451
+ try {
452
+ NapiUtils::RequireParameterCount(info, 1);
432
453
 
433
- // Napi::Number safety_padding_number = info[0].ToNumber();
434
- // auto new_safety_padding_bytes = (size_t)
435
- // safety_padding_number.Int32Value(); Safety padding size is now fixed -
436
- // ignore the input set_safety_padding_bytes(new_safety_padding_bytes);
454
+ // Napi::Number safety_padding_number = info[0].ToNumber();
455
+ // auto new_safety_padding_bytes = (size_t)
456
+ // safety_padding_number.Int32Value(); Safety padding size is now fixed -
457
+ // ignore the input set_safety_padding_bytes(new_safety_padding_bytes);
458
+ } catch (Napi::Error &e) {
459
+ e.ThrowAsJavaScriptException();
460
+ return;
461
+ } catch (const std::exception &e) {
462
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
463
+ return;
464
+ }
437
465
  }
438
466
 
439
467
  Napi::Value
440
468
  GetSetupStatus(const Napi::CallbackInfo
441
469
  &info) { // NOLINT(*-convert-member-functions-to-static)
442
- int32_t setup_status = setup_state.load(std::memory_order_acquire);
443
- return Napi::Boolean::New(info.Env(), setup_status != 0);
444
- //TODO: This needs exception handling consistent with other methods
470
+ Napi::Env env = info.Env();
471
+ Napi::HandleScope scope(env);
472
+ try {
473
+ int32_t setup_status = setup_state.load(std::memory_order_acquire);
474
+ return Napi::Boolean::New(info.Env(), setup_status != 0);
475
+ } catch (Napi::Error &e) {
476
+ e.ThrowAsJavaScriptException();
477
+ return env.Undefined();
478
+ } catch (const std::exception &e) {
479
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
480
+ return env.Undefined();
481
+ }
445
482
  }
446
483
 
447
484
  void SetLogHook(const Napi::CallbackInfo &info) {
448
- NapiUtils::RequireParameterCount(info, 1);
449
485
 
450
- if (unlikely(!info[0].IsFunction())) {
451
- NapiUtils::ThrowException(info.Env(), "Expected a function");
452
- }
486
+ Napi::Env env = info.Env();
487
+ Napi::HandleScope scope(env);
488
+ try {
489
+ NapiUtils::RequireParameterCount(info, 1);
490
+
491
+ if (unlikely(!info[0].IsFunction())) {
492
+ NapiUtils::ThrowException(info.Env(), "Expected a function");
493
+ }
453
494
 
454
- logger.set_log_hook(info[0].As<Napi::Function>());
455
- //TODO: This needs exception handling consistent with other methods
495
+ logger.set_log_hook(info[0].As<Napi::Function>());
496
+ } catch (Napi::Error &e) {
497
+ e.ThrowAsJavaScriptException();
498
+ return;
499
+ } catch (const std::exception &e) {
500
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
501
+ return;
502
+ }
456
503
  }
457
504
 
458
505
  void BeginSetupAsherah(const Napi::Env &env, const char *func_name,
@@ -487,7 +534,8 @@ private:
487
534
 
488
535
  auto old_setup_state = setup_state.exchange(1, std::memory_order_acq_rel);
489
536
  if (unlikely(old_setup_state != 0)) {
490
- NapiUtils::ThrowException(env, "EndSetupAsherah: lost race to mark setup_state?!");
537
+ NapiUtils::ThrowException(
538
+ env, "EndSetupAsherah: lost race to mark setup_state?!");
491
539
  }
492
540
  }
493
541
 
@@ -506,14 +554,15 @@ private:
506
554
  Napi::String &output_string) {
507
555
  CheckResult(env, result);
508
556
 
509
- output_string = output.ToString(env);
557
+ output_string = output.ToString();
510
558
  }
511
559
 
512
- void EndEncryptToJson(Napi::Env env, CobhanBufferNapi &output, GoInt32 result,
513
- Napi::Buffer<unsigned char> &output_buffer) {
560
+ [[maybe_unused]] void
561
+ EndEncryptToJson(Napi::Env env, CobhanBufferNapi &output, GoInt32 result,
562
+ Napi::Buffer<unsigned char> &output_buffer) {
514
563
  CheckResult(env, result);
515
564
 
516
- output_buffer = output.ToBuffer(env);
565
+ output_buffer = output.ToBuffer();
517
566
  }
518
567
 
519
568
  void BeginDecryptFromJson(const Napi::Env &env, const char *func_name,
@@ -532,14 +581,14 @@ private:
532
581
  Napi::Buffer<unsigned char> &output_buffer) {
533
582
  CheckResult(env, result);
534
583
 
535
- output_buffer = output.ToBuffer(env);
584
+ output_buffer = output.ToBuffer();
536
585
  }
537
586
 
538
587
  void EndDecryptFromJson(Napi::Env &env, CobhanBufferNapi &output,
539
588
  GoInt32 result, Napi::String &output_string) {
540
589
  CheckResult(env, result);
541
590
 
542
- output_string = output.ToString(env);
591
+ output_string = output.ToString();
543
592
  }
544
593
 
545
594
  void BeginShutdownAsherah(const Napi::Env &env, const char *func_name,
@@ -551,7 +600,8 @@ private:
551
600
  void EndShutdownAsherah(Napi::Env &env) {
552
601
  auto old_setup_state = setup_state.exchange(0, std::memory_order_acq_rel);
553
602
  if (unlikely(old_setup_state == 0)) {
554
- NapiUtils::ThrowException(env, "EndSetupAsherah: lost race to mark setup_state?!");
603
+ NapiUtils::ThrowException(
604
+ env, "EndSetupAsherah: lost race to mark setup_state?!");
555
605
  }
556
606
  }
557
607
 
@@ -626,10 +676,10 @@ private:
626
676
  Napi::Value OnOKTask(Napi::Env &env) override {
627
677
  T output_result;
628
678
  asherah->EndDecryptFromJson(env, output, result, output_result);
629
- return output_result;
679
+ return output_result; // NOLINT(*-slicing)
630
680
  }
631
681
 
632
- protected:
682
+ private:
633
683
  CobhanBufferNapi partition_id;
634
684
  CobhanBufferNapi input;
635
685
  CobhanBufferNapi output;
@@ -663,18 +713,23 @@ private:
663
713
 
664
714
  void RequireAsherahSetup(const Napi::Env &env, const char *func_name) {
665
715
  if (unlikely(setup_state.load(std::memory_order_acquire) == 0)) {
666
- NapiUtils::ThrowException(env, "RequireAsherahSetup: setup() not called");
716
+ NapiUtils::ThrowException(
717
+ env,
718
+ std::string(func_name) + ": RequireAsherahSetup: setup() not called");
667
719
  }
668
720
  }
669
721
 
670
722
  void RequireAsherahNotSetup(const Napi::Env &env, const char *func_name) {
671
723
  if (unlikely(setup_state.load(std::memory_order_acquire) != 0)) {
672
- NapiUtils::ThrowException(env, "RequireAsherahNotSetup: setup() already called");
724
+ NapiUtils::ThrowException(
725
+ env, std::string(func_name) +
726
+ ": RequireAsherahNotSetup: setup() already called");
673
727
  }
674
728
  }
675
729
 
676
- __attribute__((always_inline)) inline size_t
677
- EstimateAsherahOutputSize(size_t data_byte_len, size_t partition_byte_len) {
730
+ [[nodiscard]] __attribute__((always_inline)) inline size_t
731
+ EstimateAsherahOutputSize(size_t data_byte_len,
732
+ size_t partition_byte_len) const {
678
733
  const size_t est_encryption_overhead = 48;
679
734
  const size_t est_envelope_overhead = 185;
680
735
  const double base64_overhead = 1.34;
@@ -733,3 +788,5 @@ private:
733
788
  };
734
789
 
735
790
  NODE_API_NAMED_ADDON(asherah, Asherah)
791
+
792
+ #pragma clang diagnostic pop
package/src/asherah.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ // noinspection JSUnusedGlobalSymbols,DuplicatedCode
2
+
1
3
  /// <reference types="node" />
2
4
  export type AsherahConfig = {
3
5
  /** The name of this service (Required) */
@@ -58,3 +60,4 @@ export declare function set_max_stack_alloc_item_size(max_item_size: number): vo
58
60
  export declare function set_safety_padding_overhead(safety_padding_overhead: number): void;
59
61
  export declare function set_log_hook(logHook: LogHookCallback): void;
60
62
  export declare function get_setup_status(): boolean;
63
+ export declare function setenv(environment: string): void;
@@ -1,14 +1,9 @@
1
- // asherah_async_worker.h
2
1
  #ifndef ASHERAH_ASYNC_WORKER_H
3
2
  #define ASHERAH_ASYNC_WORKER_H
4
3
 
5
4
  #include <napi.h>
6
5
  #include <stdexcept>
7
6
 
8
- #ifndef NAPI_CPP_EXCEPTIONS
9
- #error Support for C++ exceptions is required
10
- #endif
11
-
12
7
  class Asherah;
13
8
 
14
9
  template <typename ResultType>
@@ -52,16 +52,16 @@ public:
52
52
  return static_cast<void *>(cbuffer);
53
53
  }
54
54
 
55
- char *get_data_ptr() const { return data_ptr; }
55
+ [[nodiscard]] char *get_data_ptr() const { return data_ptr; }
56
56
 
57
- size_t get_data_len_bytes() const { return *data_len_ptr; }
57
+ [[nodiscard]] size_t get_data_len_bytes() const { return *data_len_ptr; }
58
58
 
59
59
  ~CobhanBuffer() {
60
60
  verify_canaries();
61
61
  cleanup();
62
62
  }
63
63
 
64
- __attribute__((unused)) std::string DebugPrintStdErr() const {
64
+ [[nodiscard]] __attribute__((unused)) std::string DebugPrintStdErr() const {
65
65
  auto debug_string = std::string(get_data_ptr(), get_data_len_bytes());
66
66
  std::ostringstream debug_output;
67
67
  debug_output << "CobhanBuffer { " << std::endl
@@ -127,7 +127,7 @@ protected:
127
127
  }
128
128
  }
129
129
 
130
- size_t get_allocation_size() const { return allocation_size; }
130
+ [[nodiscard]] size_t get_allocation_size() const { return allocation_size; }
131
131
 
132
132
  void set_data_len_bytes(size_t data_len_bytes) {
133
133
  if (data_len_bytes > max_int32_size) {
@@ -6,35 +6,30 @@
6
6
  #include <napi.h>
7
7
  #include <stdexcept>
8
8
 
9
- #ifndef NAPI_CPP_EXCEPTIONS
10
- #error Support for C++ exceptions is required
11
- #endif
12
-
13
9
  class CobhanBufferNapi : public CobhanBuffer {
14
10
  public:
15
11
  // Constructor from a Napi::String
16
12
  CobhanBufferNapi(const Napi::Env &env, const Napi::String &napiString)
17
- : CobhanBuffer(NapiUtils::GetUtf8StringLength(env, napiString) +
18
- 1) { // Add one for possible NULL delimiter due to Node
19
- // string functions
20
- copy_from_string(env, napiString);
13
+ : CobhanBuffer(NapiUtils::GetUtf8StringLength(env, napiString) + 1),
14
+ env(env) { // Add one for possible NULL delimiter due to Node
15
+ // string functions
16
+ copy_from_string(napiString);
21
17
  }
22
18
 
23
19
  // Constructor from Napi::Buffer<unsigned char>
24
20
  explicit CobhanBufferNapi(const Napi::Env &env,
25
21
  const Napi::Buffer<unsigned char> &napiBuffer)
26
- : CobhanBuffer(napiBuffer.ByteLength()) {
22
+ : CobhanBuffer(napiBuffer.ByteLength()), env(env) {
27
23
  std::memcpy(get_data_ptr(), napiBuffer.Data(), napiBuffer.ByteLength());
28
24
  }
29
25
 
30
26
  // Constructor from Napi::Value
31
27
  explicit CobhanBufferNapi(const Napi::Env &env, const Napi::Value &napiValue)
32
- : CobhanBuffer(ValueToDataSize(env, napiValue)) {
28
+ : CobhanBuffer(ValueToDataSize(env, napiValue)), env(env) {
33
29
  if (napiValue.IsString()) {
34
- copy_from_string(env, napiValue.As<Napi::String>());
30
+ copy_from_string(napiValue.As<Napi::String>());
35
31
  } else if (napiValue.IsBuffer()) {
36
- Napi::Buffer<unsigned char> napiBuffer =
37
- napiValue.As<Napi::Buffer<unsigned char>>();
32
+ auto napiBuffer = napiValue.As<Napi::Buffer<unsigned char>>();
38
33
  std::memcpy(get_data_ptr(), napiBuffer.Data(), napiBuffer.Length());
39
34
  } else {
40
35
  NapiUtils::ThrowException(
@@ -47,26 +42,25 @@ public:
47
42
  CobhanBufferNapi(const Napi::Env &env,
48
43
  const Napi::Buffer<unsigned char> &napiBuffer, char *cbuffer,
49
44
  size_t allocation_size)
50
- : CobhanBuffer(cbuffer, allocation_size) {
45
+ : CobhanBuffer(cbuffer, allocation_size), env(env) {
51
46
  std::memcpy(get_data_ptr(), napiBuffer.Data(), napiBuffer.Length());
52
47
  }
53
48
 
54
49
  // Constructor from a Napi::String to an externally allocated buffer
55
50
  CobhanBufferNapi(const Napi::Env &env, const Napi::String &napiString,
56
51
  char *cbuffer, size_t allocation_size)
57
- : CobhanBuffer(cbuffer, allocation_size) {
58
- copy_from_string(env, napiString);
52
+ : CobhanBuffer(cbuffer, allocation_size), env(env) {
53
+ copy_from_string(napiString);
59
54
  }
60
55
 
61
56
  // Constructor from a Napi::String to an externally allocated buffer
62
57
  CobhanBufferNapi(const Napi::Env &env, const Napi::Value &napiValue,
63
58
  char *cbuffer, size_t allocation_size)
64
- : CobhanBuffer(cbuffer, allocation_size) {
59
+ : CobhanBuffer(cbuffer, allocation_size), env(env) {
65
60
  if (napiValue.IsString()) {
66
- copy_from_string(env, napiValue.As<Napi::String>());
61
+ copy_from_string(napiValue.As<Napi::String>());
67
62
  } else if (napiValue.IsBuffer()) {
68
- Napi::Buffer<unsigned char> napiBuffer =
69
- napiValue.As<Napi::Buffer<unsigned char>>();
63
+ auto napiBuffer = napiValue.As<Napi::Buffer<unsigned char>>();
70
64
  std::memcpy(get_data_ptr(), napiBuffer.Data(), napiBuffer.Length());
71
65
  } else {
72
66
  NapiUtils::ThrowException(
@@ -77,17 +71,18 @@ public:
77
71
 
78
72
  // Constructor from size_t representing data length in bytes (not allocation
79
73
  // size)
80
- explicit CobhanBufferNapi(size_t data_len_bytes)
81
- : CobhanBuffer(data_len_bytes) {}
74
+ explicit CobhanBufferNapi(const Napi::Env &env, size_t data_len_bytes)
75
+ : CobhanBuffer(data_len_bytes), env(env) {}
82
76
 
83
77
  // Constructor from externally allocated char* and size_t representing
84
78
  // allocation size in bytes
85
- explicit CobhanBufferNapi(char *cbuffer, size_t allocation_size)
86
- : CobhanBuffer(cbuffer, allocation_size) {}
79
+ explicit CobhanBufferNapi(const Napi::Env &env, char *cbuffer,
80
+ size_t allocation_size)
81
+ : CobhanBuffer(cbuffer, allocation_size), env(env) {}
87
82
 
88
83
  // Move constructor
89
84
  CobhanBufferNapi(CobhanBufferNapi &&other) noexcept
90
- : CobhanBuffer(std::move(other)) {}
85
+ : CobhanBuffer(std::move(other)), env(other.env) {}
91
86
 
92
87
  // Move assignment operator
93
88
  CobhanBufferNapi &operator=(CobhanBufferNapi &&other) noexcept {
@@ -98,7 +93,7 @@ public:
98
93
  }
99
94
 
100
95
  // Returns a Napi::String from the buffer using napi_create_string_utf8
101
- Napi::String ToString(const Napi::Env &env) const {
96
+ [[nodiscard]] Napi::String ToString() const {
102
97
  napi_value napiStr;
103
98
  napi_status status = napi_create_string_utf8(
104
99
  env, get_data_ptr(), get_data_len_bytes(), &napiStr);
@@ -113,7 +108,7 @@ public:
113
108
  }
114
109
 
115
110
  // Returns a Napi::Buffer<unsigned char> from the buffer
116
- Napi::Buffer<unsigned char> ToBuffer(const Napi::Env &env) const {
111
+ [[nodiscard]] Napi::Buffer<unsigned char> ToBuffer() const {
117
112
  auto buffer = Napi::Buffer<unsigned char>::Copy(
118
113
  env, reinterpret_cast<unsigned char *>(get_data_ptr()),
119
114
  get_data_len_bytes());
@@ -167,9 +162,11 @@ public:
167
162
  }
168
163
 
169
164
  private:
170
- void copy_from_string(const Napi::Env &env, const Napi::String &napiString) {
171
- size_t str_len = NapiUtils::GetUtf8StringLength(env, napiString);
165
+ Napi::Env env;
172
166
 
167
+ void copy_from_string(const Napi::String &napiString) {
168
+ size_t str_len = NapiUtils::GetUtf8StringLength(env, napiString);
169
+ // Add one for NULL delimiter due to napi_get_value_string_utf8
173
170
  size_t allocation_size =
174
171
  CobhanBuffer::DataSizeToAllocationSize(str_len) + 1;
175
172
 
@@ -179,6 +176,7 @@ private:
179
176
  "Buffer allocation size is insufficient to hold the Napi::String.");
180
177
  }
181
178
 
179
+ // Bytes written is the number of bytes copied, excluding the NULL
182
180
  size_t bytes_written;
183
181
  napi_status status = napi_get_value_string_utf8(
184
182
  env, napiString, get_data_ptr(), str_len + 1, &bytes_written);
@@ -189,6 +187,7 @@ private:
189
187
  ", Bytes Written: " + std::to_string(bytes_written));
190
188
  }
191
189
 
190
+ // Update our data length to the actual string length
192
191
  set_data_len_bytes(str_len);
193
192
  }
194
193
  };
package/src/logging.h CHANGED
@@ -1,13 +1,17 @@
1
+ #pragma clang diagnostic push
2
+ #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
3
+
1
4
  #ifndef LOGGING_H
2
5
  #define LOGGING_H
6
+
7
+ #include <cstddef> // size_t
8
+ #include <cstdint> // int32_t
3
9
  #include <sstream> // std::ostringstream
4
10
  #include <string> // std::string
5
- #include <cstdint> // int32_t
6
- #include <cstddef> // size_t
7
11
 
8
12
  class Logger {
9
13
  public:
10
- void set_verbose_flag(int32_t verbose_flag);
14
+ [[maybe_unused]] void set_verbose_flag(int32_t verbose) { verbose_flag = verbose != 0; };
11
15
 
12
16
  virtual void debug_log(const char *function_name,
13
17
  const char *message) const = 0;
@@ -34,21 +38,12 @@ public:
34
38
  }
35
39
 
36
40
  protected:
37
- explicit Logger(const std::string &system_name);
38
-
39
41
  bool verbose_flag = false;
40
42
  std::string system_name;
41
43
 
42
- void stderr_debug_log(const char *function_name, const char *message) const;
43
- void stderr_debug_log(const char *function_name,
44
- const std::string &message) const;
45
- void stderr_debug_log_alloca(const char *function_name,
46
- const char *variable_name, size_t length) const;
47
- void stderr_debug_log_new(const char *function_name,
48
- const char *variable_name, size_t length) const;
49
- void stderr_error_log(const char *function_name, const char *message) const;
50
- void stderr_error_log(const char *function_name,
51
- const std::string &message) const;
44
+ explicit Logger(std::string system_name) : system_name(std::move(system_name)) {}
52
45
  };
53
46
 
54
47
  #endif // LOGGING_H
48
+
49
+ #pragma clang diagnostic pop
@@ -1,14 +1,17 @@
1
1
  #include "logging_napi.h"
2
2
  #include "napi_utils.h"
3
3
 
4
- LoggerNapi::LoggerNapi(Napi::Env &env, std::string system_name)
5
- : Logger(system_name), log_hook(Napi::FunctionReference()), env(env) {}
4
+ LoggerNapi::LoggerNapi(Napi::Env &env, const std::string &system_name)
5
+ : StdErrLogger(system_name), log_hook(Napi::FunctionReference()), env(env) {
6
+ }
6
7
 
7
- LoggerNapi::LoggerNapi(Napi::Env &env, std::string system_name,
8
- Napi::Function new_log_hook)
9
- : Logger(system_name), env(env) {
8
+ [[maybe_unused]] LoggerNapi::LoggerNapi(Napi::Env &env,
9
+ const std::string &system_name,
10
+ Napi::Function new_log_hook)
11
+ : StdErrLogger(system_name), env(env) {
10
12
  if (unlikely(new_log_hook.IsEmpty())) {
11
- NapiUtils::ThrowException(env, system_name + ": new_log_hook cannot be nullptr");
13
+ NapiUtils::ThrowException(env,
14
+ system_name + ": new_log_hook cannot be nullptr");
12
15
  }
13
16
  log_hook = Napi::Persistent(new_log_hook);
14
17
  }
@@ -22,7 +25,8 @@ LoggerNapi::~LoggerNapi() {
22
25
 
23
26
  void LoggerNapi::set_log_hook(Napi::Function new_log_hook) {
24
27
  if (unlikely(new_log_hook.IsUndefined() || new_log_hook.IsEmpty())) {
25
- NapiUtils::ThrowException(env, system_name + ": new_log_hook cannot be empty");
28
+ NapiUtils::ThrowException(env,
29
+ system_name + ": new_log_hook cannot be empty");
26
30
  }
27
31
  auto old_log_hook = std::exchange(log_hook, Napi::Persistent(new_log_hook));
28
32
  if (!old_log_hook.IsEmpty()) {
@@ -36,17 +40,19 @@ void LoggerNapi::call_log_hook(int level, const std::string &message) const {
36
40
  }
37
41
  Napi::HandleScope scope(env);
38
42
  Napi::Function log_hook_function = log_hook.Value();
39
- log_hook_function.Call({Napi::Number::New(env, level),
40
- Napi::String::New(env, system_name + ": " + message)});
43
+ log_hook_function.Call(
44
+ {Napi::Number::New(env, level),
45
+ Napi::String::New(env, system_name + ": " + message)});
41
46
  }
42
47
 
43
48
  void LoggerNapi::debug_log(const char *function_name,
44
49
  const char *message) const {
45
50
  if (unlikely(verbose_flag)) {
46
51
  if (unlikely(log_hook.IsEmpty())) {
47
- stderr_debug_log(function_name, message);
52
+ StdErrLogger::debug_log(function_name, message);
48
53
  } else {
49
- call_log_hook(posix_log_level_debug, system_name + ": " + function_name + ": " + message);
54
+ call_log_hook(posix_log_level_debug,
55
+ system_name + ": " + function_name + ": " + message);
50
56
  }
51
57
  }
52
58
  }
@@ -55,9 +61,10 @@ void LoggerNapi::debug_log(const char *function_name,
55
61
  const std::string &message) const {
56
62
  if (unlikely(verbose_flag)) {
57
63
  if (unlikely(log_hook.IsEmpty())) {
58
- stderr_debug_log(function_name, message);
64
+ StdErrLogger::debug_log(function_name, message);
59
65
  } else {
60
- call_log_hook(posix_log_level_debug, system_name + ": " + function_name + ": " + message);
66
+ call_log_hook(posix_log_level_debug,
67
+ system_name + ": " + function_name + ": " + message);
61
68
  }
62
69
  }
63
70
  }
@@ -67,12 +74,12 @@ void LoggerNapi::debug_log_alloca(const char *function_name,
67
74
  size_t length) const {
68
75
  if (unlikely(verbose_flag)) {
69
76
  if (unlikely(log_hook.IsEmpty())) {
70
- stderr_debug_log_alloca(function_name, variable_name, length);
77
+ StdErrLogger::debug_log_alloca(function_name, variable_name, length);
71
78
  } else {
72
- call_log_hook(posix_log_level_debug, system_name + ": " + function_name +
73
- ": Calling alloca(" +
74
- std::to_string(length) +
75
- ") (stack) for " + variable_name);
79
+ call_log_hook(posix_log_level_debug,
80
+ system_name + ": " + function_name + ": Calling alloca(" +
81
+ std::to_string(length) + ") (stack) for " +
82
+ variable_name);
76
83
  }
77
84
  }
78
85
  }
@@ -81,12 +88,12 @@ void LoggerNapi::debug_log_new(const char *function_name,
81
88
  const char *variable_name, size_t length) const {
82
89
  if (unlikely(verbose_flag)) {
83
90
  if (unlikely(log_hook.IsEmpty())) {
84
- stderr_debug_log_new(function_name, variable_name, length);
91
+ StdErrLogger::debug_log_new(function_name, variable_name, length);
85
92
  } else {
86
93
  call_log_hook(posix_log_level_debug, system_name + ": " + function_name +
87
- ": Calling new[" +
88
- std::to_string(length) + "] (heap) for " +
89
- variable_name);
94
+ ": Calling new[" +
95
+ std::to_string(length) +
96
+ "] (heap) for " + variable_name);
90
97
  }
91
98
  }
92
99
  }
@@ -94,13 +101,15 @@ void LoggerNapi::debug_log_new(const char *function_name,
94
101
  void LoggerNapi::error_log(const char *function_name,
95
102
  const char *message) const {
96
103
  if (likely(!log_hook.IsEmpty())) {
97
- call_log_hook(posix_log_level_error, system_name + ": " + function_name + ": " + message);
104
+ call_log_hook(posix_log_level_error,
105
+ system_name + ": " + function_name + ": " + message);
98
106
  }
99
107
  }
100
108
 
101
109
  void LoggerNapi::error_log(const char *function_name,
102
110
  const std::string &message) const {
103
111
  if (likely(!log_hook.IsEmpty())) {
104
- call_log_hook(posix_log_level_error, system_name + ": " + function_name + ": " + message);
112
+ call_log_hook(posix_log_level_error,
113
+ system_name + ": " + function_name + ": " + message);
105
114
  }
106
115
  }
@@ -1,18 +1,18 @@
1
1
  #ifndef LOGGING_NAPI_H
2
2
  #define LOGGING_NAPI_H
3
+
3
4
  #include "hints.h"
4
5
  #include "logging.h"
6
+ #include "logging_stderr.h"
5
7
  #include <napi.h>
6
8
 
7
- #ifndef NAPI_CPP_EXCEPTIONS
8
- #error Support for C++ exceptions is required
9
- #endif
10
-
11
- class LoggerNapi : public Logger {
9
+ class LoggerNapi : public StdErrLogger {
12
10
  public:
13
- LoggerNapi(Napi::Env &env, std::string system_name);
14
- explicit LoggerNapi(Napi::Env &env, std::string system_name,
15
- Napi::Function new_log_hook);
11
+ LoggerNapi(Napi::Env &env, const std::string &system_name);
12
+
13
+ [[maybe_unused]] explicit LoggerNapi(Napi::Env &env,
14
+ const std::string &system_name,
15
+ Napi::Function new_log_hook);
16
16
  ~LoggerNapi();
17
17
 
18
18
  void set_log_hook(Napi::Function new_log_hook);
@@ -1,14 +1,12 @@
1
- #include "logging.h"
1
+ #include "logging_stderr.h"
2
2
  #include "hints.h"
3
3
  #include <iostream>
4
4
 
5
- void Logger::set_verbose_flag(int32_t verbose) { verbose_flag = verbose != 0; }
5
+ StdErrLogger::StdErrLogger(const std::string &system_name)
6
+ : Logger(system_name) {}
6
7
 
7
- Logger::Logger(const std::string &system_name) : system_name(system_name) {
8
- std::cerr << "Created logger for " << system_name << std::endl << std::flush;
9
- }
10
-
11
- void Logger::stderr_debug_log(const char *function_name, const char *message) const {
8
+ void StdErrLogger::debug_log(const char *function_name,
9
+ const char *message) const {
12
10
  if (unlikely(verbose_flag)) {
13
11
  std::cerr << system_name << ": [DEBUG] " << function_name << ": " << message
14
12
  << std::endl
@@ -16,8 +14,8 @@ void Logger::stderr_debug_log(const char *function_name, const char *message) co
16
14
  }
17
15
  }
18
16
 
19
- void Logger::stderr_debug_log(const char *function_name,
20
- const std::string &message) const {
17
+ void StdErrLogger::debug_log(const char *function_name,
18
+ const std::string &message) const {
21
19
  if (unlikely(verbose_flag)) {
22
20
  std::cerr << system_name << ": [DEBUG] " << function_name << ": " << message
23
21
  << std::endl
@@ -25,8 +23,9 @@ void Logger::stderr_debug_log(const char *function_name,
25
23
  }
26
24
  }
27
25
 
28
- void Logger::stderr_debug_log_alloca(
29
- const char *function_name, const char *variable_name, size_t length) const {
26
+ void StdErrLogger::debug_log_alloca(const char *function_name,
27
+ const char *variable_name,
28
+ size_t length) const {
30
29
  if (unlikely(verbose_flag)) {
31
30
  std::cerr << system_name << ": [DEBUG] " << function_name
32
31
  << ": Calling alloca(" << length << ") (stack) for "
@@ -35,8 +34,9 @@ void Logger::stderr_debug_log_alloca(
35
34
  }
36
35
  }
37
36
 
38
- void Logger::stderr_debug_log_new(const char *function_name,
39
- const char *variable_name, size_t length) const {
37
+ void StdErrLogger::debug_log_new(const char *function_name,
38
+ const char *variable_name,
39
+ size_t length) const {
40
40
  if (unlikely(verbose_flag)) {
41
41
  std::cerr << system_name << ": [DEBUG] " << function_name
42
42
  << ": Calling new[" << length << "] (heap) for " << variable_name
@@ -45,14 +45,15 @@ void Logger::stderr_debug_log_new(const char *function_name,
45
45
  }
46
46
  }
47
47
 
48
- void Logger::stderr_error_log(const char *function_name, const char *message) const {
48
+ void StdErrLogger::error_log(const char *function_name,
49
+ const char *message) const {
49
50
  std::cerr << system_name << ": [ERROR] " << function_name << ": " << message
50
51
  << std::endl
51
52
  << std::flush;
52
53
  }
53
54
 
54
- void Logger::stderr_error_log(const char *function_name,
55
- const std::string &message) const {
55
+ void StdErrLogger::error_log(const char *function_name,
56
+ const std::string &message) const {
56
57
  std::cerr << system_name << ": [ERROR] " << function_name << ": " << message
57
58
  << std::endl
58
59
  << std::flush;
@@ -0,0 +1,23 @@
1
+ #ifndef STDERR_LOGGER_H
2
+ #define STDERR_LOGGER_H
3
+
4
+ #include "logging.h"
5
+
6
+ class StdErrLogger : public Logger {
7
+ public:
8
+ StdErrLogger() = delete;
9
+ explicit StdErrLogger(const std::string &system_name);
10
+
11
+ void debug_log(const char *function_name, const char *message) const override;
12
+ void debug_log(const char *function_name,
13
+ const std::string &message) const override;
14
+ void debug_log_alloca(const char *function_name, const char *variable_name,
15
+ size_t length) const override;
16
+ void debug_log_new(const char *function_name, const char *variable_name,
17
+ size_t length) const override;
18
+ void error_log(const char *function_name, const char *message) const override;
19
+ void error_log(const char *function_name,
20
+ const std::string &message) const override;
21
+ };
22
+
23
+ #endif // STDERR_LOGGER_H
package/src/napi_utils.h CHANGED
@@ -5,9 +5,6 @@
5
5
  #include <napi.h>
6
6
  #include <stdexcept>
7
7
  #include <string>
8
- #ifndef NAPI_CPP_EXCEPTIONS
9
- #error Support for C++ exceptions is required
10
- #endif
11
8
 
12
9
  class NapiUtils {
13
10
  public:
@@ -26,7 +23,7 @@ public:
26
23
 
27
24
  [[noreturn]] static void ThrowException(const Napi::Env &env,
28
25
  const std::string &message) {
29
- //throw std::runtime_error(message);
26
+ // throw std::runtime_error(message);
30
27
  throw Napi::Error::New(env, message);
31
28
  }
32
29
 
@@ -41,12 +38,12 @@ public:
41
38
  ThrowException(env, "Input value is undefined");
42
39
  } else if (value.IsString()) {
43
40
  // Convert string to object using JSON.parse
44
- Napi::String str = value.As<Napi::String>();
41
+ auto str = value.As<Napi::String>();
45
42
  jsonString = str;
46
43
  jsonObject = jsonParse.Call({str}).As<Napi::Object>();
47
44
  } else if (value.IsObject()) {
48
45
  // Convert object to string using JSON.stringify
49
- Napi::Object obj = value.As<Napi::Object>();
46
+ auto obj = value.As<Napi::Object>();
50
47
  if (jsonStringify.IsUndefined()) {
51
48
  ThrowException(env, "jsonStringify is undefined");
52
49
  } else if (jsonStringify.IsEmpty()) {
@@ -114,25 +111,31 @@ public:
114
111
  if (likely(value.IsString())) {
115
112
  return value.As<Napi::String>();
116
113
  } else if (unlikely(value.IsUndefined())) {
117
- ThrowException(env, std::string(func_name) + ": Expected String but received undefined");
114
+ ThrowException(env, std::string(func_name) +
115
+ ": Expected String but received undefined");
118
116
  } else if (unlikely(value.IsNull())) {
119
- ThrowException(env, std::string(func_name) + ": Expected String but received null");
117
+ ThrowException(env, std::string(func_name) +
118
+ ": Expected String but received null");
120
119
  } else {
121
- ThrowException(env, std::string(func_name) + ": Expected String but received unknown type");
120
+ ThrowException(env, std::string(func_name) +
121
+ ": Expected String but received unknown type");
122
122
  }
123
123
  }
124
124
 
125
- __attribute__((unused)) static Napi::Buffer<unsigned char>
125
+ __attribute__((unused)) static Napi::Buffer<unsigned char>
126
126
  RequireParameterBuffer(const Napi::Env &env, const char *func_name,
127
127
  Napi::Value value) {
128
128
  if (likely(value.IsBuffer())) {
129
129
  return value.As<Napi::Buffer<unsigned char>>();
130
130
  } else if (unlikely(value.IsUndefined())) {
131
- ThrowException(env, std::string(func_name) + ": Expected String but received undefined");
131
+ ThrowException(env, std::string(func_name) +
132
+ ": Expected String but received undefined");
132
133
  } else if (unlikely(value.IsNull())) {
133
- ThrowException(env, std::string(func_name) + ": Expected String but received null");
134
+ ThrowException(env, std::string(func_name) +
135
+ ": Expected String but received null");
134
136
  } else {
135
- ThrowException(env, std::string(func_name) + ": Expected String but received unknown type");
137
+ ThrowException(env, std::string(func_name) +
138
+ ": Expected String but received unknown type");
136
139
  }
137
140
  }
138
141
 
@@ -144,11 +147,14 @@ public:
144
147
  } else if (likely(value.IsBuffer())) {
145
148
  return value.As<Napi::Buffer<unsigned char>>(); // NOLINT(*-slicing)
146
149
  } else if (unlikely(value.IsUndefined())) {
147
- ThrowException(env, std::string(func_name) + ": Expected String but received undefined");
150
+ ThrowException(env, std::string(func_name) +
151
+ ": Expected String but received undefined");
148
152
  } else if (unlikely(value.IsNull())) {
149
- ThrowException(env, std::string(func_name) + ": Expected String but received null");
153
+ ThrowException(env, std::string(func_name) +
154
+ ": Expected String but received null");
150
155
  } else {
151
- ThrowException(env, std::string(func_name) + ": Expected String but received unknown type");
156
+ ThrowException(env, std::string(func_name) +
157
+ ": Expected String but received unknown type");
152
158
  }
153
159
  }
154
160
 
@@ -1,6 +1,8 @@
1
1
  #ifndef SCOPED_ALLOCATE_H
2
2
  #define SCOPED_ALLOCATE_H
3
3
 
4
+ #ifdef USE_SCOPED_ALLOCATE_BUFFER
5
+
4
6
  /*
5
7
  This macro allows us to allocate a buffer either on the stack or on the heap.
6
8
  If the requested buffer size is less than max_stack_alloc_size, we create the
@@ -13,36 +15,36 @@
13
15
  will automatically free the allocated buffer when it goes out of scope.
14
16
  */
15
17
 
16
- #define SCOPED_ALLOCATE_BUFFER_UNIQUE_PTR(logger, buffer, buffer_size, \
17
- unique_ptr, max_stack_alloc_size, \
18
- function_name) \
18
+ #define SCOPED_ALLOCATE_BUFFER_UNIQUE_PTR(buffer, buffer_size, unique_ptr, \
19
+ max_stack_alloc_size, function_name) \
19
20
  do { \
20
21
  buffer = nullptr; \
21
22
  if (buffer_size < max_stack_alloc_size) { \
22
23
  /* If the buffer is small enough, allocate it on the stack */ \
23
- logger.debug_log_alloca(function_name, #buffer, buffer_size); \
24
24
  buffer = (char *)alloca(buffer_size); \
25
- throw std::runtime_error("alloca(" + std::to_string(buffer_size) + \
26
- ") returned null"); \
25
+ if (unlikely(buffer == nullptr)) { \
26
+ throw std::runtime_error(std::string(function_name) + " alloca(" + \
27
+ std::to_string(buffer_size) + \
28
+ ") returned null"); \
29
+ } \
27
30
  } else { \
28
31
  /* Otherwise, allocate it on the heap */ \
29
- logger.debug_log_new(function_name, #buffer, buffer_size); \
30
32
  buffer = new (std::nothrow) char[buffer_size]; \
31
33
  if (unlikely(buffer == nullptr)) { \
32
- std::string error_msg = std::string(function_name) + "new[" + \
33
- std::to_string(buffer_size) + \
34
- "] returned null"; \
35
- throw std::runtime_error(error_msg); \
34
+ throw std::runtime_error(std::string(function_name) + " new[" + \
35
+ std::to_string(buffer_size) + \
36
+ "] returned null"); \
36
37
  } \
37
38
  unique_ptr.reset(buffer); \
38
39
  } \
39
40
  } while (0)
40
41
 
41
- #define SCOPED_ALLOCATE_BUFFER(logger, buffer, buffer_size, \
42
- max_stack_alloc_size, function_name) \
42
+ #define SCOPED_ALLOCATE_BUFFER(buffer, buffer_size, max_stack_alloc_size, \
43
+ function_name) \
43
44
  std::unique_ptr<char[]> buffer##_unique_ptr; \
44
- SCOPED_ALLOCATE_BUFFER_UNIQUE_PTR(logger, buffer, buffer_size, \
45
- buffer##_unique_ptr, max_stack_alloc_size, \
46
- function_name)
45
+ SCOPED_ALLOCATE_BUFFER_UNIQUE_PTR(buffer, buffer_size, buffer##_unique_ptr, \
46
+ max_stack_alloc_size, function_name)
47
+
48
+ #endif // USE_SCOPED_ALLOCATE_BUFFER
47
49
 
48
50
  #endif // SCOPED_ALLOCATE_H