MT#55283 modernise SDP parsing

Use the existing `str` primitives instead of doing explicit pointer
manipulations.

Change-Id: I9ce1df77c20a1ba8f394b3221cc2a284b9045c40
pull/1870/head
Richard Fuchs 1 year ago
parent 7167237f50
commit 6ab036c4e5

@ -121,7 +121,7 @@ struct sdp_media {
int port_count;
struct sdp_connection connection;
const char *c_line_pos;
const char *c_line_pos; // XXX to be obsoleted
struct session_bandwidth bandwidth;
struct sdp_attributes attributes;
str_slice_q format_list; /* list of slice-alloc'd str objects */
@ -266,7 +266,7 @@ enum attribute_other {
struct sdp_attribute {
/* example: a=rtpmap:8 PCMA/8000 */
str full_line; /* including a= and \r\n */
str full_line; /* including a= and \r\n */ // XXX to be obsoleted
str param; /* "PCMA/8000" */
struct sdp_attribute_strs strs;
@ -1213,59 +1213,59 @@ static int parse_attribute(struct sdp_attribute *a) {
}
int sdp_parse(str *body, sdp_sessions_q *sessions, const sdp_ng_flags *flags) {
char *b, *end, *value, *line_end, *next_line;
str b;
struct sdp_session *session = NULL;
struct sdp_media *media = NULL;
const char *errstr;
struct sdp_attributes *attrs;
struct sdp_attribute *attr;
str *adj_s;
int media_sdp_id = 0;
b = body->s;
end = str_end(body);
b = *body;
while (b && b < end - 1) {
while (b.len >= 2) {
if (!rtpe_config.reject_invalid_sdp) {
if (b[0] == '\n' || b[0] == '\r') {
body->len = b - body->s;
if (b.s[0] == '\n' || b.s[0] == '\r') {
body->len = b.s - body->s;
break;
}
}
char line_code = b.s[0];
errstr = "Missing '=' sign";
if (b[1] != '=')
if (b.s[1] != '=')
goto error;
value = &b[2];
line_end = memchr(value, '\n', end - value);
if (!line_end) {
/* assume missing LF at end of body */
line_end = end;
next_line = NULL;
}
else {
next_line = line_end + 1;
if (line_end[-1] == '\r')
line_end--;
}
str full_line;
str_token(&full_line, &b, '\n');
if (full_line.s[full_line.len - 1] == '\r')
full_line.len--;
errstr = "SDP doesn't start with a session definition";
if (!session && b[0] != 'v') {
if (!session && line_code != 'v') {
if (!flags->fragment)
goto error;
else
goto new_session; // allowed for trickle ICE SDP fragments
}
str value_str = STR_LEN(value, line_end - value);
str value = full_line;
str_shift(&value, 2); // removes `v=` etc
full_line.len = b.s - full_line.s; // include \r\n
switch (b[0]) {
switch (line_code) {
case 'v':
errstr = "Error in v= line";
if (line_end != value + 1)
if (value.len != 1) {
abort();
goto error;
if (value[0] != '0')
}
if (value.s[0] != '0') {
abort();
goto error;
}
new_session:
session = g_slice_alloc0(sizeof(*session));
@ -1273,7 +1273,7 @@ new_session:
attrs_init(&session->attributes);
t_queue_push_tail(sessions, session);
media = NULL;
session->s.s = b;
session->s = full_line;
RESET_BANDWIDTH(session->bandwidth, -1);
break;
@ -1283,30 +1283,31 @@ new_session:
if (media)
goto error;
errstr = "Error parsing o= line";
if (parse_origin(&value_str, &session->origin))
if (parse_origin(&value, &session->origin))
goto error;
break;
case 'm':
if (media && !media->c_line_pos)
media->c_line_pos = b;
media->c_line_pos = full_line.s;
media = g_slice_alloc0(sizeof(*media));
media->session = session;
attrs_init(&media->attributes);
errstr = "Error parsing m= line";
if (parse_media(&value_str, media))
if (parse_media(&value, media))
goto error;
t_queue_push_tail(&session->media_streams, media);
media->s.s = b;
media->s = full_line;
RESET_BANDWIDTH(media->bandwidth, -1);
media->media_sdp_id = media_sdp_id++;
break;
case 'c':
errstr = "Error parsing c= line";
if (parse_connection(&value_str,
if (parse_connection(&value,
media ? &media->connection : &session->connection))
goto error;
@ -1314,15 +1315,12 @@ new_session:
case 'a':
if (media && !media->c_line_pos)
media->c_line_pos = b;
media->c_line_pos = full_line.s;
attr = g_slice_alloc0(sizeof(*attr));
attr->full_line.s = b;
attr->full_line.len = next_line ? (next_line - b) : (line_end - b);
attr->strs.line_value.s = value;
attr->strs.line_value.len = line_end - value;
attr->full_line = full_line;
attr->strs.line_value = value;
if (parse_attribute(attr)) {
attr_free(attr);
@ -1336,48 +1334,48 @@ new_session:
case 'b':
if (media && !media->c_line_pos)
media->c_line_pos = b;
media->c_line_pos = full_line.s;
/* RR:0 */
if (line_end - value < 4)
if (value.len < 4)
break;
/* AS, RR, RS */
if (!memcmp(value, "AS:", 3)) {
*(media ? &media->bandwidth.as : &session->bandwidth.as) = strtol((value + 3), NULL, 10);
if (!memcmp(value.s, "AS:", 3)) {
*(media ? &media->bandwidth.as : &session->bandwidth.as) = strtol((value.s + 3), NULL, 10);
}
else if (!memcmp(value, "RR:", 3)) {
*(media ? &media->bandwidth.rr : &session->bandwidth.rr) = strtol((value + 3), NULL, 10);
else if (!memcmp(value.s, "RR:", 3)) {
*(media ? &media->bandwidth.rr : &session->bandwidth.rr) = strtol((value.s + 3), NULL, 10);
}
else if (!memcmp(value, "RS:", 3)) {
*(media ? &media->bandwidth.rs : &session->bandwidth.rs) = strtol((value + 3), NULL, 10);
else if (!memcmp(value.s, "RS:", 3)) {
*(media ? &media->bandwidth.rs : &session->bandwidth.rs) = strtol((value.s + 3), NULL, 10);
}
else if (!memcmp(value, "TIAS:", 5)) {
*(media ? &media->bandwidth.tias : &session->bandwidth.tias) = strtol((value + 5), NULL, 10);
else if (!memcmp(value.s, "TIAS:", 5)) {
*(media ? &media->bandwidth.tias : &session->bandwidth.tias) = strtol((value.s + 5), NULL, 10);
}
/* CT has only session level */
else if (!memcmp(value, "CT:", 3)) {
session->bandwidth.ct = strtol((value + 3), NULL, 10);
else if (!memcmp(value.s, "CT:", 3)) {
session->bandwidth.ct = strtol((value.s + 3), NULL, 10);
}
break;
case 'k':
if (media && !media->c_line_pos)
media->c_line_pos = b;
media->c_line_pos = full_line.s;
break;
case 's':
errstr = "s= line found within media section";
if (media)
goto error;
session->session_name = value_str;
session->session_name = value;
break;
case 't':
errstr = "t= line found within media section";
if (media)
goto error;
session->session_timing = value_str;
session->session_timing = value;
break;
case 'i':
@ -1397,16 +1395,15 @@ new_session:
if (!session)
goto error;
adj_s = media ? &media->s : &session->s;
adj_s->len = (next_line ? : end) - adj_s->s;
b = next_line;
// XXX to be obsoleted
str *adj_s = media ? &media->s : &session->s;
adj_s->len = b.s - adj_s->s;
}
return 0;
error:
ilog(LOG_WARNING, "Error parsing SDP at offset %li: %s", (long) (b - body->s), errstr);
ilog(LOG_WARNING, "Error parsing SDP at offset %zu: %s", (size_t) (b.s - body->s), errstr);
sdp_sessions_clear(sessions);
return -1;
}

Loading…
Cancel
Save