- int i, metadata_last, metadata_type, metadata_size, streaminfo_updated=0;
- int initial_pos= get_bits_count(&s->gb);
-
- if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) {
- skip_bits(&s->gb, 32);
-
- do {
- metadata_last = get_bits1(&s->gb);
- metadata_type = get_bits(&s->gb, 7);
- metadata_size = get_bits_long(&s->gb, 24);
-
- if (get_bits_count(&s->gb) + 8*metadata_size > s->gb.size_in_bits) {
- skip_bits_long(&s->gb, initial_pos - get_bits_count(&s->gb));
- break;
- }
-
- if (metadata_size) {
- switch (metadata_type) {
- case METADATA_TYPE_STREAMINFO:
- ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s,
- s->gb.buffer+get_bits_count(&s->gb)/8);
- streaminfo_updated = 1;
-
- default:
- for (i = 0; i < metadata_size; i++)
- skip_bits(&s->gb, 8);
- }
- }
- } while (!metadata_last);
+ int metadata_last, metadata_size;
+ const uint8_t *buf_end = buf + buf_size;
+
+ buf += 4;
+ do {
+ if (buf_end - buf < 4)
+ return 0;
+ avpriv_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
+ buf += 4;
+ if (buf_end - buf < metadata_size) {
+ /* need more data in order to read the complete header */
+ return 0;
+ }
+ buf += metadata_size;
+ } while (!metadata_last);