Browse Source

chore: cherry-pick 4d26949260aa from chromium (#33675)

* chore: cherry-pick 4d26949260aa from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <[email protected]>
Pedro Pontes 3 years ago
parent
commit
b12d8a358d
2 changed files with 155 additions and 0 deletions
  1. 1 0
      patches/chromium/.patches
  2. 154 0
      patches/chromium/cherry-pick-4d26949260aa.patch

+ 1 - 0
patches/chromium/.patches

@@ -138,6 +138,7 @@ enable_forcesynchronoushtmlparsing_by_default.patch
 remove_incorrect_width_height_adjustments.patch
 set_dpi_correctly_during_main_window_creation.patch
 use_numpy_1_2x_supported_1_for_vpython.patch
+cherry-pick-4d26949260aa.patch
 cherry-pick-1665a1d16d46.patch
 use-after-free_of_id_and_idref_attributes.patch
 fix_--without-valid_build.patch

+ 154 - 0
patches/chromium/cherry-pick-4d26949260aa.patch

@@ -0,0 +1,154 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Yutaka Hirano <[email protected]>
+Date: Fri, 4 Feb 2022 10:16:05 +0000
+Subject: Don't interpret informational response body as HTTP/0.9 response
+
+An informational (1xx) response with body can be interpreted as an
+informational response followed by an HTTP/0.9 response. It is confusing
+so let's stop doing that.
+
+Bug: 1291482
+Change-Id: Ic3823838614330d761f11360a783859e5baa260e
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428433
+Reviewed-by: Matt Menke <[email protected]>
+Reviewed-by: Kenichi Ishibashi <[email protected]>
+Reviewed-by: Mike West <[email protected]>
+Commit-Queue: Yutaka Hirano <[email protected]>
+Cr-Commit-Position: refs/heads/main@{#967169}
+
+diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
+index 8fe9a4e507aa5b081af4b48fe80ee38275dee84e..8ec7bbc1ed065b84afd22a4223e2359344876c47 100644
+--- a/net/http/http_stream_parser.cc
++++ b/net/http/http_stream_parser.cc
+@@ -1013,15 +1013,23 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) {
+         base::StringPiece(read_buf_->StartOfBuffer(), end_offset));
+     if (!headers)
+       return net::ERR_INVALID_HTTP_RESPONSE;
++    has_seen_status_line_ = true;
+   } else {
+     // Enough data was read -- there is no status line, so this is HTTP/0.9, or
+     // the server is broken / doesn't speak HTTP.
+ 
+-    // If the port is not the default for the scheme, assume it's not a real
+-    // HTTP/0.9 response, and fail the request.
++    if (has_seen_status_line_) {
++      // If we saw a status line previously, the server can speak HTTP/1.x so it
++      // is not reasonable to interpret the response as an HTTP/0.9 response.
++      return ERR_INVALID_HTTP_RESPONSE;
++    }
++
+     base::StringPiece scheme = request_->url.scheme_piece();
+     if (url::DefaultPortForScheme(scheme.data(), scheme.length()) !=
+         request_->url.EffectiveIntPort()) {
++      // If the port is not the default for the scheme, assume it's not a real
++      // HTTP/0.9 response, and fail the request.
++
+       // Allow Shoutcast responses over HTTP, as it's somewhat common and relies
+       // on HTTP/0.9 on weird ports to work.
+       // See
+diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
+index 6141af9a4d3500e7821f1b43ef536bc130eaf9f0..064bde38a206722f39aa035f2fabb86cdfc1a23f 100644
+--- a/net/http/http_stream_parser.h
++++ b/net/http/http_stream_parser.h
+@@ -275,6 +275,11 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
+   // True if reading a keep-alive response. False if not, or if don't yet know.
+   bool response_is_keep_alive_;
+ 
++  // True if we've seen a response that has an HTTP status line. This is
++  // persistent across multiple response parsing. If we see a status line
++  // for a response, this will remain true forever.
++  bool has_seen_status_line_ = false;
++
+   // Keep track of the number of response body bytes read so far.
+   int64_t response_body_read_;
+ 
+diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
+index 3a394e629874d8ffff6eec02609e6009571a6733..e25b78539dfec4b27e6ddf2052967cab91141770 100644
+--- a/net/http/http_stream_parser_unittest.cc
++++ b/net/http/http_stream_parser_unittest.cc
+@@ -1399,6 +1399,25 @@ TEST(HttpStreamParser, Http09PortTests) {
+   }
+ }
+ 
++TEST(HttpStreamParser, ContinueWithBody) {
++  const std::string kResponse =
++      "HTTP/1.1 100 Continue\r\n\r\nhello\r\nworld\r\n";
++
++  SimpleGetRunner get_runner;
++  get_runner.set_url(GURL("http://foo.com/"));
++  get_runner.AddRead(kResponse);
++  get_runner.SetupParserAndSendRequest();
++
++  get_runner.ReadHeadersExpectingError(OK);
++  ASSERT_TRUE(get_runner.response_info()->headers);
++  EXPECT_EQ("HTTP/1.1 100 Continue",
++            get_runner.response_info()->headers->GetStatusLine());
++
++  // We ignore informational responses and start reading the next response in
++  // the stream. This simulates the behavior.
++  get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE);
++}
++
+ TEST(HttpStreamParser, NullFails) {
+   const char kTestHeaders[] =
+       "HTTP/1.1 200 OK\r\n"
+diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
+new file mode 100644
+index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
+--- /dev/null
++++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
+@@ -0,0 +1,7 @@
++This is a testharness.js-based test.
++PASS Status(100) should be ignored.
++FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
++PASS Status(103) should be ignored.
++PASS Status(199) should be ignored.
++Harness: the test ran to completion.
++
+diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
+new file mode 100644
+index 0000000000000000000000000000000000000000..df4dafcd80b38af93b688dcb318cfaf1978a939f
+--- /dev/null
++++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
+@@ -0,0 +1,28 @@
++promise_test(async (t) => {
++  // The 100 response should be ignored, then the transaction ends, which
++  // should lead to an error.
++  await promise_rejects_js(
++    t, TypeError, fetch('/common/text-plain.txt?pipe=status(100)'));
++}, 'Status(100) should be ignored.');
++
++// This behavior is being discussed at https://github.com/whatwg/fetch/issues/1397.
++promise_test(async (t) => {
++  const res = await fetch('/common/text-plain.txt?pipe=status(101)');
++  assert_equals(res.status, 101);
++  const body = await res.text();
++  assert_equals(body, '');
++}, 'Status(101) should be accepted, with removing body.');
++
++promise_test(async (t) => {
++  // The 103 response should be ignored, then the transaction ends, which
++  // should lead to an error.
++  await promise_rejects_js(
++     t, TypeError, fetch('/common/text-plain.txt?pipe=status(103)'));
++}, 'Status(103) should be ignored.');
++
++promise_test(async (t) => {
++  // The 199 response should be ignored, then the transaction ends, which
++  // should lead to an error.
++  await promise_rejects_js(
++    t, TypeError, fetch('/common/text-plain.txt?pipe=status(199)'));
++}, 'Status(199) should be ignored.');
+diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
+new file mode 100644
+index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
+--- /dev/null
++++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
+@@ -0,0 +1,7 @@
++This is a testharness.js-based test.
++PASS Status(100) should be ignored.
++FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
++PASS Status(103) should be ignored.
++PASS Status(199) should be ignored.
++Harness: the test ran to completion.
++