summaryrefslogtreecommitdiff
path: root/src/input/libreal/sdpplin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/libreal/sdpplin.c')
-rw-r--r--src/input/libreal/sdpplin.c74
1 files changed, 48 insertions, 26 deletions
diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c
index c62b6bbc1..b7e5218cb 100644
--- a/src/input/libreal/sdpplin.c
+++ b/src/input/libreal/sdpplin.c
@@ -19,7 +19,11 @@
*
* sdp/sdpplin parser.
*/
-
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "sdpplin"
#define LOG_VERBOSE
/*
@@ -58,9 +62,10 @@ static char *b64_decode(const char *in, char *out, int *size)
dtable['='] = 0;
k=0;
-
+
/*CONSTANTCONDITION*/
- for (j=0; j<strlen(in); j+=4)
+ const size_t in_len = strlen(in);
+ for (j=0; j<in_len; j+=4)
{
char a[4], b[4];
@@ -99,12 +104,12 @@ static char *nl(char *data) {
static int filter(const char *in, const char *filter, char **out) {
- int flen=strlen(filter);
+ size_t flen=strlen(filter);
size_t len;
-
+
if (!in)
return 0;
-
+
len = (strchr(in,'\n')) ? (size_t)(strchr(in,'\n')-in) : strlen(in);
if (!strncmp(in,filter,flen))
@@ -117,16 +122,16 @@ static int filter(const char *in, const char *filter, char **out) {
return len-flen;
}
-
+
return 0;
}
-static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
+static sdpplin_stream_t *XINE_MALLOC sdpplin_parse_stream(char **data) {
- sdpplin_stream_t *desc = xine_xmalloc(sizeof(sdpplin_stream_t));
+ sdpplin_stream_t *desc = calloc(1, sizeof(sdpplin_stream_t));
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
int handled;
-
+
if (filter(*data, "m=", &buf)) {
desc->id = strdup(buf);
} else
@@ -141,9 +146,16 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
while (*data && **data && *data[0]!='m') {
handled=0;
-
+
if(filter(*data,"a=control:streamid=",&buf)) {
- desc->stream_id=atoi(buf);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream id out of bound: %lu\n", tmp);
+ else
+ desc->stream_id=tmp;
handled=1;
*data=nl(*data);
}
@@ -163,7 +175,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
handled=1;
*data=nl(*data);
}
-
+
if(filter(*data,"a=StartTime:integer;",&buf)) {
desc->start_time=atoi(buf);
handled=1;
@@ -199,14 +211,14 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
if(filter(*data,"a=OpaqueData:buffer;",&buf)) {
decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
if ( decoded != NULL ) {
- desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size);
+ desc->mlti_data = malloc(desc->mlti_data_size);
memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
handled=1;
*data=nl(*data);
lprintf("mlti_data_size: %i\n", desc->mlti_data_size);
}
}
-
+
if(filter(*data,"a=ASMRuleBook:string;",&buf)) {
desc->asm_rule_book=strdup(buf);
handled=1;
@@ -226,13 +238,13 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
xine_buffer_free(buf);
xine_buffer_free(decoded);
-
+
return desc;
}
sdpplin_t *sdpplin_parse(char *data) {
- sdpplin_t *desc = xine_xmalloc(sizeof(sdpplin_t));
+ sdpplin_t *desc = calloc(1, sizeof(sdpplin_t));
sdpplin_stream_t *stream;
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
@@ -244,7 +256,7 @@ sdpplin_t *sdpplin_parse(char *data) {
while (data && *data) {
handled=0;
-
+
if (filter(data, "m=", &buf)) {
if ( ! desc->stream ) {
fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping.");
@@ -252,7 +264,10 @@ sdpplin_t *sdpplin_parse(char *data) {
}
stream=sdpplin_parse_stream(&data);
lprintf("got data for stream id %u\n", stream->stream_id);
- desc->stream[stream->stream_id]=stream;
+ if ( stream->stream_id >= desc->stream_count )
+ lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count);
+ else
+ desc->stream[stream->stream_id]=stream;
continue;
}
@@ -264,7 +279,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Author:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -273,7 +288,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Copyright:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -282,7 +297,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Abstract:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -291,10 +306,17 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=StreamCount:integer;",&buf)) {
- desc->stream_count=atoi(buf);
- desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream count out of bound: %lu\n", tmp);
+ else
+ desc->stream_count = tmp;
+ desc->stream = calloc(desc->stream_count, sizeof(sdpplin_stream_t*));
handled=1;
data=nl(data);
}
@@ -318,7 +340,7 @@ sdpplin_t *sdpplin_parse(char *data) {
xine_buffer_free(buf);
xine_buffer_free(decoded);
-
+
return desc;
}