]> git.sesse.net Git - vlc/blobdiff - modules/access/rtsp/real_sdpplin.c
Remove most stray semi-colons in module descriptions
[vlc] / modules / access / rtsp / real_sdpplin.c
index d4b1068e948f8b34bdf3985c1d57a5fd3775c85a..229501cb6b152c8600eebc430de428b89d8745bd 100644 (file)
@@ -24,6 +24,7 @@
  */
  
 #include "real.h"
+#define BUFLEN 32000
 
 /*
  * Decodes base64 strings (based upon b64 package)
@@ -88,10 +89,10 @@ static char *nl(char *data) {
   return (nlptr) ? nlptr + 1 : NULL;
 }
 
-static int filter(const char *in, const char *filter, char **out) {
+static int filter(const char *in, const char *filter, char **out, size_t outlen) {
 
   int flen=strlen(filter);
-  int len;
+  size_t len;
 
   if (!in) return 0;
 
@@ -100,6 +101,11 @@ static int filter(const char *in, const char *filter, char **out) {
     if(in[flen]=='"') flen++;
     if(in[len-1]==13) len--;
     if(in[len-1]=='"') len--;
+    if( len-flen+1 > outlen )
+    {
+        printf("Discarding end of string to avoid overflow");
+        len=outlen+flen-1;
+    }
     memcpy(*out, in+flen, len-flen+1);
     (*out)[len-flen]=0;
     return len-flen;
@@ -110,8 +116,8 @@ static int filter(const char *in, const char *filter, char **out) {
 static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
 
   sdpplin_stream_t *desc = malloc(sizeof(sdpplin_stream_t));
-  char      *buf = malloc(32000);
-  char      *decoded = malloc(32000);
+  char      *buf = malloc(BUFLEN);
+  char      *decoded = malloc(BUFLEN);
   int       handled;
 
   if( !desc ) return NULL;
@@ -120,7 +126,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
   if( !buf ) goto error;
   if( !decoded ) goto error;
 
-  if (filter(*data, "m=", &buf)) {
+  if (filter(*data, "m=", &buf, BUFLEN)) {
     desc->id = strdup(buf);
   } else {
     lprintf("sdpplin: no m= found.\n");
@@ -131,61 +137,70 @@ 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);
-      handled=1;
-      *data=nl(*data);
+    if(filter(*data,"a=control:streamid=",&buf, BUFLEN)) {
+        /* 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)) {
+    if(filter(*data,"a=MaxBitRate:integer;",&buf, BUFLEN)) {
       desc->max_bit_rate=atoi(buf);
       if (!desc->avg_bit_rate)
         desc->avg_bit_rate=desc->max_bit_rate;
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=MaxPacketSize:integer;",&buf)) {
+    if(filter(*data,"a=MaxPacketSize:integer;",&buf, BUFLEN)) {
       desc->max_packet_size=atoi(buf);
       if (!desc->avg_packet_size)
         desc->avg_packet_size=desc->max_packet_size;
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=StartTime:integer;",&buf)) {
+    if(filter(*data,"a=StartTime:integer;",&buf, BUFLEN)) {
       desc->start_time=atoi(buf);
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=Preroll:integer;",&buf)) {
+    if(filter(*data,"a=Preroll:integer;",&buf, BUFLEN)) {
       desc->preroll=atoi(buf);
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=length:npt=",&buf)) {
+    if(filter(*data,"a=length:npt=",&buf, BUFLEN)) {
       desc->duration=(uint32_t)(atof(buf)*1000);
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=StreamName:string;",&buf)) {
+    if(filter(*data,"a=StreamName:string;",&buf, BUFLEN)) {
       desc->stream_name=strdup(buf);
       desc->stream_name_size=strlen(desc->stream_name);
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=mimetype:string;",&buf)) {
+    if(filter(*data,"a=mimetype:string;",&buf, BUFLEN)) {
       desc->mime_type=strdup(buf);
       desc->mime_type_size=strlen(desc->mime_type);
       handled=1;
       *data=nl(*data);
     }
-    if(filter(*data,"a=OpaqueData:buffer;",&buf)) {
+    if(filter(*data,"a=OpaqueData:buffer;",&buf, BUFLEN)) {
       decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
-      desc->mlti_data = malloc(sizeof(char)*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 ( decoded != NULL ) {
+          desc->mlti_data = malloc(sizeof(char)*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)) {
+    if(filter(*data,"a=ASMRuleBook:string;",&buf, BUFLEN)) {
       desc->asm_rule_book=strdup(buf);
       handled=1;
       *data=nl(*data);
@@ -201,14 +216,14 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
       *data=nl(*data);
     }
   }
-  if( buf ) free(buf);
-  if( decoded )free(decoded);
+  free( buf );
+  free( decoded) ;
   return desc;
 
 error:
-  if( decoded ) free(decoded);
-  if( desc ) free( desc );
-  if( buf ) free( buf );
+  free( decoded );
+  free( desc );
+  free( buf );
   return NULL;
 }
 
@@ -216,8 +231,8 @@ sdpplin_t *sdpplin_parse(char *data) {
 
   sdpplin_t        *desc = malloc(sizeof(sdpplin_t));
   sdpplin_stream_t *stream;
-  char             *buf=malloc(3200);
-  char             *decoded=malloc(3200);
+  char             *buf=malloc(BUFLEN);
+  char             *decoded=malloc(BUFLEN);
   int              handled;
   int              len;
 
@@ -231,48 +246,73 @@ sdpplin_t *sdpplin_parse(char *data) {
     free( desc );
     return NULL;
   }
+
+  desc->stream = NULL;
+
   memset(desc, 0, sizeof(sdpplin_t));
 
   while (data && *data) {
     handled=0;
 
-    if (filter(data, "m=", &buf)) {
-      stream=sdpplin_parse_stream(&data);
-      lprintf("got data for stream id %u\n", stream->stream_id);
-      desc->stream[stream->stream_id]=stream;
-      continue;
+    if (filter(data, "m=", &buf, BUFLEN)) {
+        if ( !desc->stream ) {
+            fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping.");
+            continue;
+        }
+        stream=sdpplin_parse_stream(&data);
+        lprintf("got data for stream id %u\n", stream->stream_id);
+        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)) {
+    if(filter(data,"a=Title:buffer;",&buf, BUFLEN)) {
       decoded=b64_decode(buf, decoded, &len);
-      desc->title=strdup(decoded);
-      handled=1;
-      data=nl(data);
+         if ( decoded != NULL ) {
+          desc->title=strdup(decoded);
+          handled=1;
+          data=nl(data);
+      }
     }
-    if(filter(data,"a=Author:buffer;",&buf)) {
+    if(filter(data,"a=Author:buffer;",&buf, BUFLEN)) {
       decoded=b64_decode(buf, decoded, &len);
-      desc->author=strdup(decoded);
-      handled=1;
-      data=nl(data);
+         if ( decoded != NULL ) {
+          desc->author=strdup(decoded);
+          handled=1;
+          data=nl(data);
+      }
     }
-    if(filter(data,"a=Copyright:buffer;",&buf)) {
+    if(filter(data,"a=Copyright:buffer;",&buf, BUFLEN)) {
       decoded=b64_decode(buf, decoded, &len);
-      desc->copyright=strdup(decoded);
-      handled=1;
-      data=nl(data);
+         if ( decoded != NULL ) {
+          desc->copyright=strdup(decoded);
+          handled=1;
+          data=nl(data);
+      }
     }
-    if(filter(data,"a=Abstract:buffer;",&buf)) {
+    if(filter(data,"a=Abstract:buffer;",&buf, BUFLEN)) {
       decoded=b64_decode(buf, decoded, &len);
-      desc->abstract=strdup(decoded);
-      handled=1;
-      data=nl(data);
+      if ( decoded != NULL ) {
+           desc->abstract=strdup(decoded);
+           handled=1;
+           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);
-      handled=1;
-      data=nl(data);
+    if(filter(data,"a=StreamCount:integer;",&buf, BUFLEN)) {
+        /* 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)) {
+    if(filter(data,"a=Flags:integer;",&buf, BUFLEN)) {
       desc->flags=atoi(buf);
       handled=1;
       data=nl(data);
@@ -289,8 +329,8 @@ sdpplin_t *sdpplin_parse(char *data) {
     }
   }
 
-  free(decoded);
-  free(buf);
+  free( decoded );
+  free( buf );
   return desc;
 }
 
@@ -302,36 +342,36 @@ void sdpplin_free(sdpplin_t *description) {
 
   for( i=0; i<description->stream_count; i++ ) {
     if( description->stream[i] ) {
-      if( description->stream[i]->id ) free( description->stream[i]->id );
-      if( description->stream[i]->bandwidth ) free( description->stream[i]->bandwidth );
-      if( description->stream[i]->range ) free( description->stream[i]->range );
-      if( description->stream[i]->length ) free( description->stream[i]->length );
-      if( description->stream[i]->rtpmap ) free( description->stream[i]->rtpmap );
-      if( description->stream[i]->mimetype ) free( description->stream[i]->mimetype );
-      if( description->stream[i]->stream_name ) free( description->stream[i]->stream_name );
-      if( description->stream[i]->mime_type ) free( description->stream[i]->mime_type );
-      if( description->stream[i]->mlti_data ) free( description->stream[i]->mlti_data );
-      if( description->stream[i]->rmff_flags ) free( description->stream[i]->rmff_flags );
-      if( description->stream[i]->asm_rule_book ) free( description->stream[i]->asm_rule_book );
+      free( description->stream[i]->id );
+      free( description->stream[i]->bandwidth );
+      free( description->stream[i]->range );
+      free( description->stream[i]->length );
+      free( description->stream[i]->rtpmap );
+      free( description->stream[i]->mimetype );
+      free( description->stream[i]->stream_name );
+      free( description->stream[i]->mime_type );
+      free( description->stream[i]->mlti_data );
+      free( description->stream[i]->rmff_flags );
+      free( description->stream[i]->asm_rule_book );
       free( description->stream[i] );
     }
   }
   if( description->stream_count ) free( description->stream );
 
-  if( description->owner ) free( description->owner );
-  if( description->session_name ) free( description->session_name );
-  if( description->session_info ) free( description->session_info );
-  if( description->uri ) free( description->uri );
-  if( description->email ) free( description->email );
-  if( description->phone ) free( description->phone );
-  if( description->connection ) free( description->connection );
-  if( description->bandwidth ) free( description->bandwidth );
-  if( description->title ) free( description->title );
-  if( description->author ) free( description->author );
-  if( description->copyright ) free( description->copyright );
-  if( description->keywords ) free( description->keywords );
-  if( description->asm_rule_book ) free( description->asm_rule_book );
-  if( description->abstract ) free( description->abstract );
-  if( description->range ) free( description->range );
+  free( description->owner );
+  free( description->session_name );
+  free( description->session_info );
+  free( description->uri );
+  free( description->email );
+  free( description->phone );
+  free( description->connection );
+  free( description->bandwidth );
+  free( description->title );
+  free( description->author );
+  free( description->copyright );
+  free( description->keywords );
+  free( description->asm_rule_book );
+  free( description->abstract );
+  free( description->range );
   free(description);
 }