Have ParsedQuicVersionIsValid also validate transport versions

As part of investigating <https://crbug.com/1061509>,  we realized that since versions can be saved to disk, it's possible to try to create an invalid ParsedQuicVersion based on data from a previous build before a given version was deprecated. So to better enforce our assumptions, this CL changes ParsedQuicVersionIsValid to also check whether the transport version is known by the current codebase.

gfe-relnote: change a DCHECK, no changes in production
PiperOrigin-RevId: 301259614
Change-Id: I11051d88ddc7f9eae426858902d2b82355578910
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 3a37091..bf6c39b 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -122,6 +122,22 @@
   QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
 };
 
+// This array contains QUIC transport versions which we currently support.
+// This should be ordered such that the highest supported version is the first
+// element, with subsequent elements in descending order (versions can be
+// skipped as necessary).
+//
+// See go/new-quic-version for more details on how to roll out new versions.
+constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() {
+  return {QUIC_VERSION_IETF_DRAFT_27,
+          QUIC_VERSION_IETF_DRAFT_25,
+          QUIC_VERSION_50,
+          QUIC_VERSION_49,
+          QUIC_VERSION_48,
+          QUIC_VERSION_46,
+          QUIC_VERSION_43};
+}
+
 // Helper function which translates from a QuicTransportVersion to a string.
 // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
 QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
@@ -152,6 +168,20 @@
 QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
     HandshakeProtocol handshake_protocol,
     QuicTransportVersion transport_version) {
+  bool transport_version_is_valid =
+      transport_version == QUIC_VERSION_UNSUPPORTED ||
+      transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION;
+  if (!transport_version_is_valid) {
+    for (QuicTransportVersion trans_vers : SupportedTransportVersions()) {
+      if (trans_vers == transport_version) {
+        transport_version_is_valid = true;
+        break;
+      }
+    }
+  }
+  if (!transport_version_is_valid) {
+    return false;
+  }
   switch (handshake_protocol) {
     case PROTOCOL_UNSUPPORTED:
       return transport_version == QUIC_VERSION_UNSUPPORTED;
@@ -162,7 +192,8 @@
     case PROTOCOL_TLS1_3:
       // The TLS handshake is only deployable if CRYPTO frames are also used.
       // We explicitly removed support for T048 and T049 to reduce test load.
-      return QuicVersionUsesCryptoFrames(transport_version) &&
+      return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             QuicVersionUsesCryptoFrames(transport_version) &&
              transport_version > QUIC_VERSION_49;
   }
   return false;
@@ -312,22 +343,6 @@
 using QuicVersionLabel = uint32_t;
 using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
 
-// This vector contains QUIC versions which we currently support.
-// This should be ordered such that the highest supported version is the first
-// element, with subsequent elements in descending order (versions can be
-// skipped as necessary).
-//
-// See go/new-quic-version for more details on how to roll out new versions.
-constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() {
-  return {QUIC_VERSION_IETF_DRAFT_27,
-          QUIC_VERSION_IETF_DRAFT_25,
-          QUIC_VERSION_50,
-          QUIC_VERSION_49,
-          QUIC_VERSION_48,
-          QUIC_VERSION_46,
-          QUIC_VERSION_43};
-}
-
 // This vector contains all crypto handshake protocols that are supported.
 constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
   return {PROTOCOL_QUIC_CRYPTO, PROTOCOL_TLS1_3};