]> git.sesse.net Git - vlc/blobdiff - modules/access/rtsp/real_sdpplin.c
rtspreal: no need to compute the values of this array.
[vlc] / modules / access / rtsp / real_sdpplin.c
index f12836734c3c96e7b4d9b96ef7072ac22c571d00..64e043af5431f0fed08769a6b62781b0f166cb7a 100644 (file)
@@ -36,28 +36,29 @@ static char *b64_decode(const char *in, char *out, int *size) {
   int i,k;
   unsigned int j;
 
-  for (i = 0; i < 255; i++) {
+  for( i = 0; i < 256; i++ )
     dtable[i] = 0x80;
-  }
-  for (i = 'A'; i <= 'Z'; i++) {
+
+  for( i = 'A'; i <= 'Z'; i++ )
     dtable[i] = 0 + (i - 'A');
-  }
-  for (i = 'a'; i <= 'z'; i++) {
+
+  for( i = 'a'; i <= 'z'; i++ )
     dtable[i] = 26 + (i - 'a');
-  }
-  for (i = '0'; i <= '9'; i++) {
+
+  for( i = '0'; i <= '9'; i++ )
     dtable[i] = 52 + (i - '0');
-  }
+
   dtable['+'] = 62;
   dtable['/'] = 63;
   dtable['='] = 0;
 
   k=0;
   /*CONSTANTCONDITION*/
-  for (j=0; j<strlen(in); j+=4) {
+  int in_len = strlen(in);
+  for (j=0; j < in_len; j+=4) {
     char a[4], b[4];
 
-    for (i = 0; i < 4; i++) {
+    for (i = 0; i < 4 && j + i < in_len; i++) {
       int c = in[i+j];
 
       if (dtable[c] & 0x80) {
@@ -115,16 +116,22 @@ static int filter(const char *in, const char *filter, char **out, size_t outlen)
 
 static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
 
-  sdpplin_stream_t *desc = malloc(sizeof(sdpplin_stream_t));
-  char      *buf = malloc(BUFLEN);
-  char      *decoded = malloc(BUFLEN);
-  int       handled;
+  sdpplin_stream_t *desc;
+  char* buf = NULL;
+  char* decoded = NULL;
+  int handled;
 
-  if( !desc ) return NULL;
-  memset(desc, 0, sizeof(sdpplin_stream_t));
+  desc = calloc( 1, sizeof(sdpplin_stream_t) );
+  if( !desc )
+    return NULL;
+
+  buf = malloc( BUFLEN );
+  if( !buf )
+    goto error;
 
-  if( !buf ) goto error;
-  if( !decoded ) goto error;
+  decoded = malloc( BUFLEN );
+  if( !decoded )
+    goto error;
 
   if (filter(*data, "m=", &buf, BUFLEN)) {
     desc->id = strdup(buf);
@@ -138,9 +145,16 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
     handled=0;
 
     if(filter(*data,"a=control:streamid=",&buf, BUFLEN)) {
-      desc->stream_id=atoi(buf);
-      handled=1;
-      *data=nl(*data);
+        /* 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);
     }
     if(filter(*data,"a=MaxBitRate:integer;",&buf, BUFLEN)) {
       desc->max_bit_rate=atoi(buf);
@@ -186,7 +200,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
     if(filter(*data,"a=OpaqueData:buffer;",&buf, BUFLEN)) {
       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);
@@ -220,30 +234,36 @@ error:
   return NULL;
 }
 
-sdpplin_t *sdpplin_parse(char *data) {
 
-  sdpplin_t        *desc = malloc(sizeof(sdpplin_t));
-  sdpplin_stream_t *stream;
-  char             *buf=malloc(BUFLEN);
-  char             *decoded=malloc(BUFLEN);
-  int              handled;
-  int              len;
+sdpplin_t *sdpplin_parse(char *data)
+{
+  sdpplin_t*        desc;
+  sdpplin_stream_t* stream;
+  char*             buf;
+  char*             decoded;
+  int               handled;
+  int               len;
 
-  if( !desc ) return NULL;
-  if( !buf ) {
+  desc = calloc( 1, sizeof(sdpplin_t) );
+  if( !desc )
+    return NULL;
+
+  buf = malloc( BUFLEN );
+  if( !buf )
+  {
     free( desc );
     return NULL;
   }
-  if( !decoded ) {
+
+  decoded = malloc( BUFLEN );
+  if( !decoded )
+  {
     free( buf );
     free( desc );
     return NULL;
   }
-
   desc->stream = NULL;
 
-  memset(desc, 0, sizeof(sdpplin_t));
-
   while (data && *data) {
     handled=0;
 
@@ -254,7 +274,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;
     }
     if(filter(data,"a=Title:buffer;",&buf, BUFLEN)) {
@@ -290,10 +313,17 @@ sdpplin_t *sdpplin_parse(char *data) {
       }
     }
     if(filter(data,"a=StreamCount:integer;",&buf, BUFLEN)) {
-      desc->stream_count=atoi(buf);
-      desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
-      handled=1;
-      data=nl(data);
+        /* 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 = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
+        handled=1;
+        data=nl(data);
     }
     if(filter(data,"a=Flags:integer;",&buf, BUFLEN)) {
       desc->flags=atoi(buf);
@@ -339,7 +369,8 @@ void sdpplin_free(sdpplin_t *description) {
       free( description->stream[i] );
     }
   }
-  if( description->stream_count ) free( description->stream );
+  if( description->stream_count )
+    free( description->stream );
 
   free( description->owner );
   free( description->session_name );
@@ -356,5 +387,6 @@ void sdpplin_free(sdpplin_t *description) {
   free( description->asm_rule_book );
   free( description->abstract );
   free( description->range );
-  free(description);
+  free( description );
 }
+