diff --git a/src/llhttp/http.ts b/src/llhttp/http.ts index d05719c3..f6a186bf 100644 --- a/src/llhttp/http.ts +++ b/src/llhttp/http.ts @@ -33,7 +33,9 @@ const NODES: ReadonlyArray = [ 'res_http_minor', 'res_http_end', 'res_after_version', - 'res_status_code', + 'res_status_code_digit_1', + 'res_status_code_digit_2', + 'res_status_code_digit_3', 'res_status_code_otherwise', 'res_status_start', 'res_status', @@ -334,16 +336,30 @@ export class HTTP { )); n('res_after_version') - .match(' ', this.update('status_code', 0, 'res_status_code')) + .match(' ', this.update('status_code', 0, 'res_status_code_digit_1')) .otherwise(p.error(ERROR.INVALID_VERSION, 'Expected space after version')); - n('res_status_code') + n('res_status_code_digit_1') .select(NUM_MAP, this.mulAdd('status_code', { - overflow: p.error(ERROR.INVALID_STATUS, 'Response overflow'), - success: 'res_status_code', - }, { base: 10, signed: false, max: 999 })) - .otherwise(n('res_status_code_otherwise')); + overflow: p.error(ERROR.INVALID_STATUS, 'Invalid status code'), + success: 'res_status_code_digit_2', + })) + .otherwise(p.error(ERROR.INVALID_STATUS, 'Invalid status code')); + + n('res_status_code_digit_2') + .select(NUM_MAP, this.mulAdd('status_code', { + overflow: p.error(ERROR.INVALID_STATUS, 'Invalid status code'), + success: 'res_status_code_digit_3', + })) + .otherwise(p.error(ERROR.INVALID_STATUS, 'Invalid status code')); + + n('res_status_code_digit_3') + .select(NUM_MAP, this.mulAdd('status_code', { + overflow: p.error(ERROR.INVALID_STATUS, 'Invalid status code'), + success: 'res_status_code_otherwise', + })) + .otherwise(p.error(ERROR.INVALID_STATUS, 'Invalid status code')); n('res_status_code_otherwise') .match(' ', n('res_status_start')) diff --git a/test/response/invalid.md b/test/response/invalid.md index 9ddc3fa9..40eee9b1 100644 --- a/test/response/invalid.md +++ b/test/response/invalid.md @@ -148,4 +148,54 @@ off=8 version complete off=13 len=2 span[status]="OK" off=17 status complete off=18 error code=30 reason="Unexpected space after start line" +``` + +### Extra space between HTTP version and status code + + +```http +HTTP/1.1 200 OK + + +``` + +```log +off=0 message begin +off=5 len=3 span[version]="1.1" +off=8 version complete +off=9 error code=13 reason="Invalid status code" +``` + +### Extra space between status code and reason + + +```http +HTTP/1.1 200 OK + + +``` + +```log +off=0 message begin +off=5 len=3 span[version]="1.1" +off=8 version complete +off=13 len=3 span[status]=" OK" +off=18 status complete +off=20 headers complete status=200 v=1/1 flags=0 content_length=0 +``` + +### One-digit status code + + +```http +HTTP/1.1 2 OK + + +``` + +```log +off=0 message begin +off=5 len=3 span[version]="1.1" +off=8 version complete +off=10 error code=13 reason="Invalid status code" ``` \ No newline at end of file