[FFmpeg-soc] [soc]: r4767 - in rtmp: rtmppkt.c rtmppkt.h rtmpproto.c
kostya
subversion at mplayerhq.hu
Wed Jul 22 09:06:26 CEST 2009
Author: kostya
Date: Wed Jul 22 09:06:25 2009
New Revision: 4767
Log:
When working with AMF data, don't forget about buffer boundaries
Modified:
rtmp/rtmppkt.c
rtmp/rtmppkt.h
rtmp/rtmpproto.c
Modified: rtmp/rtmppkt.c
==============================================================================
--- rtmp/rtmppkt.c Wed Jul 22 08:54:22 2009 (r4766)
+++ rtmp/rtmppkt.c Wed Jul 22 09:06:25 2009 (r4767)
@@ -187,10 +187,12 @@ void ff_rtmp_packet_destroy(RTMPPacket *
pkt->data_size = 0;
}
-int ff_amf_skip_data(const uint8_t *data)
+int ff_amf_skip_data(const uint8_t *data, const uint8_t *data_end)
{
const uint8_t *base = data;
+ if (data >= data_end)
+ return -1;
switch (*data++) {
case AMF_DATA_TYPE_NUMBER: return 9;
case AMF_DATA_TYPE_BOOL: return 2;
@@ -202,12 +204,18 @@ int ff_amf_skip_data(const uint8_t *data
case AMF_DATA_TYPE_OBJECT:
for (;;) {
int size = bytestream_get_be16(&data);
+ int t;
if (!size) {
data++;
break;
}
data += size;
- data += ff_amf_skip_data(data);
+ if (data >= data_end)
+ return -1;
+ t = ff_amf_skip_data(data, data_end);
+ if (t < 0 || data + t >= data_end)
+ return -1;
+ data += t;
}
return data - base;
case AMF_DATA_TYPE_OBJECT_END: return 1;
@@ -215,12 +223,14 @@ int ff_amf_skip_data(const uint8_t *data
}
}
-int ff_amf_find_field(const uint8_t *data, const uint8_t *name,
+int ff_amf_find_field(const uint8_t *data, const uint8_t *data_end, const uint8_t *name,
uint8_t *dst, int dst_size)
{
int namelen = strlen(name);
int len;
+ if (data >= data_end - 3)
+ return -1;
if (*data++ != AMF_DATA_TYPE_OBJECT)
return -1;
for (;;) {
@@ -228,6 +238,8 @@ int ff_amf_find_field(const uint8_t *dat
if (!size)
break;
data += size;
+ if (data >= data_end)
+ return -1;
if (size == namelen && !memcmp(data-size, name, namelen)) {
switch (*data++) {
case AMF_DATA_TYPE_NUMBER:
@@ -244,8 +256,8 @@ int ff_amf_find_field(const uint8_t *dat
return -1;
}
}
- len = ff_amf_skip_data(data);
- if (len < 0)
+ len = ff_amf_skip_data(data, data_end);
+ if (len < 0 || data + len >= data_end)
return -1;
data += len;
}
Modified: rtmp/rtmppkt.h
==============================================================================
--- rtmp/rtmppkt.h Wed Jul 22 08:54:22 2009 (r4766)
+++ rtmp/rtmppkt.h Wed Jul 22 09:06:25 2009 (r4767)
@@ -136,20 +136,22 @@ int ff_rtmp_packet_write(URLContext *h,
* Calculates number of bytes needed to skip first AMF entry in data.
*
* @param data input data
+ * @param data_end input buffer end
* @return number of bytes used by first AMF entry
*/
-int ff_amf_skip_data(const uint8_t *data);
+int ff_amf_skip_data(const uint8_t *data, const uint8_t *data_end);
/**
* Retrieves value of given AMF object field in string form.
*
* @param data AMF object data
+ * @param data_end input buffer end
* @param name name of field to retrieve
* @param dst buffer for storing result
* @param dst_size output buffer size
* @return 0 if search and retrieval succeeded, negative value otherwise
*/
-int ff_amf_find_field(const uint8_t *data, const uint8_t *name,
+int ff_amf_find_field(const uint8_t *data, const uint8_t *data_end, const uint8_t *name,
uint8_t *dst, int dst_size);
/**
Modified: rtmp/rtmpproto.c
==============================================================================
--- rtmp/rtmpproto.c Wed Jul 22 08:54:22 2009 (r4766)
+++ rtmp/rtmpproto.c Wed Jul 22 09:06:25 2009 (r4767)
@@ -402,7 +402,7 @@ static int rtmp_parse_result(URLContext
if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
uint8_t tmpstr[256];
- if (!ff_amf_find_field(pkt->data + 9, "description", tmpstr, sizeof(tmpstr)))
+ if (!ff_amf_find_field(pkt->data + 9, pkt->data + pkt->data_size, "description", tmpstr, sizeof(tmpstr)))
av_log(NULL/*s*/, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
return -1;
}
@@ -430,18 +430,18 @@ static int rtmp_parse_result(URLContext
int t;
for (i = 0; i < 2; i++) {
- t = ff_amf_skip_data(ptr);
+ t = ff_amf_skip_data(ptr, pkt->data + pkt->data_size);
if (t < 0)
return 1;
ptr += t;
}
- t = ff_amf_find_field(ptr, "level", tmpstr, sizeof(tmpstr));
+ t = ff_amf_find_field(ptr, pkt->data + pkt->data_size, "level", tmpstr, sizeof(tmpstr));
if (!t && !strcmp(tmpstr, "error")) {
- if (!ff_amf_find_field(ptr, "description", tmpstr, sizeof(tmpstr)))
+ if (!ff_amf_find_field(ptr, pkt->data + pkt->data_size, "description", tmpstr, sizeof(tmpstr)))
av_log(NULL/*s*/, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
return -1;
}
- t = ff_amf_find_field(ptr, "code", tmpstr, sizeof(tmpstr));
+ t = ff_amf_find_field(ptr, pkt->data + pkt->data_size, "code", tmpstr, sizeof(tmpstr));
if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) {
rt->state = STATE_PLAYING;
return 0;
More information about the FFmpeg-soc
mailing list