|
43 | 43 | // StartComAndWoSignData.inc |
44 | 44 | #include "StartComAndWoSignData.inc" |
45 | 45 |
|
| 46 | +#include <algorithm> |
46 | 47 | #include <errno.h> |
47 | 48 | #include <limits.h> // INT_MAX |
48 | 49 | #include <math.h> |
49 | 50 | #include <stdlib.h> |
50 | 51 | #include <string.h> |
| 52 | +#include <vector> |
51 | 53 |
|
52 | 54 | #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val, prefix) \ |
53 | 55 | do { \ |
@@ -270,44 +272,33 @@ void ThrowCryptoError(Environment* env, |
270 | 272 | Local<Value> exception_v = Exception::Error(message); |
271 | 273 | CHECK(!exception_v.IsEmpty()); |
272 | 274 | Local<Object> exception = exception_v.As<Object>(); |
273 | | - ERR_STATE* es = ERR_get_state(); |
274 | | - |
275 | | - if (es->bottom != es->top) { |
276 | | - Local<Array> error_stack = Array::New(env->isolate()); |
277 | | - int top = es->top; |
278 | | - |
279 | | - // Build the error_stack array to be added to opensslErrorStack property. |
280 | | - for (unsigned int i = 0; es->bottom != es->top;) { |
281 | | - unsigned long err_buf = es->err_buffer[es->top]; // NOLINT(runtime/int) |
282 | | - // Only add error string if there is valid err_buffer. |
283 | | - if (err_buf) { |
284 | | - char tmp_str[256]; |
285 | | - ERR_error_string_n(err_buf, tmp_str, sizeof(tmp_str)); |
286 | | - error_stack->Set(env->context(), i, |
287 | | - String::NewFromUtf8(env->isolate(), tmp_str, |
288 | | - v8::NewStringType::kNormal) |
289 | | - .ToLocalChecked()).FromJust(); |
290 | | - // Only increment if we added to error_stack. |
291 | | - i++; |
292 | | - } |
293 | 275 |
|
294 | | - // Since the ERR_STATE is a ring buffer, we need to use modular |
295 | | - // arithmetic to loop back around in the case where bottom is after top. |
296 | | - // Using ERR_NUM_ERRORS macro defined in openssl. |
297 | | - es->top = (((es->top - 1) % ERR_NUM_ERRORS) + ERR_NUM_ERRORS) % |
298 | | - ERR_NUM_ERRORS; |
| 276 | + std::vector<Local<String>> errors; |
| 277 | + for (;;) { |
| 278 | + unsigned long err = ERR_get_error(); // NOLINT(runtime/int) |
| 279 | + if (err == 0) { |
| 280 | + break; |
299 | 281 | } |
300 | | - |
301 | | - // Restore top. |
302 | | - es->top = top; |
303 | | - |
304 | | - // Add the opensslErrorStack property to the exception object. |
305 | | - // The new property will look like the following: |
306 | | - // opensslErrorStack: [ |
307 | | - // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib', |
308 | | - // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 err' |
309 | | - // ] |
310 | | - exception->Set(env->context(), env->openssl_error_stack(), error_stack) |
| 282 | + char tmp_str[256]; |
| 283 | + ERR_error_string_n(err, tmp_str, sizeof(tmp_str)); |
| 284 | + errors.push_back(String::NewFromUtf8(env->isolate(), tmp_str, |
| 285 | + v8::NewStringType::kNormal) |
| 286 | + .ToLocalChecked()); |
| 287 | + } |
| 288 | + |
| 289 | + // ERR_get_error returns errors in order of most specific to least |
| 290 | + // specific. We wish to have the reverse ordering: |
| 291 | + // opensslErrorStack: [ |
| 292 | + // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib', |
| 293 | + // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 err' |
| 294 | + // ] |
| 295 | + if (!errors.empty()) { |
| 296 | + std::reverse(errors.begin(), errors.end()); |
| 297 | + Local<Array> errors_array = Array::New(env->isolate(), errors.size()); |
| 298 | + for (size_t i = 0; i < errors.size(); i++) { |
| 299 | + errors_array->Set(env->context(), i, errors[i]).FromJust(); |
| 300 | + } |
| 301 | + exception->Set(env->context(), env->openssl_error_stack(), errors_array) |
311 | 302 | .FromJust(); |
312 | 303 | } |
313 | 304 |
|
|
0 commit comments