Skip to content

Commit 741c5ef

Browse files
mscdexBethGriggs
authored andcommitted
http: fix error check in Execute()
Refs: #24738 Fixes: #25858 PR-URL: #25863 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent fe0e119 commit 741c5ef

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

src/node_http_parser.cc

+28-2
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,28 @@ class Parser : public AsyncWrap, public StreamListener {
605605
size_t nparsed =
606606
http_parser_execute(&parser_, &settings, data, len);
607607

608-
Save();
608+
enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
609+
610+
// Finish()
611+
if (data == nullptr) {
612+
// `http_parser_execute()` returns either `0` or `1` when `len` is 0
613+
// (part of the finishing sequence).
614+
CHECK_EQ(len, 0);
615+
switch (nparsed) {
616+
case 0:
617+
err = HPE_OK;
618+
break;
619+
case 1:
620+
nparsed = 0;
621+
break;
622+
default:
623+
UNREACHABLE();
624+
}
625+
626+
// Regular Execute()
627+
} else {
628+
Save();
629+
}
609630

610631
// Unassign the 'buffer_' variable
611632
current_buffer_.Clear();
@@ -619,7 +640,7 @@ class Parser : public AsyncWrap, public StreamListener {
619640
Local<Integer> nparsed_obj = Integer::New(env()->isolate(), nparsed);
620641
// If there was a parse error in one of the callbacks
621642
// TODO(bnoordhuis) What if there is an error on EOF?
622-
if (!parser_.upgrade && nparsed != len) {
643+
if (!parser_.upgrade && err != HPE_OK) {
623644
enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
624645

625646
Local<Value> e = Exception::Error(env()->parse_error_string());
@@ -631,6 +652,11 @@ class Parser : public AsyncWrap, public StreamListener {
631652

632653
return scope.Escape(e);
633654
}
655+
656+
// No return value is needed for `Finish()`
657+
if (data == nullptr) {
658+
return scope.Escape(Local<Value>());
659+
}
634660
return scope.Escape(nparsed_obj);
635661
}
636662

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
require('../common');
3+
const common = require('../common');
44
const assert = require('assert');
55
const { spawnSync } = require('child_process');
66
const http = require('http');
@@ -9,3 +9,16 @@ assert.strictEqual(http.maxHeaderSize, 8 * 1024);
99
const child = spawnSync(process.execPath, ['--max-http-header-size=10', '-p',
1010
'http.maxHeaderSize']);
1111
assert.strictEqual(+child.stdout.toString().trim(), 10);
12+
13+
{
14+
const server = http.createServer(common.mustNotCall());
15+
server.listen(0, common.mustCall(() => {
16+
http.get({
17+
port: server.address().port,
18+
headers: { foo: 'x'.repeat(http.maxHeaderSize + 1) }
19+
}, common.mustCall((res) => {
20+
assert.strictEqual(res.statusCode, 400);
21+
server.close();
22+
}));
23+
}));
24+
}

0 commit comments

Comments
 (0)