]> git.sesse.net Git - ffmpeg/blob - libavformat/oggparseflac.c
prevent infinite loop with VORC012.WMA
[ffmpeg] / libavformat / oggparseflac.c
1 /*
2  *    Copyright (C) 2005  Matthieu CASTET
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include <stdlib.h>
20 #include "avformat.h"
21 #include "bitstream.h"
22 #include "ogg2.h"
23
24 #define FLAC_STREAMINFO_SIZE 0x22
25
26 static int
27 flac_header (AVFormatContext * s, int idx)
28 {
29     ogg_t *ogg = s->priv_data;
30     ogg_stream_t *os = ogg->streams + idx;
31     AVStream *st = s->streams[idx];
32     GetBitContext gb;
33     int mdt;
34
35     if (os->buf[os->pstart] == 0xff)
36         return 0;
37
38     init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
39     get_bits(&gb, 1); /* metadata_last */
40     mdt = get_bits(&gb, 7);
41
42     if (mdt == 0x7f) {
43         skip_bits(&gb, 4*8); /* "FLAC" */
44         if(get_bits(&gb, 8) != 1) /* unsupported major version */
45             return -1;
46         skip_bits(&gb, 8 + 16);      /* minor version + header count */
47         skip_bits(&gb, 4*8); /* "fLaC" */
48
49         /* METADATA_BLOCK_HEADER */
50         if (get_bits(&gb, 32) != FLAC_STREAMINFO_SIZE)
51             return -1;
52
53         skip_bits(&gb, 16*2+24*2);
54
55         st->codec->sample_rate = get_bits_long(&gb, 20);
56         st->codec->channels = get_bits(&gb, 3) + 1;
57
58         st->codec->codec_type = CODEC_TYPE_AUDIO;
59         st->codec->codec_id = CODEC_ID_FLAC;
60
61         st->codec->extradata =
62             av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
63         memcpy (st->codec->extradata, os->buf + os->pstart + 5 + 4 + 4 + 4,
64                 FLAC_STREAMINFO_SIZE);
65         st->codec->extradata_size = FLAC_STREAMINFO_SIZE;
66
67         st->time_base.num = 1;
68         st->time_base.den = st->codec->sample_rate;
69     } else if (mdt == 4) {
70         vorbis_comment (s, os->buf + os->pstart + 4, os->psize - 4);
71     }
72
73     return 1;
74 }
75
76 ogg_codec_t flac_codec = {
77     .magic = "\177FLAC",
78     .magicsize = 5,
79     .header = flac_header
80 };