Reject non-token char in BUNDLE (and other) groups
also modernize code for parsing and serialization. This is a safe change
since such BUNDLE tags need to refer to a mid and non-token-char are not accepted for mid.
Bug: webrtc:42220536
Change-Id: Iddf06e7935a4e7ad0a3897739c851bd9dbfedad8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/404203
Reviewed-by: Evan Shrubsole <eshr@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@meta.com>
Cr-Commit-Position: refs/heads/main@{#45341}
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 3b3f4f1..a96701a 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -191,7 +191,6 @@
const char kSessionOriginAddress[] = "127.0.0.1";
const char kSessionName[] = "s=-";
const char kTimeDescription[] = "t=0 0";
-const char kAttrGroup[] = "a=group:BUNDLE";
const char kConnectionNettype[] = "IN";
const char kConnectionIpv4Addrtype[] = "IP4";
const char kConnectionIpv6Addrtype[] = "IP6";
@@ -1570,13 +1569,18 @@
SdpParseError* error) {
RTC_DCHECK(desc != nullptr);
- // RFC 5888 and draft-holmberg-mmusic-sdp-bundle-negotiation-00
+ // RFC 5888 and RFC 8843.
// a=group:BUNDLE video voice
std::vector<absl::string_view> fields =
split(line.substr(kLinePrefixLength), kSdpDelimiterSpaceChar);
std::string semantics;
if (!GetValue(fields[0], kAttributeGroup, &semantics, error)) {
- return false;
+ return ParseFailed(line, "Failed to parse group attribute.", error);
+ }
+ for (size_t i = 1; i < fields.size(); ++i) {
+ if (!absl::c_all_of(fields[i], IsTokenChar)) {
+ return ParseFailed(line, "Failed to parse group tag.", error);
+ }
}
ContentGroup group(semantics);
for (size_t i = 1; i < fields.size(); ++i) {
@@ -3242,13 +3246,13 @@
std::vector<const ContentGroup*> groups =
desc->GetGroupsByName(GROUP_TYPE_BUNDLE);
for (const ContentGroup* group : groups) {
- std::string group_line = kAttrGroup;
RTC_DCHECK(group != nullptr);
+ InitAttrLine(kAttributeGroup, &os);
+ os << kSdpDelimiterColon << GROUP_TYPE_BUNDLE;
for (const std::string& content_name : group->content_names()) {
- group_line.append(" ");
- group_line.append(content_name);
+ os << " " << content_name;
}
- AddLine(group_line, &message);
+ AddLine(os.str(), &message);
}
// Mixed one- and two-byte header extension.
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 1f2e29f..54636fa 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -5096,5 +5096,15 @@
EXPECT_TRUE(desc->ToString(&serialized));
}
+TEST_F(WebRtcSdpTest, RejectsInvalidCharactersInBundleGroup) {
+ JsepSessionDescription desc(kDummyType);
+ std::string sdp_with_bad_bundle_tag = kSdpFullString;
+ // Inject a "shrug" unicode character.
+ InjectAfter(kSessionTime, "a=group:BUNDLE \u1f937\r\n",
+ &sdp_with_bad_bundle_tag);
+ SdpParseError error;
+ EXPECT_FALSE(SdpDeserialize(sdp_with_bad_bundle_tag, &desc, &error));
+}
+
} // namespace
} // namespace webrtc