Commit 75c42e9d108 for nodejs

commit 75c42e9d1085a1c5ad9009b531a7aa16bdf00c79
Author: Yagiz Nizipli <yagiz@nizipli.com>
Date:   Wed Oct 28 17:25:03 2026 -0400

    crypto: skip clearing empty OpenSSL error queues

    ClearErrorOnReturn calls ERR_clear_error() when it is created and
    again when it goes out of scope. That function resets all 16 slots of
    the thread's error queue, including two free() calls per slot, even
    when the queue is empty, which is almost always the case. Check for a
    queued error first, which costs a fraction of that.

    ClearErrorOnReturn guards most crypto operations, including every
    CryptoJob, so this applies to all of them.

    Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
    Assisted-by: Grok
    PR-URL: https://github.com/nodejs/node/pull/67109
    Reviewed-By: Filip Skokan <panva.ip@gmail.com>

diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc
index 51f09e42710..ba0e1f2e09d 100644
--- a/deps/ncrypto/ncrypto.cc
+++ b/deps/ncrypto/ncrypto.cc
@@ -337,14 +337,22 @@ constexpr BoringSSLCipher kBoringSSLCiphers[] = {

 // ============================================================================

+namespace {
+// ERR_clear_error() resets every slot of the error queue even when it is
+// empty, which costs several times more than checking for an error first.
+void ClearErrorQueue() {
+  if (ERR_peek_error() != 0) ERR_clear_error();
+}
+}  // namespace
+
 ClearErrorOnReturn::ClearErrorOnReturn(CryptoErrorList* errors)
     : errors_(errors) {
-  ERR_clear_error();
+  ClearErrorQueue();
 }

 ClearErrorOnReturn::~ClearErrorOnReturn() {
   if (errors_ != nullptr) errors_->capture();
-  ERR_clear_error();
+  ClearErrorQueue();
 }

 unsigned long ClearErrorOnReturn::peekError() {  // NOLINT(runtime/int)