Guard against integer overflow when decoding QUIC receive timestamp deltas

This makes sure that the decoded delta itself does not overflow; we might want to limit the size of the deltas after that (so that the timestamp math does not overflow) too, but that's an issue for a separate CL.

PiperOrigin-RevId: 983989890
diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc
index 5884abe..4ff9171 100644
--- a/quiche/quic/core/quic_framer.cc
+++ b/quiche/quic/core/quic_framer.cc
@@ -3898,9 +3898,18 @@
         set_detailed_error("Unable to read receive timestamp delta.");
         return false;
       }
+      // The IETF draft does not allow exponents above 20; this ensures that the
+      // bitshifts below are always valid.
+      QUICHE_DCHECK_LE(local_receive_timestamps_exponent_, 20u);
       // The first timestamp delta is relative to framer creation time; whereas
       // subsequent deltas are relative to the previous delta in decreasing
       // packet order.
+      if (timestamp_delta >
+          (static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) >>
+           local_receive_timestamps_exponent_)) {
+        set_detailed_error("Receive timestamp delta too high.");
+        return false;
+      }
       timestamp_delta = timestamp_delta << local_receive_timestamps_exponent_;
       if (i == 0 && j == 0) {
         last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
diff --git a/quiche/quic/core/quic_framer_test.cc b/quiche/quic/core/quic_framer_test.cc
index 0ceec4e..4bafd02 100644
--- a/quiche/quic/core/quic_framer_test.cc
+++ b/quiche/quic/core/quic_framer_test.cc
@@ -4110,6 +4110,63 @@
                                "Receive timestamp count too high."));
 }
 
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampDeltaShiftOverflow) {
+  if (!VersionIsIetfQuic(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x83, 0x17, 0x83, 0x07 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp delta largest acked.",
+         { kVarInt62OneByte + 0x00 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x01 }},
+       // Max 62-bit varint (0x3fffffffffffffff), which overflows when shifted
+       // by exponent >= 2.
+       { "Unable to read receive timestamp delta.",
+         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_local_receive_timestamps_exponent(3);
+  framer_.set_local_max_receive_timestamps_per_ack(1000);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp delta too high."));
+}
+
 TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) {
   SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
   // clang-format off