@@ -272,32 +272,47 @@ void ThrowCryptoError(Environment* env,
272
272
Local<Value> exception_v = Exception::Error (message);
273
273
CHECK (!exception_v.IsEmpty ());
274
274
Local<Object> exception = exception_v.As <Object>();
275
- Local<Array> error_stack = Array::New (env->isolate ());
276
-
277
- ERR_STATE *es = ERR_get_state ();
278
- // Build the error_stack array to be added to openSSLErrorStack property.
279
- for (unsigned int i = 0 ; es->bottom != es->top
280
- && (es->err_flags [es->top ] & ERR_FLAG_MARK) == 0 ; i++) {
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 tmpStr[256 ] = { };
285
- ERR_error_string_n (err_buf, tmpStr, sizeof (tmpStr));
286
- error_stack->Set (env->context (), i,
287
- String::NewFromUtf8 (env->isolate (), tmpStr,
288
- v8::NewStringType::kNormal )
289
- .ToLocalChecked ()).FromJust ();
275
+ ERR_STATE* es = ERR_get_state ();
276
+
277
+ if (es->bottom != es->top ) {
278
+ Local<Array> error_stack = Array::New (env->isolate ());
279
+ int top = es->top ;
280
+
281
+ // Build the error_stack array to be added to openSSLErrorStack property.
282
+ for (unsigned int i = 0 ; es->bottom != es->top ;) {
283
+ unsigned long err_buf = es->err_buffer [es->top ]; // NOLINT(runtime/int)
284
+ // Only add error string if there is valid err_buffer.
285
+ if (err_buf) {
286
+ char tmp_str[256 ];
287
+ ERR_error_string_n (err_buf, tmp_str, sizeof (tmp_str));
288
+ error_stack->Set (env->context (), i,
289
+ String::NewFromUtf8 (env->isolate (), tmp_str,
290
+ v8::NewStringType::kNormal )
291
+ .ToLocalChecked ()).FromJust ();
292
+ // Only increment if we added to error_stack.
293
+ i++;
294
+ }
295
+
296
+ // Since the ERR_STATE is a ring buffer, we need to use modular
297
+ // arithmetic to loop back around in the case where bottom is after top.
298
+ // Using ERR_NUM_ERRORS macro defined in openssl.
299
+ es->top = (((es->top - 1 ) % ERR_NUM_ERRORS) + ERR_NUM_ERRORS) %
300
+ ERR_NUM_ERRORS;
290
301
}
291
- es->top -= 1 ;
302
+
303
+ // Restore top.
304
+ es->top = top;
305
+
306
+ // Add the openSSLErrorStack property to the exception object.
307
+ // The new property will look like the following:
308
+ // openSSLErrorStack: [
309
+ // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib',
310
+ // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 err'
311
+ // ]
312
+ exception->Set (env->context (), env->openssl_error_stack (), error_stack)
313
+ .FromJust ();
292
314
}
293
315
294
- // Add the openSSLErrorStack property to the exception object.
295
- // The new property will look like the following:
296
- // openSSLErrorStack: [
297
- // 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib',
298
- // 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error'
299
- // ]
300
- exception->Set (env->openssl_error_stack (), error_stack);
301
316
env->isolate ()->ThrowException (exception);
302
317
}
303
318
@@ -4315,8 +4330,6 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
4315
4330
if (!initialised_)
4316
4331
return kSignNotInitialised ;
4317
4332
4318
- // ClearErrorOnReturn clear_error_on_return;
4319
-
4320
4333
EVP_PKEY* pkey = nullptr ;
4321
4334
BIO* bp = nullptr ;
4322
4335
X509* x509 = nullptr ;
@@ -4326,8 +4339,6 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
4326
4339
int r = 0 ;
4327
4340
EVP_PKEY_CTX* pkctx = nullptr ;
4328
4341
4329
- ERR_set_mark ();
4330
-
4331
4342
bp = BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len);
4332
4343
if (bp == nullptr )
4333
4344
goto exit;
0 commit comments