diff options
Diffstat (limited to 'src/input/libreal')
-rw-r--r-- | src/input/libreal/asmrp.c | 6 | ||||
-rw-r--r-- | src/input/libreal/real.c | 15 | ||||
-rw-r--r-- | src/input/libreal/rmff.c | 144 | ||||
-rw-r--r-- | src/input/libreal/rmff.h | 14 | ||||
-rw-r--r-- | src/input/libreal/sdpplin.c | 42 | ||||
-rw-r--r-- | src/input/libreal/sdpplin.h | 6 |
6 files changed, 163 insertions, 64 deletions
diff --git a/src/input/libreal/asmrp.c b/src/input/libreal/asmrp.c index f7206b583..902c59d42 100644 --- a/src/input/libreal/asmrp.c +++ b/src/input/libreal/asmrp.c @@ -32,6 +32,10 @@ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -95,7 +99,7 @@ typedef struct { } asmrp_t; -static asmrp_t *asmrp_new () { +static asmrp_t *XINE_MALLOC asmrp_new () { asmrp_t *p; diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index df50f0440..dcb90bcd0 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -21,6 +21,10 @@ * adopted from joschkas real tools. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <string.h> @@ -48,9 +52,6 @@ static const unsigned char xor_table[] = { #define _X_BE_32C(x,y) do { *(uint32_t *)(x) = be2me_32((y)); } while(0) #define _X_LE_32C(x,y) do { *(uint32_t *)(x) = le2me_32((y)); } while(0) -#define MAX(x,y) ((x>y) ? x : y) - - static void hash(char *field, char *param) { uint32_t a, b, c, d; @@ -313,7 +314,7 @@ static void calc_response_string (char *result, char *challenge) { void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) { - int ch_len, resp_len; + size_t ch_len, resp_len; int i; char *ptr; char buf[128]; @@ -449,7 +450,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt if (!desc) return NULL; buf=xine_buffer_init(2048); - header = xine_xmalloc(sizeof(rmff_header_t)); + header = calloc(1, sizeof(rmff_header_t)); header->fileheader=rmff_new_fileheader(4+desc->stream_count); header->cont=rmff_new_cont( @@ -458,7 +459,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt desc->copyright, desc->abstract); header->data=rmff_new_dataheader(0,0); - header->streams = xine_xmalloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); + header->streams = calloc((desc->stream_count+1), sizeof(rmff_mdpr_t*)); lprintf("number of streams: %u\n", desc->stream_count); for (i=0; i<desc->stream_count; i++) { @@ -660,7 +661,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid lprintf("Stream description size: %i\n", size); - description = malloc(sizeof(char)*(size+1)); + description = malloc(size+1); if( rtsp_read_data(rtsp_session, description, size) <= 0) { xine_buffer_free(buf); diff --git a/src/input/libreal/rmff.c b/src/input/libreal/rmff.c index 159b81ee6..2d3fcc613 100644 --- a/src/input/libreal/rmff.c +++ b/src/input/libreal/rmff.c @@ -21,6 +21,10 @@ * adopted from joschkas real tools */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define LOG_MODULE "rmff" #define LOG_VERBOSE /* @@ -35,9 +39,13 @@ * writes header data to a buffer */ -static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) { +static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, uint8_t *buffer, int bufsize) { + + if (!fileheader) return 0; + + if (bufsize < RMFF_FILEHEADER_SIZE) + return -1; - if (!fileheader) return; fileheader->object_id=_X_BE_32(&fileheader->object_id); fileheader->size=_X_BE_32(&fileheader->size); fileheader->object_version=_X_BE_16(&fileheader->object_version); @@ -53,11 +61,17 @@ static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) { fileheader->file_version=_X_BE_32(&fileheader->file_version); fileheader->num_headers=_X_BE_32(&fileheader->num_headers); fileheader->object_id=_X_BE_32(&fileheader->object_id); + + return RMFF_FILEHEADER_SIZE; } -static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) { +static int rmff_dump_prop(rmff_prop_t *prop, uint8_t *buffer, int bufsize) { + + if (!prop) return 0; + + if (bufsize < RMFF_PROPHEADER_SIZE) + return -1; - if (!prop) return; prop->object_id=_X_BE_32(&prop->object_id); prop->size=_X_BE_32(&prop->size); prop->object_version=_X_BE_16(&prop->object_version); @@ -93,13 +107,19 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) { prop->num_streams=_X_BE_16(&prop->num_streams); prop->flags=_X_BE_16(&prop->flags); prop->object_id=_X_BE_32(&prop->object_id); + + return RMFF_PROPHEADER_SIZE; } -static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) { +static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, uint8_t *buffer, int bufsize) { int s1, s2, s3; - if (!mdpr) return; + if (!mdpr) return 0; + + if (bufsize < RMFF_MDPRHEADER_SIZE + mdpr->type_specific_len + mdpr->stream_name_size + mdpr->mime_type_size) + return -1; + mdpr->object_id=_X_BE_32(&mdpr->object_id); mdpr->size=_X_BE_32(&mdpr->size); mdpr->object_version=_X_BE_16(&mdpr->object_version); @@ -141,13 +161,19 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) { mdpr->duration=_X_BE_32(&mdpr->duration); mdpr->object_id=_X_BE_32(&mdpr->object_id); + return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; } -static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { +static int rmff_dump_cont(rmff_cont_t *cont, uint8_t *buffer, int bufsize) { int p; - if (!cont) return; + if (!cont) return 0; + + if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len) + return -1; + cont->object_id=_X_BE_32(&cont->object_id); cont->size=_X_BE_32(&cont->size); cont->object_version=_X_BE_16(&cont->object_version); @@ -181,11 +207,18 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { cont->size=_X_BE_32(&cont->size); cont->object_version=_X_BE_16(&cont->object_version); cont->object_id=_X_BE_32(&cont->object_id); + + return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len; } -static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { +static int rmff_dump_dataheader(rmff_data_t *data, uint8_t *buffer, int bufsize) { + + if (!data) return 0; + + if (bufsize < RMFF_DATAHEADER_SIZE) + return -1; - if (!data) return; data->object_id=_X_BE_32(&data->object_id); data->size=_X_BE_32(&data->size); data->object_version=_X_BE_16(&data->object_version); @@ -201,31 +234,43 @@ static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { data->size=_X_BE_32(&data->size); data->object_version=_X_BE_16(&data->object_version); data->object_id=_X_BE_32(&data->object_id); + + return RMFF_DATAHEADER_SIZE; } -int rmff_dump_header(rmff_header_t *h, char *buffer, int max) { +int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max) { + uint8_t *buffer = buf_gen; - int written=0; + int written=0, size; rmff_mdpr_t **stream=h->streams; - rmff_dump_fileheader(h->fileheader, &buffer[written]); - written+=h->fileheader->size; - rmff_dump_prop(h->prop, &buffer[written]); - written+=h->prop->size; - rmff_dump_cont(h->cont, &buffer[written]); - written+=h->cont->size; + if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) + return -1; + written+=size; + max -= size; + if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) + return -1; + written+=size; + max -= size; + if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) + return -1; + written+=size; + max -= size; if (stream) { while(*stream) { - rmff_dump_mdpr(*stream, &buffer[written]); - written+=(*stream)->size; + if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) + return -1; + written+=size; + max -= size; stream++; } } - rmff_dump_dataheader(h->data, &buffer[written]); - written+=18; + if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) + return -1; + written+=size; return written; } @@ -289,12 +334,14 @@ static rmff_prop_t *rmff_scan_prop(const char *data) { return prop; } -static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { - - rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); +static rmff_mdpr_t *rmff_scan_mdpr(const char *data) +{ + rmff_mdpr_t *mdpr = calloc(sizeof(rmff_mdpr_t), 1); mdpr->object_id=_X_BE_32(data); mdpr->size=_X_BE_32(&data[4]); + if (mdpr->size < 46) + goto fail; mdpr->object_version=_X_BE_16(&data[8]); if (mdpr->object_version != 0) { @@ -310,21 +357,40 @@ static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { mdpr->duration=_X_BE_32(&data[36]); mdpr->stream_name_size=data[40]; - mdpr->stream_name = malloc(sizeof(char)*(mdpr->stream_name_size+1)); + if (mdpr->size < 46 + mdpr->stream_name_size) + goto fail; + mdpr->stream_name = malloc(mdpr->stream_name_size+1); + if (!mdpr->stream_name) + goto fail; memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size); mdpr->stream_name[mdpr->stream_name_size]=0; mdpr->mime_type_size=data[41+mdpr->stream_name_size]; - mdpr->mime_type = malloc(sizeof(char)*(mdpr->mime_type_size+1)); + if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size) + goto fail; + mdpr->mime_type = malloc(mdpr->mime_type_size+1); + if (!mdpr->mime_type) + goto fail; memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size); mdpr->mime_type[mdpr->mime_type_size]=0; mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); - mdpr->type_specific_data = malloc(sizeof(char)*(mdpr->type_specific_len)); + if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data) + goto fail; + mdpr->type_specific_data = malloc(mdpr->type_specific_len); + if (!mdpr->type_specific_data) + goto fail; memcpy(mdpr->type_specific_data, &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); return mdpr; + +fail: + free (mdpr->stream_name); + free (mdpr->mime_type); + free (mdpr->type_specific_data); + free (mdpr); + return NULL; } static rmff_cont_t *rmff_scan_cont(const char *data) { @@ -340,22 +406,22 @@ static rmff_cont_t *rmff_scan_cont(const char *data) { lprintf("warning: unknown object version in CONT: 0x%04x\n", cont->object_version); } cont->title_len=_X_BE_16(&data[10]); - cont->title = malloc(sizeof(char)*(cont->title_len+1)); + cont->title = malloc(cont->title_len+1); memcpy(cont->title, &data[12], cont->title_len); cont->title[cont->title_len]=0; pos=cont->title_len+12; cont->author_len=_X_BE_16(&data[pos]); - cont->author = malloc(sizeof(char)*(cont->author_len+1)); + cont->author = malloc(cont->author_len+1); memcpy(cont->author, &data[pos+2], cont->author_len); cont->author[cont->author_len]=0; pos=pos+2+cont->author_len; cont->copyright_len=_X_BE_16(&data[pos]); - cont->copyright = malloc(sizeof(char)*(cont->copyright_len+1)); + cont->copyright = malloc(cont->copyright_len+1); memcpy(cont->copyright, &data[pos+2], cont->copyright_len); cont->copyright[cont->copyright_len]=0; pos=pos+2+cont->copyright_len; cont->comment_len=_X_BE_16(&data[pos]); - cont->comment = malloc(sizeof(char)*(cont->comment_len+1)); + cont->comment = malloc(cont->comment_len+1); memcpy(cont->comment, &data[pos+2], cont->comment_len); cont->comment[cont->comment_len]=0; @@ -403,10 +469,7 @@ rmff_header_t *rmff_scan_header(const char *data) { header->fileheader=rmff_scan_fileheader(ptr); ptr += header->fileheader->size; - header->streams = malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers)); - for (i=0; i<header->fileheader->num_headers; i++) { - header->streams[i]=NULL; - } + header->streams = calloc(header->fileheader->num_headers, sizeof(rmff_mdpr_t*)); for (i=1; i<header->fileheader->num_headers; i++) { chunk_type = _X_BE_32(ptr); @@ -425,8 +488,11 @@ rmff_header_t *rmff_scan_header(const char *data) { break; case MDPR_TAG: mdpr=rmff_scan_mdpr(ptr); - chunk_size=mdpr->size; - header->streams[mdpr->stream_number]=mdpr; + if (mdpr) /* FIXME: what to do if NULL? */ + { + chunk_size=mdpr->size; + header->streams[mdpr->stream_number]=mdpr; + } break; case CONT_TAG: header->cont=rmff_scan_cont(ptr); @@ -586,7 +652,7 @@ rmff_mdpr_t *rmff_new_mdpr( mdpr->mime_type_size=strlen(mime_type); } mdpr->type_specific_len=type_specific_len; - mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len); + mdpr->type_specific_data = malloc(type_specific_len); memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); mdpr->mlti_data=NULL; diff --git a/src/input/libreal/rmff.h b/src/input/libreal/rmff.h index d39942088..50656349d 100644 --- a/src/input/libreal/rmff.h +++ b/src/input/libreal/rmff.h @@ -32,13 +32,19 @@ #include <string.h> #include <inttypes.h> - #ifndef HAVE_RMFF_H #define HAVE_RMFF_H +#include "attributes.h" #define RMFF_HEADER_SIZE 0x12 +#define RMFF_FILEHEADER_SIZE 18 +#define RMFF_PROPHEADER_SIZE 50 +#define RMFF_MDPRHEADER_SIZE 46 +#define RMFF_CONTHEADER_SIZE 18 +#define RMFF_DATAHEADER_SIZE 18 + #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ (((long)(unsigned char)(ch3) ) | \ ( (long)(unsigned char)(ch2) << 8 ) | \ @@ -214,7 +220,7 @@ rmff_data_t *rmff_new_dataheader( /* * reads header infos from data and returns a newly allocated header struct */ -rmff_header_t *rmff_scan_header(const char *data); +rmff_header_t *rmff_scan_header(const char *data) XINE_MALLOC; /* * scans a data packet header. Notice, that this function does not allocate @@ -225,7 +231,7 @@ void rmff_scan_pheader(rmff_pheader_t *h, char *data); /* * reads header infos from stream and returns a newly allocated header struct */ -rmff_header_t *rmff_scan_header_stream(int fd); +rmff_header_t *rmff_scan_header_stream(int fd) XINE_MALLOC; /* * prints header information in human readible form to stdout @@ -245,7 +251,7 @@ int rmff_get_header_size(rmff_header_t *h); /* * dumps the header <h> to <buffer>. <max> is the size of <buffer> */ -int rmff_dump_header(rmff_header_t *h, char *buffer, int max); +int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max); /* * dumps a packet header diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c index c62b6bbc1..a07cb3360 100644 --- a/src/input/libreal/sdpplin.c +++ b/src/input/libreal/sdpplin.c @@ -19,6 +19,10 @@ * * sdp/sdpplin parser. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #define LOG_MODULE "sdpplin" #define LOG_VERBOSE @@ -60,7 +64,8 @@ static char *b64_decode(const char *in, char *out, int *size) 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,7 +104,7 @@ 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) @@ -120,9 +125,9 @@ static int filter(const char *in, const char *filter, char **out) { 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; @@ -143,7 +148,14 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { 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); } @@ -199,7 +211,7 @@ 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); @@ -232,7 +244,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { 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); @@ -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; } @@ -293,8 +308,15 @@ sdpplin_t *sdpplin_parse(char *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); } diff --git a/src/input/libreal/sdpplin.h b/src/input/libreal/sdpplin.h index cb3b434d4..1604ee38c 100644 --- a/src/input/libreal/sdpplin.h +++ b/src/input/libreal/sdpplin.h @@ -37,7 +37,7 @@ typedef struct { char *id; char *bandwidth; - int stream_id; + uint16_t stream_id; char *range; char *length; char *rtpmap; @@ -81,7 +81,7 @@ typedef struct { int flags; int is_real_data_type; - int stream_count; + uint16_t stream_count; char *title; char *author; char *copyright; @@ -101,7 +101,7 @@ typedef struct { } sdpplin_t; -sdpplin_t *sdpplin_parse(char *data); +sdpplin_t *sdpplin_parse(char *data) XINE_MALLOC; void sdpplin_free(sdpplin_t *description); |