Tighten content-length header parsing in shared spdy code, not flag protected

This CL is to fix crbug.com/596576.

PiperOrigin-RevId: 325516552
Change-Id: I64dc8c9127b6b40b959172fd0c42bb6697899098
diff --git a/quic/core/http/spdy_utils.cc b/quic/core/http/spdy_utils.cc
index 98d22cb..69dd3d0 100644
--- a/quic/core/http/spdy_utils.cc
+++ b/quic/core/http/spdy_utils.cc
@@ -34,7 +34,8 @@
         quiche::QuicheTextUtils::Split(content_length_header, '\0');
     for (const quiche::QuicheStringPiece& value : values) {
       uint64_t new_value;
-      if (!quiche::QuicheTextUtils::StringToUint64(value, &new_value)) {
+      if (!quiche::QuicheTextUtils::StringToUint64(value, &new_value) ||
+          !quiche::QuicheTextUtils::IsAllDigits(value)) {
         QUIC_DLOG(ERROR)
             << "Content length was either unparseable or negative.";
         return false;
diff --git a/quic/core/http/spdy_utils_test.cc b/quic/core/http/spdy_utils_test.cc
index 55d4706..dd8079e 100644
--- a/quic/core/http/spdy_utils_test.cc
+++ b/quic/core/http/spdy_utils_test.cc
@@ -141,6 +141,20 @@
   EXPECT_EQ(9000000000, content_length);
 }
 
+TEST_F(CopyAndValidateHeaders, NonDigitContentLength) {
+  // Section 3.3.2 of RFC 7230 defines content-length as being only digits.
+  // Number parsers might accept symbols like a leading plus; test that this
+  // fails to parse.
+  auto headers = FromList({{"content-length", "+123"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
 TEST_F(CopyAndValidateHeaders, MultipleValues) {
   auto headers = FromList({{"foo", "foovalue"},
                            {"bar", "barvalue"},