Revision f8d33a36

View differences:

libavformat/avidec.c
25 25
#include <strings.h>
26 26
#include "libavutil/intreadwrite.h"
27 27
#include "libavutil/bswap.h"
28
#include "libavcodec/bytestream.h"
29 28
#include "avformat.h"
30 29
#include "avi.h"
31 30
#include "dv.h"
......
748 747

  
749 748
static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
750 749
    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
751
        uint8_t desc[256], *d = desc;
752
        uint8_t *end, *ptr = pkt->data+7;
753
        unsigned int size, desc_len = bytestream_get_le32(&ptr);
754
        int score = AVPROBE_SCORE_MAX / 2;
750
        uint8_t desc[256];
751
        int score = AVPROBE_SCORE_MAX / 2, ret;
755 752
        AVIStream *ast = st->priv_data;
756 753
        AVInputFormat *sub_demuxer;
757 754
        AVRational time_base;
758
        ByteIOContext *pb;
755
        ByteIOContext *pb = av_alloc_put_byte(pkt->data + 7,
756
                                              pkt->size - 7,
757
                                              0, NULL, NULL, NULL, NULL);
759 758
        AVProbeData pd;
759
        unsigned int desc_len = get_le32(pb);
760 760

  
761
        if (desc_len > FFMAX(pkt->size-17, 0))
762
            return 0;
761
        if (desc_len > pb->buf_end - pb->buf_ptr)
762
            goto error;
763 763

  
764
        end = ptr + desc_len;
765
        while (ptr < end-1) {
766
            uint8_t tmp;
767
            uint32_t ch;
768
            GET_UTF16(ch, ptr < end-1 ? bytestream_get_le16(&ptr) : 0, break;);
769
            PUT_UTF8(ch, tmp, if(d-desc < sizeof(desc)-1)  *d++ = tmp;);
770
        }
771
        *d = 0;
764
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
765
        url_fskip(pb, desc_len - ret);
772 766
        if (*desc)
773 767
            av_metadata_set2(&st->metadata, "title", desc, 0);
774 768

  
775
        ptr = end + 2;
776
        size = bytestream_get_le32(&ptr);
777
        size = FFMIN(size, pkt->size+pkt->data-ptr);
769
        get_le16(pb);   /* flags? */
770
        get_le32(pb);   /* data size */
778 771

  
779
        pd = (AVProbeData) { .buf = ptr, .buf_size = size };
772
        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
780 773
        if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
781
            return 0;
774
            goto error;
782 775

  
783
        pb = av_alloc_put_byte(ptr, size, 0, NULL, NULL, NULL, NULL);
784 776
        if (!av_open_input_stream(&ast->sub_ctx, pb, "", sub_demuxer, NULL)) {
785 777
            av_read_packet(ast->sub_ctx, &ast->sub_pkt);
786 778
            *st->codec = *ast->sub_ctx->streams[0]->codec;
......
791 783
        ast->sub_buffer = pkt->data;
792 784
        memset(pkt, 0, sizeof(*pkt));
793 785
        return 1;
786
error:
787
        av_freep(&pb);
794 788
    }
795 789
    return 0;
796 790
}

Also available in: Unified diff