--- sndhdr.py.orig 2008-09-16 13:21:41.000000000 +0200 +++ /usr/lib/python2.5/sndhdr.py 2008-09-16 13:38:35.000000000 +0200 @@ -126,15 +126,38 @@ tests.append(test_voc) +# This list of chunk types and parts of below code are based on the WAV +# description at +# http://www.sonicspot.com/guide/wavefiles.html#wavefileheader +# bext and fake are taken from a file found at +# http://bugs.python.org/issue1611944 +chunk_types = ['fmt ', 'data', 'fact', 'wavl', 'sint', 'cue ', 'plst', + 'list', 'labl', 'note', 'ltxt', 'smpl', 'inst', 'bext', 'fake'] def test_wav(h, f): # 'RIFF' 'WAVE' 'fmt ' - if h[:4] != 'RIFF' or h[8:12] != 'WAVE' or h[12:16] != 'fmt ': + if h[:4] != 'RIFF' or h[8:12] != 'WAVE': return None - style = get_short_le(h[20:22]) - nchannels = get_short_le(h[22:24]) - rate = get_long_le(h[24:28]) - sample_bits = get_short_le(h[34:36]) + offset = 12 + + # Now, look for the first fmt chunk. Chunks start with two fields, + # one for chunk type and one for chunk length. + while (h[offset:offset+4].lower() != 'fmt '): + # This check and the chunk_types variable above should probably + # be removed + if (not h[offset:offset+4].lower() in chunk_types): + # Wrong header? Probably not a wave file after all + return None + offset = offset + ( get_long_le( h[offset+4:offset+8] ) + 8 ) + # We need to read at least 24 bytes from offset to find the fmt + # info + if offset + 24 > len(h): + return + + style = get_short_le(h[offset+8:offset+10]) + nchannels = get_short_le(h[offset+10:offset+12]) + rate = get_long_le(h[offset+12:offset+16]) + sample_bits = get_short_le(h[offset+22:offset+24]) return 'wav', rate, nchannels, -1, sample_bits tests.append(test_wav)