sdp: harden sctp max-message-size and sctp-port parsing

Bug: chromium:498185618
Change-Id: Ifce653f1746d63b2aa410bc3f40b6a974263e50e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/461780
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Philipp Hancke <philipp.hancke@googlemail.com>
Cr-Commit-Position: refs/heads/main@{#47402}
diff --git a/api/webrtc_sdp.cc b/api/webrtc_sdp.cc
index 56dc7b6..5348c81 100644
--- a/api/webrtc_sdp.cc
+++ b/api/webrtc_sdp.cc
@@ -696,6 +696,9 @@
   if (!FromString(fields[1], sctp_port)) {
     return ParseFailed(line, "Invalid sctp port value.", error);
   }
+  if (!IsValidPort(*sctp_port)) {
+    return ParseFailed(line, "Invalid sctp port value.", error);
+  }
   return true;
 }
 
@@ -713,6 +716,9 @@
   if (!FromString(fields[1], max_message_size)) {
     return ParseFailed(line, "Invalid SCTP max message size.", error);
   }
+  if (*max_message_size < 0) {
+    return ParseFailed(line, "Invalid SCTP max message size.", error);
+  }
   return true;
 }
 
diff --git a/api/webrtc_sdp_unittest.cc b/api/webrtc_sdp_unittest.cc
index 7a4d0a9..91b74ca 100644
--- a/api/webrtc_sdp_unittest.cc
+++ b/api/webrtc_sdp_unittest.cc
@@ -2785,6 +2785,42 @@
       MatchesCurrentDescriptionNoCandidates(SdpDeserialize(sdp_with_data)));
 }
 
+TEST_F(WebRtcSdpTest, DeserializeSdpWithNegativeSctpPort) {
+  std::string sdp = kSdpString;
+  sdp.append(kSdpSctpDataChannelStringWithSctpColonPort);
+  SdpParseError error;
+  absl::StrReplaceAll({{absl::StrCat(kDefaultSctpPort), absl::StrCat("-1")}},
+                      &sdp);
+  std::unique_ptr<SessionDescriptionInterface> output =
+      SdpDeserialize(sdp, &error);
+  ASSERT_THAT(output, IsNull());
+  EXPECT_EQ(error.line, "a=sctp-port:-1");
+}
+
+TEST_F(WebRtcSdpTest, DeserializeSdpWithTooLargeSctpPort) {
+  std::string sdp = kSdpString;
+  sdp.append(kSdpSctpDataChannelStringWithSctpColonPort);
+  SdpParseError error;
+  absl::StrReplaceAll({{absl::StrCat(kDefaultSctpPort), absl::StrCat("70000")}},
+                      &sdp);
+  std::unique_ptr<SessionDescriptionInterface> output =
+      SdpDeserialize(sdp, &error);
+  ASSERT_THAT(output, IsNull());
+  EXPECT_EQ(error.line, "a=sctp-port:70000");
+}
+
+TEST_F(WebRtcSdpTest, DeserializeSdpWithStringSctpPort) {
+  std::string sdp = kSdpString;
+  sdp.append(kSdpSctpDataChannelStringWithSctpColonPort);
+  SdpParseError error;
+  absl::StrReplaceAll(
+      {{absl::StrCat(kDefaultSctpPort), absl::StrCat("webrtc")}}, &sdp);
+  std::unique_ptr<SessionDescriptionInterface> output =
+      SdpDeserialize(sdp, &error);
+  ASSERT_THAT(output, IsNull());
+  EXPECT_EQ(error.line, "a=sctp-port:webrtc");
+}
+
 TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelsWithSctpInit) {
   bool use_sctpmap = false;
   AddSctpDataChannel(use_sctpmap);
@@ -2885,6 +2921,18 @@
       SdpDeserialize(sdp_with_data)));
 }
 
+TEST_F(WebRtcSdpTest,
+       DeserializeSdpWithSctpDataChannelsWithInvalidMaxMessageSize) {
+  std::string sdp_with_data = kSdpString;
+  sdp_with_data.append(kSdpSctpDataChannelStringWithSctpColonPort);
+  sdp_with_data.append("a=max-message-size:-1\r\n");
+  SdpParseError error;
+  std::unique_ptr<SessionDescriptionInterface> output =
+      SdpDeserialize(sdp_with_data, &error);
+  ASSERT_THAT(output, IsNull());
+  EXPECT_EQ(error.line, "a=max-message-size:-1");
+}
+
 TEST_F(WebRtcSdpTest, SerializeSdpWithSctpDataChannelWithMaxMessageSize) {
   bool use_sctpmap = false;
   AddSctpDataChannel(use_sctpmap);