[dart:io] validate path component of class Cookie
Bug: https://github.com/dart-lang/sdk/issues/42823
Change-Id: Icb9e0fa84404acfe5c6f3c98014dae4cd16edf2c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155843
Commit-Queue: Zichang Guo <zichangguo@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3325b41..c9eefa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@
* Adds `Abort` method to class `HttpClientRequest`, which allows users
to cancel outgoing HTTP requests and stop following IO operations.
+* A validtion check is added to `path` of class `Cookie`. Having characters
+ ranging from 0x00 to 0x1f and 0x3b (";") will lead to a `FormatException`.
#### `dart:typed_data`
diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart
index 73ed901..7d87b88 100644
--- a/sdk/lib/_http/http_headers.dart
+++ b/sdk/lib/_http/http_headers.dart
@@ -913,7 +913,7 @@
DateTime? expires;
int? maxAge;
String? domain;
- String? path;
+ String? _path;
bool httpOnly = false;
bool secure = false;
@@ -925,6 +925,13 @@
String get name => _name;
String get value => _value;
+ String? get path => _path;
+
+ set path(String? newPath) {
+ _validatePath(newPath);
+ _path = newPath;
+ }
+
set name(String newName) {
_validateName(newName);
_name = newName;
@@ -1104,4 +1111,19 @@
}
return newValue;
}
+
+ static void _validatePath(String? path) {
+ if (path == null) return;
+ for (int i = 0; i < path.length; i++) {
+ int codeUnit = path.codeUnitAt(i);
+ // According to RFC 6265, semicolon and controls should not occur in the
+ // path.
+ // path-value = <any CHAR except CTLs or ";">
+ // CTLs = %x00-1F / %x7F
+ if (codeUnit < 0x20 || codeUnit >= 0x7f || codeUnit == 0x3b /*;*/) {
+ throw FormatException(
+ "Invalid character in cookie path, code unit: '$codeUnit'");
+ }
+ }
+ }
}
diff --git a/tests/standalone/io/http_cookie_test.dart b/tests/standalone/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone/io/http_cookie_test.dart
+++ b/tests/standalone/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
}
+void testValidatePath() {
+ Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+ Expect.equals('/', cookie.path);
+ cookie.path = null;
+ Expect.throws<FormatException>(() {
+ cookie.path = "something; ";
+ }, (e) => e.toString().contains('Invalid character'));
+
+ StringBuffer buffer = StringBuffer();
+ buffer.writeCharCode(0x1f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x7f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x00);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+}
+
void main() {
testCookies();
testValidateCookieWithDoubleQuotes();
+ testValidatePath();
}
diff --git a/tests/standalone_2/io/http_cookie_test.dart b/tests/standalone_2/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone_2/io/http_cookie_test.dart
+++ b/tests/standalone_2/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
}
+void testValidatePath() {
+ Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+ Expect.equals('/', cookie.path);
+ cookie.path = null;
+ Expect.throws<FormatException>(() {
+ cookie.path = "something; ";
+ }, (e) => e.toString().contains('Invalid character'));
+
+ StringBuffer buffer = StringBuffer();
+ buffer.writeCharCode(0x1f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x7f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x00);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+}
+
void main() {
testCookies();
testValidateCookieWithDoubleQuotes();
+ testValidatePath();
}