marc-q/libwav

Infinite loop in wav_read in libwav.c

fouzhe opened this issue · 1 comments

I use Clang 6.0 and AddressSanitizer to build libwav, this file can cause infinite loop in function wav_read when running the wav_gain in folder tools/wav_gain with the following command:

./wav_gain wav_gain__crash__infinite_loop 1.wav

Here is the gdb information:

(gdb) bt
#0  0x00007ffff6ba7447 in lseek64 () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007ffff6b18571 in _IO_new_file_seekoff (fp=0x61600000fc80, offset=<optimized out>, dir=1, mode=<optimized out>) at fileops.c:1118
#2  0x00007ffff6b15f79 in __GI_fseek (fp=0x61600000fc80, offset=<optimized out>, whence=<optimized out>) at fseek.c:36
#3  0x0000000000401e12 in wav_read (wavfile=0x7fffffffe2c0, filename=0x7fffffffe6f1 "wav_gain__crash__infinite_loop") at ../../libwav.c:268
#4  0x0000000000402121 in gain_file (filename=0x7fffffffe6f1 "wav_gain__crash__infinite_loop", filename_out=0x7fffffffe710 "1.wav") at wav_gain.c:20
#5  0x0000000000402275 in main (argc=3, argv=0x7fffffffe448) at wav_gain.c:43

The infinite loop is caused by this:

	while (!feof (f))
	{
		wav_chunk_read (&chunk, f);
		
		switch (chunk.chunk_id.hash)
		{
			case WAV_CHUNKID_FORMAT:
				wavfile->format = chunk.content.format;
				break;
			case WAV_CHUNKID_DATA:
				wavfile->datablocks = chunk.chunk_size / sizeof (int);
				wavfile->data = chunk.content.data;
				fclose (f);
				return WAV_OK;
			default:
				// NOTE: Unknown chunk!
				fseek (f, chunk.chunk_size, SEEK_CUR);
				break;
		}
	}