summaryrefslogtreecommitdiff
path: root/libavformat/rtmppkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/rtmppkt.c')
-rw-r--r--libavformat/rtmppkt.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 378328de06..1d07c18778 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
{
const uint8_t *base = data;
+ AMFDataType type;
+ unsigned nb = -1;
+ int parse_key = 1;
if (data >= data_end)
return -1;
- switch (*data++) {
+ switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER: return 9;
case AMF_DATA_TYPE_BOOL: return 2;
case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data);
case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
case AMF_DATA_TYPE_NULL: return 1;
case AMF_DATA_TYPE_ARRAY:
- data += 4;
+ parse_key = 0;
+ case AMF_DATA_TYPE_MIXEDARRAY:
+ nb = bytestream_get_be32(&data);
case AMF_DATA_TYPE_OBJECT:
- for (;;) {
- int size = bytestream_get_be16(&data);
+ while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
int t;
- if (!size) {
- data++;
- break;
+ if (parse_key) {
+ int size = bytestream_get_be16(&data);
+ if (!size) {
+ data++;
+ break;
+ }
+ if (size < 0 || size >= data_end - data)
+ return -1;
+ data += size;
}
- if (size < 0 || size >= data_end - data)
- return -1;
- data += size;
t = ff_amf_tag_size(data, data_end);
if (t < 0 || t >= data_end - data)
return -1;
@@ -474,12 +481,14 @@ static const char* rtmp_packet_type(int type)
static void amf_tag_contents(void *ctx, const uint8_t *data,
const uint8_t *data_end)
{
- unsigned int size;
+ unsigned int size, nb = -1;
char buf[1024];
+ AMFDataType type;
+ int parse_key = 1;
if (data >= data_end)
return;
- switch (*data++) {
+ switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER:
av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data)));
return;
@@ -488,7 +497,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
return;
case AMF_DATA_TYPE_STRING:
case AMF_DATA_TYPE_LONG_STRING:
- if (data[-1] == AMF_DATA_TYPE_STRING) {
+ if (type == AMF_DATA_TYPE_STRING) {
size = bytestream_get_be16(&data);
} else {
size = bytestream_get_be32(&data);
@@ -502,22 +511,28 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
av_log(ctx, AV_LOG_DEBUG, " NULL\n");
return;
case AMF_DATA_TYPE_ARRAY:
- data += 4;
+ parse_key = 0;
+ case AMF_DATA_TYPE_MIXEDARRAY:
+ nb = bytestream_get_be32(&data);
case AMF_DATA_TYPE_OBJECT:
av_log(ctx, AV_LOG_DEBUG, " {\n");
- for (;;) {
+ while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
int t;
- size = bytestream_get_be16(&data);
- av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
- if (!size) {
- av_log(ctx, AV_LOG_DEBUG, " }\n");
- data++;
- break;
+ if (parse_key) {
+ size = bytestream_get_be16(&data);
+ size = FFMIN(size, sizeof(buf) - 1);
+ if (!size) {
+ av_log(ctx, AV_LOG_DEBUG, " }\n");
+ data++;
+ break;
+ }
+ memcpy(buf, data, size);
+ buf[size] = 0;
+ if (size >= data_end - data)
+ return;
+ data += size;
+ av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
}
- if (size >= data_end - data)
- return;
- data += size;
- av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
amf_tag_contents(ctx, data, data_end);
t = ff_amf_tag_size(data, data_end);
if (t < 0 || t >= data_end - data)