mirror of https://github.com/mpv-player/mpv
Some sanity and bound checking
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12267 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
ebfa939727
commit
31d8127a15
|
@ -35,6 +35,7 @@
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
#include "asmrp.h"
|
#include "asmrp.h"
|
||||||
#include "sdpplin.h"
|
#include "sdpplin.h"
|
||||||
|
#include "xbuffer.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define LOG
|
#define LOG
|
||||||
|
@ -422,7 +423,7 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe
|
||||||
* returns a pointer to selected data and number of bytes in that.
|
* 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 numrules, codec, size;
|
||||||
int i;
|
int i;
|
||||||
|
@ -437,7 +438,7 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
printf("libreal: MLTI tag not detected, copying data\n");
|
printf("libreal: MLTI tag not detected, copying data\n");
|
||||||
#endif
|
#endif
|
||||||
memcpy(out, mlti_chunk, mlti_size);
|
*out = xbuffer_copyin(*out, 0, mlti_chunk, mlti_size);
|
||||||
return mlti_size;
|
return mlti_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +479,7 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
hexdump(mlti_chunk+4, size);
|
hexdump(mlti_chunk+4, size);
|
||||||
#endif
|
#endif
|
||||||
memcpy(out,mlti_chunk+4, size);
|
*out = xbuffer_copyin(*out, 0, mlti_chunk+4, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,11 +487,11 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
|
||||||
* looking at stream description.
|
* 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;
|
sdpplin_t *desc;
|
||||||
rmff_header_t *header;
|
rmff_header_t *header;
|
||||||
char buf[2048];
|
char *buf;
|
||||||
int len, i;
|
int len, i;
|
||||||
int max_bit_rate=0;
|
int max_bit_rate=0;
|
||||||
int avg_bit_rate=0;
|
int avg_bit_rate=0;
|
||||||
|
@ -505,6 +506,7 @@ rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth
|
||||||
|
|
||||||
if (!desc) return NULL;
|
if (!desc) return NULL;
|
||||||
|
|
||||||
|
buf = xbuffer_init(2048);
|
||||||
header=calloc(1,sizeof(rmff_header_t));
|
header=calloc(1,sizeof(rmff_header_t));
|
||||||
|
|
||||||
header->fileheader=rmff_new_fileheader(4+desc->stream_count);
|
header->fileheader=rmff_new_fileheader(4+desc->stream_count);
|
||||||
|
@ -535,12 +537,12 @@ rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth
|
||||||
printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id);
|
printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id);
|
||||||
#endif
|
#endif
|
||||||
sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]);
|
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;
|
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(
|
header->streams[i]=rmff_new_mdpr(
|
||||||
desc->stream[i]->stream_id,
|
desc->stream[i]->stream_id,
|
||||||
|
@ -566,8 +568,8 @@ rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth
|
||||||
avg_packet_size=desc->stream[i]->avg_packet_size;
|
avg_packet_size=desc->stream[i]->avg_packet_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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 */
|
(*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */
|
||||||
|
|
||||||
header->prop=rmff_new_prop(
|
header->prop=rmff_new_prop(
|
||||||
max_bit_rate,
|
max_bit_rate,
|
||||||
|
@ -583,11 +585,12 @@ rmff_header_t *real_parse_sdp(char *data, char *stream_rules, uint32_t bandwidth
|
||||||
desc->flags);
|
desc->flags);
|
||||||
|
|
||||||
rmff_fix_header(header);
|
rmff_fix_header(header);
|
||||||
|
buf = xbuffer_free(buf);
|
||||||
|
|
||||||
return header;
|
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;
|
int n=1;
|
||||||
uint8_t header[8];
|
uint8_t header[8];
|
||||||
|
@ -653,9 +656,10 @@ int real_get_rdt_chunk(rtsp_t *rtsp_session, char *buffer) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ph.flags=0;
|
ph.flags=0;
|
||||||
rmff_dump_pheader(&ph, buffer);
|
*buffer = xbuffer_ensure_size(*buffer, 12+size);
|
||||||
|
rmff_dump_pheader(&ph, *buffer);
|
||||||
size-=12;
|
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+12;
|
||||||
}
|
}
|
||||||
|
@ -687,8 +691,8 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
|
||||||
char *challenge1;
|
char *challenge1;
|
||||||
char challenge2[64];
|
char challenge2[64];
|
||||||
char checksum[34];
|
char checksum[34];
|
||||||
char subscribe[256];
|
char *subscribe;
|
||||||
char buf[256];
|
char *buf = xbuffer_init(256);
|
||||||
char *mrl=rtsp_get_mrl(rtsp_session);
|
char *mrl=rtsp_get_mrl(rtsp_session);
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int status;
|
int status;
|
||||||
|
@ -718,6 +722,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
|
||||||
printf("real: got message from server:\n%s\n", alert);
|
printf("real: got message from server:\n%s\n", alert);
|
||||||
}
|
}
|
||||||
rtsp_send_ok(rtsp_session);
|
rtsp_send_ok(rtsp_session);
|
||||||
|
buf = xbuffer_free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,9 +748,14 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
|
||||||
description[size]=0;
|
description[size]=0;
|
||||||
|
|
||||||
/* parse sdp (sdpplin) and create a header and a subscribe string */
|
/* parse sdp (sdpplin) and create a header and a subscribe string */
|
||||||
|
subscribe = xbuffer_init(256);
|
||||||
strcpy(subscribe, "Subscribe: ");
|
strcpy(subscribe, "Subscribe: ");
|
||||||
h=real_parse_sdp(description, subscribe+11, bandwidth);
|
h=real_parse_sdp(description, &subscribe, bandwidth);
|
||||||
if (!h) return NULL;
|
if (!h) {
|
||||||
|
subscribe = xbuffer_free(subscribe);
|
||||||
|
buf = xbuffer_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
rmff_fix_header(h);
|
rmff_fix_header(h);
|
||||||
|
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
|
@ -755,19 +765,24 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
|
||||||
|
|
||||||
/* setup our streams */
|
/* setup our streams */
|
||||||
real_calc_response_and_checksum (challenge2, checksum, challenge1);
|
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);
|
sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum);
|
||||||
rtsp_schedule_field(rtsp_session, buf);
|
rtsp_schedule_field(rtsp_session, buf);
|
||||||
|
buf = xbuffer_ensure_size(buf, strlen(session_id) + 32);
|
||||||
sprintf(buf, "If-Match: %s", session_id);
|
sprintf(buf, "If-Match: %s", session_id);
|
||||||
rtsp_schedule_field(rtsp_session, buf);
|
rtsp_schedule_field(rtsp_session, buf);
|
||||||
rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play");
|
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);
|
sprintf(buf, "%s/streamid=0", mrl);
|
||||||
rtsp_request_setup(rtsp_session,buf);
|
rtsp_request_setup(rtsp_session,buf);
|
||||||
|
|
||||||
if (h->prop->num_streams > 1) {
|
if (h->prop->num_streams > 1) {
|
||||||
rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play");
|
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);
|
sprintf(buf, "If-Match: %s", session_id);
|
||||||
rtsp_schedule_field(rtsp_session, buf);
|
rtsp_schedule_field(rtsp_session, buf);
|
||||||
|
|
||||||
|
buf = xbuffer_ensure_size(buf, strlen(mrl) + 32);
|
||||||
sprintf(buf, "%s/streamid=1", mrl);
|
sprintf(buf, "%s/streamid=1", mrl);
|
||||||
rtsp_request_setup(rtsp_session,buf);
|
rtsp_request_setup(rtsp_session,buf);
|
||||||
}
|
}
|
||||||
|
@ -794,5 +809,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
|
||||||
/* and finally send a play request */
|
/* and finally send a play request */
|
||||||
rtsp_request_play(rtsp_session,NULL);
|
rtsp_request_play(rtsp_session,NULL);
|
||||||
|
|
||||||
|
subscribe = xbuffer_free(subscribe);
|
||||||
|
buf = xbuffer_free(buf);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
* (RealChallenge1 in rtsp). See implementation for details.
|
* (RealChallenge1 in rtsp). See implementation for details.
|
||||||
*/
|
*/
|
||||||
void real_calc_response_and_checksum (char *response, char *chksum, char *challenge);
|
void real_calc_response_and_checksum (char *response, char *chksum, char *challenge);
|
||||||
int real_get_rdt_chunk(rtsp_t *rtsp_session, char *buffer);
|
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_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);
|
rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
#include "rmff.h"
|
#include "rmff.h"
|
||||||
#include "asmrp.h"
|
#include "asmrp.h"
|
||||||
|
#include "xbuffer.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define LOG
|
#define LOG
|
||||||
|
@ -58,7 +59,7 @@ struct rtsp_session_s {
|
||||||
rtsp_t *s;
|
rtsp_t *s;
|
||||||
|
|
||||||
/* receive buffer */
|
/* receive buffer */
|
||||||
uint8_t recv[BUF_SIZE];
|
uint8_t *recv;
|
||||||
int recv_size;
|
int recv_size;
|
||||||
int recv_read;
|
int recv_read;
|
||||||
|
|
||||||
|
@ -78,6 +79,8 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i
|
||||||
rmff_header_t *h;
|
rmff_header_t *h;
|
||||||
uint32_t bandwidth=10485800;
|
uint32_t bandwidth=10485800;
|
||||||
|
|
||||||
|
rtsp_session->recv = xbuffer_init(BUF_SIZE);
|
||||||
|
|
||||||
//connect:
|
//connect:
|
||||||
*redir = 0;
|
*redir = 0;
|
||||||
|
|
||||||
|
@ -86,6 +89,7 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i
|
||||||
if (!rtsp_session->s)
|
if (!rtsp_session->s)
|
||||||
{
|
{
|
||||||
printf("rtsp_session: failed to connect to server %s\n", path);
|
printf("rtsp_session: failed to connect to server %s\n", path);
|
||||||
|
rtsp_session->recv = xbuffer_free(rtsp_session->recv);
|
||||||
free(rtsp_session);
|
free(rtsp_session);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +128,7 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i
|
||||||
{
|
{
|
||||||
printf("rtsp_session: session can not be established.\n");
|
printf("rtsp_session: session can not be established.\n");
|
||||||
rtsp_close(rtsp_session->s);
|
rtsp_close(rtsp_session->s);
|
||||||
|
rtsp_session->recv = xbuffer_free(rtsp_session->recv);
|
||||||
free(rtsp_session);
|
free(rtsp_session);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +136,7 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i
|
||||||
|
|
||||||
rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,1024);
|
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_size = rtsp_session->header_len;
|
||||||
rtsp_session->recv_read = 0;
|
rtsp_session->recv_read = 0;
|
||||||
|
|
||||||
|
@ -140,6 +145,7 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i
|
||||||
printf("rtsp_session: Not a Real server. Server type is '%s'.\n",server);
|
printf("rtsp_session: Not a Real server. Server type is '%s'.\n",server);
|
||||||
rtsp_close(rtsp_session->s);
|
rtsp_close(rtsp_session->s);
|
||||||
free(server);
|
free(server);
|
||||||
|
rtsp_session->recv = xbuffer_free(rtsp_session->recv);
|
||||||
free(rtsp_session);
|
free(rtsp_session);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -162,8 +168,8 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
|
||||||
to_copy -= fill;
|
to_copy -= fill;
|
||||||
dest += fill;
|
dest += fill;
|
||||||
this->recv_read = 0;
|
this->recv_read = 0;
|
||||||
|
this->recv_size = real_get_rdt_chunk (this->s, &(this->recv));
|
||||||
source = this->recv;
|
source = this->recv;
|
||||||
this->recv_size = real_get_rdt_chunk (this->s, source);
|
|
||||||
fill = this->recv_size;
|
fill = this->recv_size;
|
||||||
|
|
||||||
if (this->recv_size == 0) {
|
if (this->recv_size == 0) {
|
||||||
|
@ -197,5 +203,6 @@ int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize) {
|
||||||
void rtsp_session_end(rtsp_session_t *session) {
|
void rtsp_session_end(rtsp_session_t *session) {
|
||||||
|
|
||||||
rtsp_close(session->s);
|
rtsp_close(session->s);
|
||||||
|
session->recv = xbuffer_free(session->recv);
|
||||||
free(session);
|
free(session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,13 +96,19 @@ static char *b64_decode(const char *in, char *out, int *size)
|
||||||
|
|
||||||
static char *nl(char *data) {
|
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) {
|
static int filter(const char *in, const char *filter, char **out) {
|
||||||
|
|
||||||
int flen=strlen(filter);
|
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))
|
if (!strncmp(in,filter,flen))
|
||||||
{
|
{
|
||||||
|
@ -135,7 +141,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
|
||||||
}
|
}
|
||||||
*data=nl(*data);
|
*data=nl(*data);
|
||||||
|
|
||||||
while (**data && *data[0]!='m') {
|
while (*data && **data && *data[0]!='m') {
|
||||||
|
|
||||||
handled=0;
|
handled=0;
|
||||||
|
|
||||||
|
@ -236,7 +242,7 @@ sdpplin_t *sdpplin_parse(char *data) {
|
||||||
int handled;
|
int handled;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
while (*data) {
|
while (data && *data) {
|
||||||
|
|
||||||
handled=0;
|
handled=0;
|
||||||
|
|
||||||
|
|
|
@ -85,3 +85,18 @@ void *xbuffer_ensure_size(void *buf, int size) {
|
||||||
|
|
||||||
return buf;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -21,5 +21,6 @@ void *xbuffer_init(int chunk_size);
|
||||||
void *xbuffer_free(void *buf);
|
void *xbuffer_free(void *buf);
|
||||||
void *xbuffer_copyin(void *buf, int index, const void *data, int len);
|
void *xbuffer_copyin(void *buf, int index, const void *data, int len);
|
||||||
void *xbuffer_ensure_size(void *buf, int size);
|
void *xbuffer_ensure_size(void *buf, int size);
|
||||||
|
void *xbuffer_strcat(void *buf, char *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue