summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Roberts <vieuxtech@gmail.com>2018-11-21 18:02:53 -0800
committerSam Roberts <vieuxtech@gmail.com>2018-12-27 14:28:33 -0800
commitca9c0c90c28ed012cdd5be4e94a974ad07fd9b9a (patch)
treed1295a871cea804d5d847d9923385a91199bb386 /src
parent455bcca00574de4f1533476bd42496a649f07de4 (diff)
downloadandroid-node-v8-ca9c0c90c28ed012cdd5be4e94a974ad07fd9b9a.tar.gz
android-node-v8-ca9c0c90c28ed012cdd5be4e94a974ad07fd9b9a.tar.bz2
android-node-v8-ca9c0c90c28ed012cdd5be4e94a974ad07fd9b9a.zip
src: add .code and SSL specific error properties
SSL errors have a long structured message, but lacked the standard .code property which can be used for stable comparisons. Add a `code` property, as well as the 3 string components of an SSL error: `reason`, `library`, and `function`. PR-URL: https://github.com/nodejs/node/pull/25093 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/env.h4
-rw-r--r--src/tls_wrap.cc38
2 files changed, 40 insertions, 2 deletions
diff --git a/src/env.h b/src/env.h
index 3b76259773..fbb64f48b5 100644
--- a/src/env.h
+++ b/src/env.h
@@ -183,6 +183,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(fingerprint_string, "fingerprint") \
V(flags_string, "flags") \
V(fragment_string, "fragment") \
+ V(function_string, "function") \
V(get_data_clone_error_string, "_getDataCloneError") \
V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId") \
V(gid_string, "gid") \
@@ -204,6 +205,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(issuercert_string, "issuerCertificate") \
V(kill_signal_string, "killSignal") \
V(kind_string, "kind") \
+ V(library_string, "library") \
V(mac_string, "mac") \
V(main_string, "main") \
V(max_buffer_string, "maxBuffer") \
@@ -313,7 +315,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(write_host_object_string, "_writeHostObject") \
V(write_queue_size_string, "writeQueueSize") \
V(x_forwarded_string, "x-forwarded-for") \
- V(zero_return_string, "ZERO_RETURN")
+ V(zero_return_string, "ZERO_RETURN") \
#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \
V(as_external, v8::External) \
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 3995c16d95..b5d6559355 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -41,6 +41,7 @@ using v8::Exception;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
+using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::ReadOnly;
@@ -347,15 +348,50 @@ Local<Value> TLSWrap::GetSSLError(int status, int* err, std::string* msg) {
{
CHECK(*err == SSL_ERROR_SSL || *err == SSL_ERROR_SYSCALL);
+ unsigned long ssl_err = ERR_peek_error(); // NOLINT(runtime/int)
BIO* bio = BIO_new(BIO_s_mem());
ERR_print_errors(bio);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
+ Isolate* isolate = env()->isolate();
+ Local<Context> context = isolate->GetCurrentContext();
+
Local<String> message =
- OneByteString(env()->isolate(), mem->data, mem->length);
+ OneByteString(isolate, mem->data, mem->length);
Local<Value> exception = Exception::Error(message);
+ Local<Object> obj = exception->ToObject(context).ToLocalChecked();
+
+ const char* ls = ERR_lib_error_string(ssl_err);
+ const char* fs = ERR_func_error_string(ssl_err);
+ const char* rs = ERR_reason_error_string(ssl_err);
+
+ if (ls != nullptr)
+ obj->Set(context, env()->library_string(),
+ OneByteString(isolate, ls)).FromJust();
+ if (fs != nullptr)
+ obj->Set(context, env()->function_string(),
+ OneByteString(isolate, fs)).FromJust();
+ if (rs != nullptr) {
+ obj->Set(context, env()->reason_string(),
+ OneByteString(isolate, rs)).FromJust();
+
+ // SSL has no API to recover the error name from the number, so we
+ // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
+ // which ends up being close to the original error macro name.
+ std::string code(rs);
+
+ for (auto& c : code) {
+ if (c == ' ')
+ c = '_';
+ else
+ c = ::toupper(c);
+ }
+ obj->Set(context, env()->code_string(),
+ OneByteString(isolate, ("ERR_SSL_" + code).c_str()))
+ .FromJust();
+ }
if (msg != nullptr)
msg->assign(mem->data, mem->data + mem->length);