Skip to content

Commit d6fbd81

Browse files
indutnyrvagg
authored andcommitted
tls_wrap: reach error reporting for UV_EPROTO
Do not swallow error details when reporting UV_EPROTO asynchronously, and when creating artificial errors. Fix: #3692 PR-URL: #4885 Reviewed-By: Shigeki Ohtsu <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent f7ed473 commit d6fbd81

File tree

5 files changed

+55
-11
lines changed

5 files changed

+55
-11
lines changed

lib/net.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ function afterWrite(status, handle, req, err) {
760760
}
761761

762762
if (status < 0) {
763-
var ex = exceptionWithHostPort(status, 'write', req.address, req.port);
763+
var ex = errnoException(status, 'write', req.error);
764764
debug('write failure', ex);
765765
self._destroy(ex, req.cb);
766766
return;

src/stream_base.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@ class StreamReq {
2222
explicit StreamReq(DoneCb cb) : cb_(cb) {
2323
}
2424

25-
inline void Done(int status) {
26-
cb_(static_cast<Req*>(this), status);
25+
inline void Done(int status, const char* error_str = nullptr) {
26+
Req* req = static_cast<Req*>(this);
27+
Environment* env = req->env();
28+
if (error_str != nullptr) {
29+
req->object()->Set(env->error_string(),
30+
OneByteString(env->isolate(), error_str));
31+
}
32+
33+
cb_(req, status);
2734
}
2835

2936
private:

src/tls_wrap.cc

+15-7
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ void TLSWrap::MakePending() {
9292
}
9393

9494

95-
bool TLSWrap::InvokeQueued(int status) {
95+
bool TLSWrap::InvokeQueued(int status, const char* error_str) {
9696
if (pending_write_items_.IsEmpty())
9797
return false;
9898

9999
// Process old queue
100100
WriteItemList queue;
101101
pending_write_items_.MoveBack(&queue);
102102
while (WriteItem* wi = queue.PopFront()) {
103-
wi->w_->Done(status);
103+
wi->w_->Done(status, error_str);
104104
delete wi;
105105
}
106106

@@ -484,11 +484,12 @@ bool TLSWrap::ClearIn() {
484484

485485
// Error or partial write
486486
int err;
487-
Local<Value> arg = GetSSLError(written, &err, &error_);
487+
const char* error_str = nullptr;
488+
Local<Value> arg = GetSSLError(written, &err, &error_str);
488489
if (!arg.IsEmpty()) {
489490
MakePending();
490-
if (!InvokeQueued(UV_EPROTO))
491-
ClearError();
491+
InvokeQueued(UV_EPROTO, error_str);
492+
delete[] error_str;
492493
clear_in_->Reset();
493494
}
494495

@@ -589,8 +590,15 @@ int TLSWrap::DoWrite(WriteWrap* w,
589590
return 0;
590591
}
591592

592-
if (ssl_ == nullptr)
593+
if (ssl_ == nullptr) {
594+
ClearError();
595+
596+
static char msg[] = "Write after DestroySSL";
597+
char* tmp = new char[sizeof(msg)];
598+
memcpy(tmp, msg, sizeof(msg));
599+
error_ = tmp;
593600
return UV_EPROTO;
601+
}
594602

595603
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
596604

@@ -775,7 +783,7 @@ void TLSWrap::DestroySSL(const FunctionCallbackInfo<Value>& args) {
775783
wrap->MakePending();
776784

777785
// And destroy
778-
wrap->InvokeQueued(UV_ECANCELED);
786+
wrap->InvokeQueued(UV_ECANCELED, "Canceled because of SSL destruction");
779787

780788
// Destroy the SSL structure and friends
781789
wrap->SSLWrap<TLSWrap>::DestroySSL();

src/tls_wrap.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class TLSWrap : public AsyncWrap,
8989
bool ClearIn();
9090
void ClearOut();
9191
void MakePending();
92-
bool InvokeQueued(int status);
92+
bool InvokeQueued(int status, const char* error_str = nullptr);
9393

9494
inline void Cycle() {
9595
// Prevent recursion

test/parallel/test-tls-junk-server.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
if (!common.hasCrypto) {
5+
console.log('1..0 # Skipped: missing crypto');
6+
return;
7+
}
8+
9+
const assert = require('assert');
10+
const https = require('https');
11+
const net = require('net');
12+
13+
const server = net.createServer(function(s) {
14+
s.once('data', function() {
15+
s.end('I was waiting for you, hello!', function() {
16+
s.destroy();
17+
});
18+
});
19+
});
20+
21+
server.listen(common.PORT, function() {
22+
const req = https.request({ port: common.PORT });
23+
req.end();
24+
25+
req.once('error', common.mustCall(function(err) {
26+
assert(/unknown protocol/.test(err.message));
27+
server.close();
28+
}));
29+
});

0 commit comments

Comments
 (0)