mirror of https://git.ffmpeg.org/ffmpeg.git
Merge commit 'e930b112d14d7acd050d5087d11b6dd4c56a8e4e' into release/0.10
* commit 'e930b112d14d7acd050d5087d11b6dd4c56a8e4e': oma: refactor seek function 8bps: Bound-check the input buffer rtmp: Do not misuse memcmp Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
1c896e865c
|
@ -69,7 +69,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
|
|||
unsigned char *pixptr, *pixptr_end;
|
||||
unsigned int height = avctx->height; // Real image height
|
||||
unsigned int dlen, p, row;
|
||||
const unsigned char *lp, *dp;
|
||||
const unsigned char *lp, *dp, *ep;
|
||||
unsigned char count;
|
||||
unsigned int planes = c->planes;
|
||||
unsigned char *planemap = c->planemap;
|
||||
|
@ -84,6 +84,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
|
|||
return -1;
|
||||
}
|
||||
|
||||
ep = encoded + buf_size;
|
||||
|
||||
/* Set data pointer after line lengths */
|
||||
dp = encoded + planes * (height << 1);
|
||||
|
||||
|
@ -95,16 +97,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
|
|||
for(row = 0; row < height; row++) {
|
||||
pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p];
|
||||
pixptr_end = pixptr + c->pic.linesize[0];
|
||||
if (ep - lp < row * 2 + 2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
dlen = av_be2ne16(*(const unsigned short *)(lp+row*2));
|
||||
/* Decode a row of this plane */
|
||||
while(dlen > 0) {
|
||||
if(dp + 1 >= buf+buf_size) return -1;
|
||||
if(ep - dp <= 1) return -1;
|
||||
if ((count = *dp++) <= 127) {
|
||||
count++;
|
||||
dlen -= count + 1;
|
||||
if (pixptr + count * planes > pixptr_end)
|
||||
break;
|
||||
if(dp + count > buf+buf_size) return -1;
|
||||
if(ep - dp < count) return -1;
|
||||
while(count--) {
|
||||
*pixptr = *dp++;
|
||||
pixptr += planes;
|
||||
|
|
|
@ -425,22 +425,26 @@ static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t ti
|
|||
{
|
||||
OMAContext *oc = s->priv_data;
|
||||
|
||||
pcm_read_seek(s, stream_index, timestamp, flags);
|
||||
int err = pcm_read_seek(s, stream_index, timestamp, flags);
|
||||
|
||||
if (oc->encrypted) {
|
||||
/* readjust IV for CBC */
|
||||
int64_t pos = avio_tell(s->pb);
|
||||
if (pos < oc->content_start)
|
||||
memset(oc->iv, 0, 8);
|
||||
else {
|
||||
if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
|
||||
memset(oc->iv, 0, 8);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!oc->encrypted)
|
||||
return err;
|
||||
|
||||
/* readjust IV for CBC */
|
||||
if (err || avio_tell(s->pb) < oc->content_start)
|
||||
goto wipe;
|
||||
if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0)
|
||||
goto wipe;
|
||||
if ((err = avio_read(s->pb, oc->iv, 8)) < 8) {
|
||||
if (err >= 0)
|
||||
err = AVERROR_EOF;
|
||||
goto wipe;
|
||||
}
|
||||
|
||||
return 0;
|
||||
wipe:
|
||||
memset(oc->iv, 0, 8);
|
||||
return err;
|
||||
}
|
||||
|
||||
AVInputFormat ff_oma_demuxer = {
|
||||
|
|
|
@ -447,3 +447,36 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
|
|||
av_log(ctx, AV_LOG_DEBUG, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
int ff_amf_match_string(const uint8_t *data, int size, const char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
int amf_len, type;
|
||||
|
||||
if (size < 1)
|
||||
return 0;
|
||||
|
||||
type = *data++;
|
||||
|
||||
if (type != AMF_DATA_TYPE_LONG_STRING &&
|
||||
type != AMF_DATA_TYPE_STRING)
|
||||
return 0;
|
||||
|
||||
if (type == AMF_DATA_TYPE_LONG_STRING) {
|
||||
if ((size -= 4 + 1) < 0)
|
||||
return 0;
|
||||
amf_len = bytestream_get_be32(&data);
|
||||
} else {
|
||||
if ((size -= 2 + 1) < 0)
|
||||
return 0;
|
||||
amf_len = bytestream_get_be16(&data);
|
||||
}
|
||||
|
||||
if (amf_len > size)
|
||||
return 0;
|
||||
|
||||
if (amf_len != len)
|
||||
return 0;
|
||||
|
||||
return !memcmp(data, str, len);
|
||||
}
|
||||
|
|
|
@ -218,6 +218,13 @@ void ff_amf_write_field_name(uint8_t **dst, const char *str);
|
|||
*/
|
||||
void ff_amf_write_object_end(uint8_t **dst);
|
||||
|
||||
/**
|
||||
* Match AMF string with a NULL-terminated string.
|
||||
*
|
||||
* @return 0 if the strings do not match.
|
||||
*/
|
||||
int ff_amf_match_string(const uint8_t *data, int size, const char *str);
|
||||
|
||||
/** @} */ // AMF funcs
|
||||
|
||||
#endif /* AVFORMAT_RTMPPKT_H */
|
||||
|
|
|
@ -588,14 +588,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
|
|||
break;
|
||||
case RTMP_PT_INVOKE:
|
||||
//TODO: check for the messages sent for wrong state?
|
||||
if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
|
||||
if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
|
||||
uint8_t tmpstr[256];
|
||||
|
||||
if (!ff_amf_get_field_value(pkt->data + 9, data_end,
|
||||
"description", tmpstr, sizeof(tmpstr)))
|
||||
av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
|
||||
return -1;
|
||||
} else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
|
||||
} else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
|
||||
switch (rt->state) {
|
||||
case STATE_HANDSHAKED:
|
||||
if (!rt->is_input) {
|
||||
|
@ -636,7 +636,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
|
|||
rt->state = STATE_READY;
|
||||
break;
|
||||
}
|
||||
} else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
|
||||
} else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
|
||||
const uint8_t* ptr = pkt->data + 11;
|
||||
uint8_t tmpstr[256];
|
||||
|
||||
|
@ -724,7 +724,8 @@ static int get_packet(URLContext *s, int for_header)
|
|||
continue;
|
||||
}
|
||||
if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
|
||||
(rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
|
||||
(rpkt.type == RTMP_PT_NOTIFY &&
|
||||
ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) {
|
||||
ts = rpkt.timestamp;
|
||||
|
||||
// generate packet header and put data into buffer for FLV demuxer
|
||||
|
|
Loading…
Reference in New Issue