1.1 --- a/src/codecs/music_mad.c Thu Dec 05 01:56:50 2019 +0300
1.2 +++ b/src/codecs/music_mad.c Sat Dec 07 14:10:24 2019 +0300
1.3 @@ -305,12 +305,14 @@
1.4 }
1.5 return SDL_TRUE;
1.6 }
1.7 -static SDL_INLINE long get_ape_len(const unsigned char *data, long datalen, Uint32 *version)
1.8 +static SDL_INLINE long get_ape_len(const unsigned char *data)
1.9 {
1.10 + Uint32 flags, version;
1.11 long size = (long)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]);
1.12 - *version = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]);
1.13 - (void)datalen;
1.14 - return size; /* caller will handle the additional v2 header length */
1.15 + version = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]);
1.16 + flags = (Uint32)((data[23]<<24) | (data[22]<<16) | (data[21]<<8) | data[20]);
1.17 + if (version == 2000U && (flags & (1U<<31))) size += 32; /* header present. */
1.18 + return size;
1.19 }
1.20
1.21 static int skip_tags(MAD_Music *music)
1.22 @@ -328,11 +330,10 @@
1.23 music->length -= len;
1.24 MAD_RWseek(music, 0, RW_SEEK_SET);
1.25 }
1.26 - /* APE tag _might_ be at the start: read the header */
1.27 + /* APE tag _might_ be at the start (discouraged
1.28 + * but not forbidden, either.) read the header. */
1.29 else if (is_apetag(music->input_buffer, readsize)) {
1.30 - Uint32 v;
1.31 - len = get_ape_len(music->input_buffer, (long)readsize, &v);
1.32 - len += 32; /* we're at top: have a header. */
1.33 + len = get_ape_len(music->input_buffer);
1.34 if (len >= music->length) return -1;
1.35 music->start += len;
1.36 music->length -= len;
1.37 @@ -348,29 +349,10 @@
1.38 if (is_id3v1(music->input_buffer, 128)) {
1.39 music->length -= 128;
1.40
1.41 - /* APE tag may be before the ID3v1: read the footer */
1.42 - if (music->length < 32) goto end;
1.43 - MAD_RWseek(music, -32, RW_SEEK_END);
1.44 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.45 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.46 - if (readsize != 32) return -1;
1.47 - if (is_apetag(music->input_buffer, 32)) {
1.48 - Uint32 v;
1.49 - len = get_ape_len(music->input_buffer, (long)readsize, &v);
1.50 - if (v == 2000U) len += 32; /* header */
1.51 - if (len >= music->length) return -1;
1.52 - if (v == 2000U) { /* verify header : */
1.53 - MAD_RWseek(music, -len, RW_SEEK_END);
1.54 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.55 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.56 - if (readsize != 32) return -1;
1.57 - if (!is_apetag(music->input_buffer, 32)) return -1;
1.58 - }
1.59 - music->length -= len;
1.60 - goto end;
1.61 - }
1.62 - /* extended ID3v1 just before the ID3v1 tag? (unlikely) */
1.63 - if (music->length < 227) goto end;
1.64 + /* extended ID3v1 just before the ID3v1 tag? (unlikely)
1.65 + * if found, assume no additional tags: this stupidity
1.66 + * is non-standard.. */
1.67 + if (music->length < 227) goto ape;
1.68 MAD_RWseek(music, -227, RW_SEEK_END);
1.69 readsize = MAD_RWread(music, music->input_buffer, 1, 227);
1.70 MAD_RWseek(music, 0, RW_SEEK_SET);
1.71 @@ -379,7 +361,10 @@
1.72 music->length -= 227;
1.73 goto end;
1.74 }
1.75 +
1.76 + /* FIXME: handle possible double-ID3v1 tags? */
1.77 }
1.78 +
1.79 ape: /* APE tag may be at the end: read the footer */
1.80 if (music->length >= 32) {
1.81 MAD_RWseek(music, -32, RW_SEEK_END);
1.82 @@ -387,17 +372,8 @@
1.83 MAD_RWseek(music, 0, RW_SEEK_SET);
1.84 if (readsize != 32) return -1;
1.85 if (is_apetag(music->input_buffer, 32)) {
1.86 - Uint32 v;
1.87 - len = get_ape_len(music->input_buffer, (long)readsize, &v);
1.88 - if (v == 2000U) len += 32; /* header */
1.89 + len = get_ape_len(music->input_buffer);
1.90 if (len >= music->length) return -1;
1.91 - if (v == 2000U) { /* verify header : */
1.92 - MAD_RWseek(music, -len, RW_SEEK_END);
1.93 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.94 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.95 - if (readsize != 32) return -1;
1.96 - if (!is_apetag(music->input_buffer, 32)) return -1;
1.97 - }
1.98 music->length -= len;
1.99 }
1.100 }