Signal error on duplicate SETTINGS identifiers.

See https://quicwg.org/base-drafts/draft-ietf-quic-http.html#frame-settings,
with proposed clarification at https://github.com/quicwg/base-drafts/pull/2979.

gfe-relnote: n/a, change to QUIC v99-only code.  Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 264857966
Change-Id: I6bcd0f70cb52d897d465fb89f9937ab4a3ea093f
diff --git a/quic/core/http/http_decoder.cc b/quic/core/http/http_decoder.cc
index 78f8539..c9519fe 100644
--- a/quic/core/http/http_decoder.cc
+++ b/quic/core/http/http_decoder.cc
@@ -565,7 +565,12 @@
                  "Unable to read settings frame content");
       return false;
     }
-    frame->values[id] = content;
+    auto result = frame->values.insert({id, content});
+    if (!result.second) {
+      // TODO(b/124216424): Use HTTP_SETTINGS_ERROR.
+      RaiseError(QUIC_INVALID_FRAME_DATA, "Duplicate SETTINGS identifier.");
+      return false;
+    }
   }
   return true;
 }
diff --git a/quic/core/http/http_decoder_test.cc b/quic/core/http/http_decoder_test.cc
index 12d96e8..6090cad 100644
--- a/quic/core/http/http_decoder_test.cc
+++ b/quic/core/http/http_decoder_test.cc
@@ -512,6 +512,25 @@
     EXPECT_EQ(test_data.error_message, decoder.error_detail());
   }
 }
+
+TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
+  std::string input =
+      "\x04"   // type (SETTINGS)
+      "\x04"   // length
+      "\x01"   // identifier
+      "\x01"   // content
+      "\x01"   // identifier
+      "\x02";  // content
+
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+
+  EXPECT_EQ(input.size(), ProcessInput(input));
+
+  EXPECT_EQ(QUIC_INVALID_FRAME_DATA, decoder_.error());
+  EXPECT_EQ("Duplicate SETTINGS identifier.", decoder_.error_detail());
+}
+
 TEST_F(HttpDecoderTest, DataFrame) {
   InSequence s;
   std::string input(