[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>
This commit is contained in:
Zichang Guo 2020-08-22 00:30:01 +00:00 committed by commit-bot@chromium.org
parent afd6344e99
commit c9b4f1b5d5
4 changed files with 81 additions and 1 deletions

View file

@ -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`

View file

@ -913,7 +913,7 @@ class _Cookie implements Cookie {
DateTime? expires;
int? maxAge;
String? domain;
String? path;
String? _path;
bool httpOnly = false;
bool secure = false;
@ -925,6 +925,13 @@ class _Cookie implements Cookie {
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 @@ class _Cookie implements Cookie {
}
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'");
}
}
}
}

View file

@ -83,7 +83,35 @@ void testValidateCookieWithDoubleQuotes() {
() => 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();
}

View file

@ -83,7 +83,35 @@ void testValidateCookieWithDoubleQuotes() {
() => 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();
}