warn early when SDP is likely to be invalid

This commit is contained in:
Daniel Gultsch 2023-10-04 13:07:06 +02:00
parent 6bc3cad7de
commit 1b5d2151d0
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -176,8 +176,15 @@ public class SessionDescription {
mediaAttributes.put("ice-options", Joiner.on(' ').join(iceOptions)); mediaAttributes.put("ice-options", Joiner.on(' ').join(iceOptions));
final IceUdpTransportInfo.Fingerprint fingerprint = transport.getFingerprint(); final IceUdpTransportInfo.Fingerprint fingerprint = transport.getFingerprint();
if (fingerprint != null) { if (fingerprint != null) {
mediaAttributes.put( final String hashFunction = fingerprint.getHash();
"fingerprint", fingerprint.getHash() + " " + fingerprint.getContent()); final String hash = fingerprint.getContent();
if (Strings.isNullOrEmpty(hashFunction) || Strings.isNullOrEmpty(hash)) {
throw new IllegalArgumentException("DTLS-SRTP missing hash");
}
checkNoWhitespace(
hashFunction, "DTLS-SRTP hash function must not contain whitespace");
checkNoWhitespace(hash, "DTLS-SRTP hash must not contain whitespace");
mediaAttributes.put("fingerprint", hashFunction + " " + hash);
final IceUdpTransportInfo.Setup setup = fingerprint.getSetup(); final IceUdpTransportInfo.Setup setup = fingerprint.getSetup();
if (setup != null) { if (setup != null) {
mediaAttributes.put("setup", setup.toString().toLowerCase(Locale.ROOT)); mediaAttributes.put("setup", setup.toString().toLowerCase(Locale.ROOT));
@ -214,12 +221,14 @@ public class SessionDescription {
} }
checkNoWhitespace( checkNoWhitespace(
type, "feedback negotiation type must not contain whitespace"); type, "feedback negotiation type must not contain whitespace");
mediaAttributes.put( if (Strings.isNullOrEmpty(subtype)) {
"rtcp-fb", mediaAttributes.put("rtcp-fb", id + " " + type);
id } else {
+ " " checkNoWhitespace(
+ type subtype,
+ (Strings.isNullOrEmpty(subtype) ? "" : " " + subtype)); "feedback negotiation subtype must not contain whitespace");
mediaAttributes.put("rtcp-fb", id + " " + type + " " + subtype);
}
} }
for (RtpDescription.FeedbackNegotiationTrrInt feedbackNegotiationTrrInt : for (RtpDescription.FeedbackNegotiationTrrInt feedbackNegotiationTrrInt :
payloadType.feedbackNegotiationTrrInts()) { payloadType.feedbackNegotiationTrrInts()) {
@ -236,9 +245,13 @@ public class SessionDescription {
throw new IllegalArgumentException("a feedback negotiation is missing type"); throw new IllegalArgumentException("a feedback negotiation is missing type");
} }
checkNoWhitespace(type, "feedback negotiation type must not contain whitespace"); checkNoWhitespace(type, "feedback negotiation type must not contain whitespace");
mediaAttributes.put( if (Strings.isNullOrEmpty(subtype)) {
"rtcp-fb", mediaAttributes.put("rtcp-fb", "* " + type);
"* " + type + (Strings.isNullOrEmpty(subtype) ? "" : " " + subtype)); } else {
checkNoWhitespace(
subtype, "feedback negotiation subtype must not contain whitespace");
mediaAttributes.put("rtcp-fb", "* " + type + " " + subtype); /**/
}
} }
for (final RtpDescription.FeedbackNegotiationTrrInt feedbackNegotiationTrrInt : for (final RtpDescription.FeedbackNegotiationTrrInt feedbackNegotiationTrrInt :
description.feedbackNegotiationTrrInts()) { description.feedbackNegotiationTrrInts()) {
@ -275,6 +288,9 @@ public class SessionDescription {
if (groups.size() == 0) { if (groups.size() == 0) {
throw new IllegalArgumentException("A SSRC group is missing SSRC ids"); throw new IllegalArgumentException("A SSRC group is missing SSRC ids");
} }
for (final String source : groups) {
checkNoWhitespace(source, "Sources must not contain whitespace");
}
mediaAttributes.put( mediaAttributes.put(
"ssrc-group", "ssrc-group",
String.format("%s %s", semantics, Joiner.on(' ').join(groups))); String.format("%s %s", semantics, Joiner.on(' ').join(groups)));
@ -298,6 +314,12 @@ public class SessionDescription {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"A source specific media attribute is missing its value"); "A source specific media attribute is missing its value");
} }
checkNoWhitespace(
parameterName,
"A source specific media attribute name not not contain whitespace");
checkNoNewline(
parameterValue,
"A source specific media attribute value must not contain new lines");
mediaAttributes.put( mediaAttributes.put(
"ssrc", id + " " + parameterName + ":" + parameterValue.trim()); "ssrc", id + " " + parameterName + ":" + parameterValue.trim());
} }
@ -338,6 +360,13 @@ public class SessionDescription {
return input; return input;
} }
public static String checkNoNewline(final String input, final String message) {
if (CharMatcher.anyOf("\r\n").matchesAnyOf(message)) {
throw new IllegalArgumentException(message);
}
return input;
}
public static int ignorantIntParser(final String input) { public static int ignorantIntParser(final String input) {
try { try {
return Integer.parseInt(input); return Integer.parseInt(input);