Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c6e6405

Browse files
lrhnCommit Queue
authored and
Commit Queue
committed
Fix bug in HTTP header parameter value parsing.
The `preserveBackslash` flag should preserve backslashes before any non-`"` character, not before any non-`\` character. Change-Id: I3270f3b1b6c678e712e27a1cf4557558c883610b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/452781 Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Ivan Inozemtsev <iinozemtsev@google.com> Reviewed-by: Ivan Inozemtsev <iinozemtsev@google.com>
1 parent d4036a7 commit c6e6405

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

‎sdk/lib/_http/http_headers.dart‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ class _HeaderValue implements HeaderValue {
851851
if (index < source.length) {
852852
char = source.codeUnitAt(index);
853853
index++;
854-
if (preserveBackslash && char != _CharCode.BACKSLASH) {
854+
if (preserveBackslash && char != _CharCode.QUOTE) {
855855
sb.writeCharCode(_CharCode.BACKSLASH);
856856
}
857857
sb.writeCharCode(char);

‎tests/standalone/io/http_headers_test.dart‎

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,65 @@ void testForEach() {
820820
Expect.equals(4, totalValues);
821821
}
822822

823-
main() {
823+
void testPreserveBackslash() {
824+
// The `preserveBackslash` parameter of `HttpValue.parse` makes `\`s in
825+
// property values be retained, except if before a `"`.
826+
// (Is only allowed inside a `"..."`-quoted value.?)
827+
final _backslashRE = RegExp(r'\\.');
828+
829+
// Preserves every `\` escaping a non-`"` character.
830+
String preserve(Match m) {
831+
// Preserve entire `\.` match unless `.` is `"`.
832+
if (!m.input.startsWith('"', m.start + 1)) return m[0]!;
833+
return '"';
834+
}
835+
836+
// Preserves no escaping `\`.
837+
String remove(Match m) => m.input[m.start + 1];
838+
839+
for (var preserveBackslash in [false, true]) {
840+
void testInput(String input) {
841+
var headerValue = HeaderValue.parse(
842+
'value; name="$input"',
843+
preserveBackslash: preserveBackslash,
844+
);
845+
Expect.stringEquals(
846+
input.replaceAllMapped(
847+
_backslashRE,
848+
preserveBackslash ? preserve : remove,
849+
),
850+
headerValue.parameters['name']!,
851+
"$input (${preserveBackslash ? "preserved" : "removed"})",
852+
);
853+
}
854+
855+
testInput(r'\\');
856+
testInput(r'\"');
857+
testInput(r'\ ');
858+
testInput(r'text\ \a\"text');
859+
testInput(r'text\"\\\"');
860+
testInput(r'\"; abc=\\\"');
861+
862+
// An escaping `\` cannot be last character of an input.
863+
Expect.throws(
864+
() => HeaderValue.parse(r'value; name="abc\"'),
865+
null,
866+
"Trailing backslash (${preserveBackslash ? "preserved" : "removed"})",
867+
);
868+
869+
// Unquoted values do not treat backslash as escape,
870+
// and ignore `preserveBackslash`. Backslash is just a another valid
871+
// character and can occur anywhere until a terminator character.
872+
var input = r'abc\"\de\';
873+
Expect.stringEquals(
874+
input,
875+
HeaderValue.parse('value; name=$input').parameters['name']!,
876+
"Escaping in unquoted value (${preserveBackslash ? "preserved" : "removed"})",
877+
);
878+
}
879+
}
880+
881+
void main() {
824882
testMultiValue();
825883
testDate();
826884
testExpires();
@@ -843,4 +901,5 @@ main() {
843901
testLowercaseAdd();
844902
testLowercaseSet();
845903
testForEach();
904+
testPreserveBackslash();
846905
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /