Skip to content

Commit 981bcf6

Browse files
brianquinlanCommit Bot
authored and
Commit Bot
committed
Disallow invalid content-length.
Change-Id: I502c80f6d5914683622272cca37b5ba324f9262f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248840 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Brian Quinlan <[email protected]>
1 parent 5cc2856 commit 981bcf6

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ Updated the Linter to `1.26.0`, which includes changes that
2626
non-final variable.
2727
- fix`use_build_context_synchronously` to handle `await`s in `if` conditions.
2828

29+
#### `dart:io`
30+
31+
- **Breaking Change** [#49305](https://github.com/dart-lang/sdk/issues/49305):
32+
Disallow negative or hexadecimal content-length headers.
33+
2934
## 2.18.0
3035

3136
### Language

sdk/lib/_http/http_headers.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
part of dart._http;
66

7+
final _digitsValidator = RegExp(r"^\d+$");
8+
79
class _HttpHeaders implements HttpHeaders {
810
final Map<String, List<String>> _headers;
911
// The original header names keyed by the lowercase header names.
@@ -373,12 +375,18 @@ class _HttpHeaders implements HttpHeaders {
373375

374376
void _addContentLength(String name, value) {
375377
if (value is int) {
376-
contentLength = value;
378+
if (value < 0) {
379+
throw HttpException("Content-Length must contain only digits");
380+
}
377381
} else if (value is String) {
378-
contentLength = int.parse(value);
382+
if (!_digitsValidator.hasMatch(value)) {
383+
throw HttpException("Content-Length must contain only digits");
384+
}
385+
value = int.parse(value);
379386
} else {
380387
throw HttpException("Unexpected type for header named $name");
381388
}
389+
contentLength = value;
382390
}
383391

384392
void _addTransferEncoding(String name, value) {

tests/standalone/io/http_headers_content_length_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import "dart:io";
66

77
import "package:expect/expect.dart";
88

9+
// See also http_headers_test.dart.
10+
911
Future<void> main() async {
1012
final server = await HttpServer.bind("localhost", 0);
1113
final request = await HttpClient().get("localhost", server.port, "/");

tests/standalone/io/http_headers_test.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,48 @@ void testHeaderValue() {
361361
Expect.equals("v; a=\"ø\"", HeaderValue("v", {"a": "ø"}).toString());
362362
}
363363

364+
void testContentLength() {
365+
// See also http_headers_content_length_test.dart.
366+
var headers = new _HttpHeaders("1.1");
367+
headers.set("content-length", ["256"]);
368+
Expect.equals(256, headers.contentLength);
369+
Expect.listEquals(["256"], headers["content-length"]!);
370+
Expect.equals("256", headers.value("content-length"));
371+
372+
headers = new _HttpHeaders("1.1");
373+
headers.set("content-length", [256]);
374+
Expect.equals(256, headers.contentLength);
375+
Expect.listEquals(["256"], headers["content-length"]!);
376+
Expect.equals("256", headers.value("content-length"));
377+
378+
headers = new _HttpHeaders("1.1");
379+
var e = Expect.throws<HttpException>(
380+
() => headers.set("content-length", ["cat"]));
381+
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
382+
383+
headers = new _HttpHeaders("1.1");
384+
e = Expect.throws(
385+
() => headers.set("content-length", ["-3"]), (e) => e is HttpException);
386+
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
387+
388+
headers = new _HttpHeaders("1.1");
389+
e = Expect.throws(
390+
() => headers.set("content-length", [-3]), (e) => e is HttpException);
391+
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
392+
393+
headers = new _HttpHeaders("1.1");
394+
e = Expect.throws(
395+
() => headers.set("content-length", [[]]), (e) => e is HttpException);
396+
Expect.isTrue(
397+
e.message.contains("Unexpected type for header named content-length"));
398+
399+
headers = new _HttpHeaders("1.1");
400+
headers.set("content-length", ["1", "2"]);
401+
Expect.equals(2, headers.contentLength);
402+
Expect.listEquals(["2"], headers["content-length"]!);
403+
Expect.equals("2", headers.value("content-length"));
404+
}
405+
364406
void testContentType() {
365407
void check(ContentType contentType, String primaryType, String subType,
366408
[Map<String, String?>? parameters]) {
@@ -743,6 +785,7 @@ main() {
743785
testTransferEncoding();
744786
testEnumeration();
745787
testHeaderValue();
788+
testContentLength();
746789
testContentType();
747790
testKnownContentTypes();
748791
testContentTypeCache();

tests/standalone_2/io/http_headers_content_length_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
// @dart = 2.9
66

7+
// See also http_headers_test.dart.
8+
79
import "dart:io";
810

911
import "package:expect/expect.dart";

0 commit comments

Comments
 (0)