Disallow invalid content-length.

Change-Id: I502c80f6d5914683622272cca37b5ba324f9262f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248840
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Brian Quinlan <bquinlan@google.com>
This commit is contained in:
Brian Quinlan 2022-07-19 00:44:33 +00:00 committed by Commit Bot
parent 5cc2856daa
commit 981bcf61c9
5 changed files with 62 additions and 2 deletions

View file

@ -26,6 +26,11 @@ Updated the Linter to `1.26.0`, which includes changes that
non-final variable.
- fix`use_build_context_synchronously` to handle `await`s in `if` conditions.
#### `dart:io`
- **Breaking Change** [#49305](https://github.com/dart-lang/sdk/issues/49305):
Disallow negative or hexadecimal content-length headers.
## 2.18.0
### Language

View file

@ -4,6 +4,8 @@
part of dart._http;
final _digitsValidator = RegExp(r"^\d+$");
class _HttpHeaders implements HttpHeaders {
final Map<String, List<String>> _headers;
// The original header names keyed by the lowercase header names.
@ -373,12 +375,18 @@ class _HttpHeaders implements HttpHeaders {
void _addContentLength(String name, value) {
if (value is int) {
contentLength = value;
if (value < 0) {
throw HttpException("Content-Length must contain only digits");
}
} else if (value is String) {
contentLength = int.parse(value);
if (!_digitsValidator.hasMatch(value)) {
throw HttpException("Content-Length must contain only digits");
}
value = int.parse(value);
} else {
throw HttpException("Unexpected type for header named $name");
}
contentLength = value;
}
void _addTransferEncoding(String name, value) {

View file

@ -6,6 +6,8 @@ import "dart:io";
import "package:expect/expect.dart";
// See also http_headers_test.dart.
Future<void> main() async {
final server = await HttpServer.bind("localhost", 0);
final request = await HttpClient().get("localhost", server.port, "/");

View file

@ -361,6 +361,48 @@ void testHeaderValue() {
Expect.equals("v; a=\"ø\"", HeaderValue("v", {"a": "ø"}).toString());
}
void testContentLength() {
// See also http_headers_content_length_test.dart.
var headers = new _HttpHeaders("1.1");
headers.set("content-length", ["256"]);
Expect.equals(256, headers.contentLength);
Expect.listEquals(["256"], headers["content-length"]!);
Expect.equals("256", headers.value("content-length"));
headers = new _HttpHeaders("1.1");
headers.set("content-length", [256]);
Expect.equals(256, headers.contentLength);
Expect.listEquals(["256"], headers["content-length"]!);
Expect.equals("256", headers.value("content-length"));
headers = new _HttpHeaders("1.1");
var e = Expect.throws<HttpException>(
() => headers.set("content-length", ["cat"]));
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
headers = new _HttpHeaders("1.1");
e = Expect.throws(
() => headers.set("content-length", ["-3"]), (e) => e is HttpException);
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
headers = new _HttpHeaders("1.1");
e = Expect.throws(
() => headers.set("content-length", [-3]), (e) => e is HttpException);
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
headers = new _HttpHeaders("1.1");
e = Expect.throws(
() => headers.set("content-length", [[]]), (e) => e is HttpException);
Expect.isTrue(
e.message.contains("Unexpected type for header named content-length"));
headers = new _HttpHeaders("1.1");
headers.set("content-length", ["1", "2"]);
Expect.equals(2, headers.contentLength);
Expect.listEquals(["2"], headers["content-length"]!);
Expect.equals("2", headers.value("content-length"));
}
void testContentType() {
void check(ContentType contentType, String primaryType, String subType,
[Map<String, String?>? parameters]) {
@ -743,6 +785,7 @@ main() {
testTransferEncoding();
testEnumeration();
testHeaderValue();
testContentLength();
testContentType();
testKnownContentTypes();
testContentTypeCache();

View file

@ -4,6 +4,8 @@
// @dart = 2.9
// See also http_headers_test.dart.
import "dart:io";
import "package:expect/expect.dart";