--- libmpdemux/realrtsp/real.c 2003-12-08 22:57:12.000000000 +0100 +++ libmpdemux/realrtsp/real.c 2004-07-01 15:37:33.000000000 +0200 @@ -35,6 +35,7 @@ #include "real.h" #include "asmrp.h" #include "sdpplin.h" +#include "xbuffer.h" /* #define LOG @@ -422,7 +423,7 @@ * returns a pointer to selected data and number of bytes in that. */ -static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char *out) { +static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { int numrules, codec, size; int i; @@ -437,7 +438,7 @@ #ifdef LOG printf("libreal: MLTI tag not detected, copying data\n"); #endif - memcpy(out, mlti_chunk, mlti_size); + *out = xbuffer_copyin(*out, 0, mlti_chunk, mlti_size); return mlti_size; } @@ -478,7 +479,7 @@ #ifdef LOG hexdump(mlti_chunk+4, size); #endif - memcpy(out,mlti_chunk+4, size); + *out = xbuffer_copyin(*out, 0, mlti_chunk+4, size); return size; } @@ -486,11 +487,11 @@ * looking at stream description. */ -rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth) { +rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { sdpplin_t *desc; rmff_header_t *header; - char buf[2048]; + char *buf; int len, i; int max_bit_rate=0; int avg_bit_rate=0; @@ -505,6 +506,7 @@ if (!desc) return NULL; + buf = xbuffer_init(2048); header=calloc(1,sizeof(rmff_header_t)); header->fileheader=rmff_new_fileheader(4+desc->stream_count); @@ -535,12 +537,12 @@ printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); #endif sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); - strcat(stream_rules, b); + *stream_rules = xbuffer_strcat(*stream_rules, b); } if (!desc->stream[i]->mlti_data) return NULL; - len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], buf); + len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); header->streams[i]=rmff_new_mdpr( desc->stream[i]->stream_id, @@ -566,8 +568,8 @@ avg_packet_size=desc->stream[i]->avg_packet_size; } - if (stream_rules) - stream_rules[strlen(stream_rules)-1]=0; /* delete last ',' in stream_rules */ + if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') + (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ header->prop=rmff_new_prop( max_bit_rate, @@ -583,11 +585,12 @@ desc->flags); rmff_fix_header(header); + buf = xbuffer_free(buf); return header; } -int real_get_rdt_chunk(rtsp_t *rtsp_session, char *buffer) { +int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer) { int n=1; uint8_t header[8]; @@ -653,11 +656,12 @@ } else ph.flags=0; - rmff_dump_pheader(&ph, buffer); + *buffer = xbuffer_ensure_size(*buffer, 12+size); + rmff_dump_pheader(&ph, *buffer); size-=12; - n=rtsp_read_data(rtsp_session, buffer+12, size); + n=rtsp_read_data(rtsp_session, (*buffer)+12, size); - return n+12; + return (n <= 0) ? 0 : n+12; } int convert_timestamp(char *str, int *sec, int *msec) { @@ -687,8 +691,8 @@ char *challenge1; char challenge2[64]; char checksum[34]; - char subscribe[256]; - char buf[256]; + char *subscribe; + char *buf = xbuffer_init(256); char *mrl=rtsp_get_mrl(rtsp_session); unsigned int size; int status; @@ -718,6 +722,7 @@ printf("real: got message from server:\n%s\n", alert); } rtsp_send_ok(rtsp_session); + buf = xbuffer_free(buf); return NULL; } @@ -739,13 +744,21 @@ description=malloc(sizeof(char)*(size+1)); - rtsp_read_data(rtsp_session, description, size); + if( rtsp_read_data(rtsp_session, description, size) <= 0) { + buf = xbuffer_free(buf); + return NULL; + } description[size]=0; /* parse sdp (sdpplin) and create a header and a subscribe string */ + subscribe = xbuffer_init(256); strcpy(subscribe, "Subscribe: "); - h=real_parse_sdp(description, subscribe+11, bandwidth); - if (!h) return NULL; + h=real_parse_sdp(description, &subscribe, bandwidth); + if (!h) { + subscribe = xbuffer_free(subscribe); + buf = xbuffer_free(buf); + return NULL; + } rmff_fix_header(h); #ifdef LOG @@ -755,19 +768,24 @@ /* setup our streams */ real_calc_response_and_checksum (challenge2, checksum, challenge1); + buf = xbuffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32); sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); rtsp_schedule_field(rtsp_session, buf); + buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); + buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=0", mrl); rtsp_request_setup(rtsp_session,buf); if (h->prop->num_streams > 1) { rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); + buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); + buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=1", mrl); rtsp_request_setup(rtsp_session,buf); } @@ -794,5 +812,7 @@ /* and finally send a play request */ rtsp_request_play(rtsp_session,NULL); + subscribe = xbuffer_free(subscribe); + buf = xbuffer_free(buf); return h; } --- libmpdemux/realrtsp/real.h 2003-04-20 16:40:38.000000000 +0200 +++ libmpdemux/realrtsp/real.h 2004-07-01 15:34:18.000000000 +0200 @@ -38,8 +38,8 @@ * (RealChallenge1 in rtsp). See implementation for details. */ void real_calc_response_and_checksum (char *response, char *chksum, char *challenge); -int real_get_rdt_chunk(rtsp_t *rtsp_session, char *buffer); -rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth); +int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer); +rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth); rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth); #endif --- libmpdemux/realrtsp/rtsp.c 2003-11-23 14:35:55.000000000 +0100 +++ libmpdemux/realrtsp/rtsp.c 2004-07-01 15:37:33.000000000 +0200 @@ -73,8 +73,6 @@ unsigned int server_state; uint32_t server_caps; - char buffer[BUF_SIZE]; /* scratch buffer */ - unsigned int cseq; char *session; @@ -271,11 +269,12 @@ static char *rtsp_get(rtsp_t *s) { int n=0; - char *string; + char *buffer = malloc(BUF_SIZE); + char *string = NULL; while (ns, &s->buffer[n], 1); - if ((s->buffer[n-1]==0x0d)&&(s->buffer[n]==0x0a)) break; + read_stream(s->s, &(buffer[n]), 1); + if ((buffer[n-1]==0x0d)&&(buffer[n]==0x0a)) break; n++; } @@ -284,7 +283,7 @@ exit(1); } string=malloc(sizeof(char)*n); - memcpy(string,s->buffer,n-1); + memcpy(string,buffer,n-1); string[n-1]=0; #ifdef LOG @@ -292,6 +291,7 @@ #endif + free(buffer); return string; } @@ -352,8 +352,13 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) { char **payload=s->scheduled; - sprintf(s->buffer,"%s %s %s",type, what, rtsp_protocol_version); - rtsp_put(s,s->buffer); + char *buf; + + buf = malloc(strlen(type)+strlen(what)+strlen(rtsp_protocol_version)+3); + + sprintf(buf,"%s %s %s",type, what, rtsp_protocol_version); + rtsp_put(s,buf); + free(buf); if (payload) while (*payload) { rtsp_put(s,*payload); @@ -369,11 +374,17 @@ static void rtsp_schedule_standard(rtsp_t *s) { - sprintf(s->buffer, "Cseq: %u", s->cseq); - rtsp_schedule_field(s, s->buffer); + char tmp[16]; + + snprintf(tmp, 16, "Cseq: %u", s->cseq); + rtsp_schedule_field(s, tmp); + if (s->session) { - sprintf(s->buffer, "Session: %s", s->session); - rtsp_schedule_field(s, s->buffer); + char *buf; + buf = malloc(strlen(s->session)+15); + sprintf(buf, "Session: %s", s->session); + rtsp_schedule_field(s, buf); + free(buf); } } /* @@ -388,6 +399,8 @@ int code; answer=rtsp_get(s); + if (!answer) + return 0; code=rtsp_get_code(answer); free(answer); @@ -396,6 +409,8 @@ do { /* while we get answer lines */ answer=rtsp_get(s); + if (!answer) + return 0; if (!strncmp(answer,"Cseq:",5)) { sscanf(answer,"Cseq: %u",&answer_seq); @@ -407,26 +422,29 @@ } } if (!strncmp(answer,"Server:",7)) { - sscanf(answer,"Server: %s",s->buffer); + char *buf = malloc(strlen(answer)); + sscanf(answer,"Server: %s",buf); if (s->server) free(s->server); - s->server=strdup(s->buffer); + s->server=strdup(buf); + free(buf); } if (!strncmp(answer,"Session:",8)) { - memset(s->buffer,0, BUF_SIZE); - sscanf(answer,"Session: %s",s->buffer); + char *buf = calloc(1, strlen(answer)); + sscanf(answer,"Session: %s",buf); if (s->session) { - if (strcmp(s->buffer, s->session)) { - printf("rtsp: warning: setting NEW session: %s\n", s->buffer); + if (strcmp(buf, s->session)) { + printf("rtsp: warning: setting NEW session: %s\n", buf); free(s->session); - s->session=strdup(s->buffer); + s->session=strdup(buf); } } else { #ifdef LOG - printf("rtsp: setting session id to: %s\n", s->buffer); + printf("rtsp: setting session id to: %s\n", s->buf); #endif - s->session=strdup(s->buffer); + s->session=strdup(buf); } + free(buf); } *answer_ptr=answer; answer_ptr++; @@ -555,13 +573,15 @@ if ((buffer[0]=='S')&&(buffer[1]=='E')&&(buffer[2]=='T')&&(buffer[3]=='_')) { char *rest=rtsp_get(s); - /* a real server wanna play table tennis? */ - memcpy(s->buffer, buffer, 4); - strcpy(s->buffer+4, rest); + if (!rest) + return -1; + seq=-1; do { free(rest); rest=rtsp_get(s); + if (!rest) + return -1; if (!strncmp(rest,"Cseq:",5)) sscanf(rest,"Cseq: %u",&seq); } while (strlen(rest)!=0); --- libmpdemux/realrtsp/rtsp_session.c 2003-06-11 18:48:08.000000000 +0200 +++ libmpdemux/realrtsp/rtsp_session.c 2004-07-01 15:34:18.000000000 +0200 @@ -45,6 +45,7 @@ #include "real.h" #include "rmff.h" #include "asmrp.h" +#include "xbuffer.h" /* #define LOG @@ -58,7 +59,7 @@ rtsp_t *s; /* receive buffer */ - uint8_t recv[BUF_SIZE]; + uint8_t *recv; int recv_size; int recv_read; @@ -78,6 +79,8 @@ rmff_header_t *h; uint32_t bandwidth=10485800; + rtsp_session->recv = xbuffer_init(BUF_SIZE); + //connect: *redir = 0; @@ -86,6 +89,7 @@ if (!rtsp_session->s) { printf("rtsp_session: failed to connect to server %s\n", path); + rtsp_session->recv = xbuffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } @@ -124,6 +128,7 @@ { printf("rtsp_session: session can not be established.\n"); rtsp_close(rtsp_session->s); + rtsp_session->recv = xbuffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } @@ -131,7 +136,7 @@ rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,1024); - memcpy(rtsp_session->recv, rtsp_session->header, rtsp_session->header_len); + rtsp_session->recv = xbuffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len); rtsp_session->recv_size = rtsp_session->header_len; rtsp_session->recv_read = 0; @@ -140,6 +145,7 @@ printf("rtsp_session: rtsp server type is '%s' instead of Real. Please report.\n",server); rtsp_close(rtsp_session->s); free(server); + rtsp_session->recv = xbuffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } @@ -162,8 +168,8 @@ to_copy -= fill; dest += fill; this->recv_read = 0; + this->recv_size = real_get_rdt_chunk (this->s, &(this->recv)); source = this->recv; - this->recv_size = real_get_rdt_chunk (this->s, source); fill = this->recv_size; if (this->recv_size == 0) { @@ -197,5 +203,6 @@ void rtsp_session_end(rtsp_session_t *session) { rtsp_close(session->s); + session->recv = xbuffer_free(session->recv); free(session); } --- libmpdemux/realrtsp/sdpplin.c 2003-04-17 22:38:57.000000000 +0200 +++ libmpdemux/realrtsp/sdpplin.c 2004-07-01 15:34:18.000000000 +0200 @@ -96,13 +96,19 @@ static char *nl(char *data) { - return strchr(data,'\n')+1; + char *nlptr = (data) ? strchr(data,'\n') : NULL; + return (nlptr) ? nlptr + 1 : NULL; } static int filter(const char *in, const char *filter, char **out) { int flen=strlen(filter); - int len=strchr(in,'\n')-in; + int len; + + if (!in) + return 0; + + len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in); if (!strncmp(in,filter,flen)) { @@ -135,7 +141,7 @@ } *data=nl(*data); - while (**data && *data[0]!='m') { + while (*data && **data && *data[0]!='m') { handled=0; @@ -236,7 +242,7 @@ int handled; int len; - while (*data) { + while (data && *data) { handled=0; --- libmpdemux/realrtsp/xbuffer.c 2003-06-01 22:27:32.000000000 +0200 +++ libmpdemux/realrtsp/xbuffer.c 2004-07-01 15:34:18.000000000 +0200 @@ -85,3 +85,18 @@ return buf; } + + + +void *xbuffer_strcat(void *buf, char *data) { + + if (!buf || !data) { + return NULL; + } + + buf = xbuffer_ensure_size(buf, strlen(buf)+strlen(data)+1); + + strcat(buf, data); + + return buf; +} --- libmpdemux/realrtsp/xbuffer.h 2003-04-17 22:38:57.000000000 +0200 +++ libmpdemux/realrtsp/xbuffer.h 2004-07-01 15:34:18.000000000 +0200 @@ -21,5 +21,6 @@ void *xbuffer_free(void *buf); void *xbuffer_copyin(void *buf, int index, const void *data, int len); void *xbuffer_ensure_size(void *buf, int size); +void *xbuffer_strcat(void *buf, char *data); #endif