Skip to content

Commit

Permalink
http: disable chunked encoding when OBS fold is used (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShogunPanda authored Sep 23, 2022
1 parent f014c23 commit 181e700
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "llhttp",
"version": "2.1.5",
"version": "2.1.6",
"description": "HTTP parser in LLVM IR",
"main": "lib/llhttp.js",
"types": "lib/llhttp.d.ts",
Expand Down
12 changes: 9 additions & 3 deletions src/llhttp/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@ export class HTTP {
n('header_value_discard_ws')
.match([ ' ', '\t' ], n('header_value_discard_ws'))
.match('\r', n('header_value_discard_ws_almost_done'))
.match('\n', n('header_value_discard_lws'))
.match('\n', this.testFlags(FLAGS.LENIENT, {
1: n('header_value_discard_lws'),
}, p.error(ERROR.INVALID_HEADER_TOKEN, 'Invalid header value char')))
.otherwise(span.headerValue.start(n('header_value_start')));

if (this.mode === 'strict') {
Expand Down Expand Up @@ -570,7 +572,7 @@ export class HTTP {

const checkLenient = this.testFlags(FLAGS.LENIENT, {
1: n('header_value_lenient'),
}, n('header_value_lenient_failed'));
}, span.headerValue.end(p.error(ERROR.INVALID_HEADER_TOKEN, 'Invalid header value char')));

n('header_value_otherwise')
.peek('\r', span.headerValue.end().skipTo(n('header_value_almost_done')))
Expand All @@ -593,7 +595,11 @@ export class HTTP {
'Missing expected LF after header value'));

n('header_value_lws')
.peek([ ' ', '\t' ], span.headerValue.start(n('header_value_start')))
.peek([ ' ', '\t' ],
this.load('header_state', {
[HEADER_STATE.TRANSFER_ENCODING_CHUNKED]:
this.resetHeaderState(span.headerValue.start(n('header_value_start'))),
}, span.headerValue.start(n('header_value_start'))))
.otherwise(this.setHeaderFlags('header_field_start'));

const checkTrailing = this.testFlags(FLAGS.TRAILING, {
Expand Down
49 changes: 48 additions & 1 deletion test/request/invalid.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,53 @@ off=21 len=1 span[header_value]="1"
off=23 error code=3 reason="Missing expected LF after header value"
```

### Headers separated by LF

<!-- meta={"type": "request"} -->
```http
POST / HTTP/1.1
Host: localhost:5000
x:x\nTransfer-Encoding: chunked
1
A
0
```

```log
off=0 message begin
off=5 len=1 span[url]="/"
off=17 len=4 span[header_field]="Host"
off=23 len=14 span[header_value]="localhost:5000"
off=39 len=1 span[header_field]="x"
off=41 len=1 span[header_value]="x"
off=42 error code=10 reason="Invalid header value char"
```

### Empty headers separated by LF

<!-- meta={"type": "request"} -->
```http
POST / HTTP/1.1
Host: localhost:5000
x:\nTransfer-Encoding: chunked
1
A
0
```

```log
off=0 message begin
off=5 len=1 span[url]="/"
off=17 len=4 span[header_field]="Host"
off=23 len=14 span[header_value]="localhost:5000"
off=39 len=1 span[header_field]="x"
off=42 error code=10 reason="Invalid header value char"
```

### Invalid header token #1

<!-- meta={"type": "request", "noScan": true} -->
Expand Down Expand Up @@ -174,5 +221,5 @@ off=16 len=4 span[header_field]="Host"
off=22 len=9 span[header_value]="localhost"
off=33 len=5 span[header_field]="Dummy"
off=40 len=1 span[header_value]="x"
off=42 error code=25 reason="Missing expected CR after header value"
off=41 error code=10 reason="Invalid header value char"
```
1 change: 1 addition & 0 deletions test/request/lenient.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,6 @@ Header1: \f
off=0 message begin
off=4 len=4 span[url]="/url"
off=19 len=7 span[header_field]="Header1"
off=28 len=0 span[header_value]=""
off=28 error code=10 reason="Invalid header value char"
```
2 changes: 1 addition & 1 deletion test/request/sample.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ off=0 message begin
off=4 len=1 span[url]="/"
off=15 len=5 span[header_field]="Line1"
off=24 len=3 span[header_value]="abc"
off=28 error code=25 reason="Missing expected CR after header value"
off=27 error code=10 reason="Invalid header value char"
```

## Request starting with CRLF
Expand Down
25 changes: 25 additions & 0 deletions test/request/transfer-encoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,28 @@ off=38 len=7 span[header_value]="chunked"
off=49 headers complete method=4 v=1/1 flags=208 content_length=0
off=51 error code=2 reason="Invalid character in chunk parameters"
```

## Invalid OBS fold after chunked value

<!-- meta={"type": "request", "mode": "strict"} -->
```http
PUT /url HTTP/1.1
Transfer-Encoding: chunked
abc
5
World
0
```

```log
off=0 message begin
off=4 len=4 span[url]="/url"
off=19 len=17 span[header_field]="Transfer-Encoding"
off=38 len=7 span[header_value]="chunked"
off=47 len=5 span[header_value]=" abc"
off=56 headers complete method=4 v=1/1 flags=200 content_length=0
off=56 error code=15 reason="Request has invalid `Transfer-Encoding`"
```
2 changes: 1 addition & 1 deletion test/response/sample.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ off=0 message begin
off=13 len=2 span[status]="OK"
off=16 len=12 span[header_field]="Content-Type"
off=30 len=24 span[header_value]="text/html; charset=utf-8"
off=55 error code=25 reason="Missing expected CR after header value"
off=54 error code=10 reason="Invalid header value char"
```

## Underscore in header key
Expand Down
38 changes: 37 additions & 1 deletion test/response/transfer-encoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,40 @@ off=75 len=1 span[body]=cr
off=76 len=1 span[body]=lf
off=77 len=1 span[body]=cr
off=78 len=1 span[body]=lf
```
```

## Invalid OBS fold after chunked value

<!-- meta={"type": "response" } -->
```http
HTTP/1.1 200 OK
Transfer-Encoding: chunked
abc
5
World
0
```

```log
off=0 message begin
off=13 len=2 span[status]="OK"
off=17 len=17 span[header_field]="Transfer-Encoding"
off=36 len=7 span[header_value]="chunked"
off=45 len=5 span[header_value]=" abc"
off=54 headers complete status=200 v=1/1 flags=200 content_length=0
off=54 len=1 span[body]="5"
off=55 len=1 span[body]=cr
off=56 len=1 span[body]=lf
off=57 len=5 span[body]="World"
off=62 len=1 span[body]=cr
off=63 len=1 span[body]=lf
off=64 len=1 span[body]="0"
off=65 len=1 span[body]=cr
off=66 len=1 span[body]=lf
off=67 len=1 span[body]=cr
off=68 len=1 span[body]=lf
```

0 comments on commit 181e700

Please sign in to comment.