|
42 | 42 | // StartComAndWoSignData.inc
|
43 | 43 | #include "StartComAndWoSignData.inc"
|
44 | 44 |
|
| 45 | +#include <algorithm> |
45 | 46 | #include <errno.h>
|
46 | 47 | #include <limits.h> // INT_MAX
|
47 | 48 | #include <math.h>
|
48 | 49 | #include <stdlib.h>
|
49 | 50 | #include <string.h>
|
| 51 | +#include <vector> |
50 | 52 |
|
51 | 53 | #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val, prefix) \
|
52 | 54 | do { \
|
@@ -428,44 +430,33 @@ void ThrowCryptoError(Environment* env,
|
428 | 430 | Local<Value> exception_v = Exception::Error(message);
|
429 | 431 | CHECK(!exception_v.IsEmpty());
|
430 | 432 | Local<Object> exception = exception_v.As<Object>();
|
431 |
| - ERR_STATE* es = ERR_get_state(); |
432 |
| - |
433 |
| - if (es->bottom != es->top) { |
434 |
| - Local<Array> error_stack = Array::New(env->isolate()); |
435 |
| - int top = es->top; |
436 |
| - |
437 |
| - // Build the error_stack array to be added to opensslErrorStack property. |
438 |
| - for (unsigned int i = 0; es->bottom != es->top;) { |
439 |
| - unsigned long err_buf = es->err_buffer[es->top]; // NOLINT(runtime/int) |
440 |
| - // Only add error string if there is valid err_buffer. |
441 |
| - if (err_buf) { |
442 |
| - char tmp_str[256]; |
443 |
| - ERR_error_string_n(err_buf, tmp_str, sizeof(tmp_str)); |
444 |
| - error_stack->Set(env->context(), i, |
445 |
| - String::NewFromUtf8(env->isolate(), tmp_str, |
446 |
| - v8::NewStringType::kNormal) |
447 |
| - .ToLocalChecked()).FromJust(); |
448 |
| - // Only increment if we added to error_stack. |
449 |
| - i++; |
450 |
| - } |
451 | 433 |
|
452 |
| - // Since the ERR_STATE is a ring buffer, we need to use modular |
453 |
| - // arithmetic to loop back around in the case where bottom is after top. |
454 |
| - // Using ERR_NUM_ERRORS macro defined in openssl. |
455 |
| - es->top = (((es->top - 1) % ERR_NUM_ERRORS) + ERR_NUM_ERRORS) % |
456 |
| - ERR_NUM_ERRORS; |
| 434 | + std::vector<Local<String>> errors; |
| 435 | + for (;;) { |
| 436 | + unsigned long err = ERR_get_error(); // NOLINT(runtime/int) |
| 437 | + if (err == 0) { |
| 438 | + break; |
457 | 439 | }
|
458 |
| - |
459 |
| - // Restore top. |
460 |
| - es->top = top; |
461 |
| - |
462 |
| - // Add the opensslErrorStack property to the exception object. |
463 |
| - // The new property will look like the following: |
464 |
| - // opensslErrorStack: [ |
465 |
| - // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib', |
466 |
| - // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 err' |
467 |
| - // ] |
468 |
| - exception->Set(env->context(), env->openssl_error_stack(), error_stack) |
| 440 | + char tmp_str[256]; |
| 441 | + ERR_error_string_n(err, tmp_str, sizeof(tmp_str)); |
| 442 | + errors.push_back(String::NewFromUtf8(env->isolate(), tmp_str, |
| 443 | + v8::NewStringType::kNormal) |
| 444 | + .ToLocalChecked()); |
| 445 | + } |
| 446 | + |
| 447 | + // ERR_get_error returns errors in order of most specific to least |
| 448 | + // specific. We wish to have the reverse ordering: |
| 449 | + // opensslErrorStack: [ |
| 450 | + // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib', |
| 451 | + // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 err' |
| 452 | + // ] |
| 453 | + if (!errors.empty()) { |
| 454 | + std::reverse(errors.begin(), errors.end()); |
| 455 | + Local<Array> errors_array = Array::New(env->isolate(), errors.size()); |
| 456 | + for (size_t i = 0; i < errors.size(); i++) { |
| 457 | + errors_array->Set(env->context(), i, errors[i]).FromJust(); |
| 458 | + } |
| 459 | + exception->Set(env->context(), env->openssl_error_stack(), errors_array) |
469 | 460 | .FromJust();
|
470 | 461 | }
|
471 | 462 |
|
|
0 commit comments