RF64: Fix an RF64_AUTO_DOWNGRADE bug

Also add a test for this. The test is disabled by default because it
needs to write a 4 Gig file.

Closes: https://github.com/erikd/libsndfile/issues/238
This commit is contained in:
Erik de Castro Lopo 2017-04-16 10:44:28 +10:00
parent a3287d88eb
commit bf83b95fd9
2 changed files with 60 additions and 2 deletions

View File

@ -339,6 +339,11 @@ rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
} ; } ;
break ; break ;
case PAD_MARKER :
psf_log_printf (psf, "%M : %d\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", chunk_size) ;
break ;
default : default :
if (chunk_size >= 0xffff0000) if (chunk_size >= 0xffff0000)
{ psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %u. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ; { psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %u. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ;
@ -659,7 +664,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
if (wpriv->rf64_downgrade && psf->filelength < RIFF_DOWNGRADE_BYTES) if (wpriv->rf64_downgrade && psf->filelength < RIFF_DOWNGRADE_BYTES)
{ psf_binheader_writef (psf, "etm8m", RIFF_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8, WAVE_MARKER) ; { psf_binheader_writef (psf, "etm8m", RIFF_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8, WAVE_MARKER) ;
psf_binheader_writef (psf, "m4884", JUNK_MARKER, 20, 0, 0, 0, 0) ; psf_binheader_writef (psf, "m4z", JUNK_MARKER, 24, 24) ;
add_fact_chunk = 1 ; add_fact_chunk = 1 ;
} }
else else

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2001-2016 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2001-2017 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software ; you can redistribute it and/or modify ** This program is free software ; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
@ -52,6 +52,7 @@ static void filesystem_full_test (int format) ;
static void permission_test (const char *filename, int typemajor) ; static void permission_test (const char *filename, int typemajor) ;
static void wavex_amb_test (const char *filename) ; static void wavex_amb_test (const char *filename) ;
static void rf64_downgrade_test (const char *filename) ; static void rf64_downgrade_test (const char *filename) ;
static void rf64_long_file_downgrade_test (const char *filename) ;
int int
main (int argc, char *argv []) main (int argc, char *argv [])
@ -145,6 +146,9 @@ main (int argc, char *argv [])
filesystem_full_test (SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ; filesystem_full_test (SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
permission_test ("readonly.rf64", SF_FORMAT_RF64) ; permission_test ("readonly.rf64", SF_FORMAT_RF64) ;
rf64_downgrade_test ("downgrade.wav") ; rf64_downgrade_test ("downgrade.wav") ;
/* Disable this by default, because it needs to write 4 gigabytes of data. */
if (SF_FALSE)
rf64_long_file_downgrade_test ("no-downgrade.rf64") ;
test_count++ ; test_count++ ;
} ; } ;
@ -472,3 +476,52 @@ rf64_downgrade_test (const char *filename)
return ; return ;
} /* rf64_downgrade_test */ } /* rf64_downgrade_test */
static void
rf64_long_file_downgrade_test (const char *filename)
{ static int output [BUFFER_LEN] ;
SNDFILE *file ;
SF_INFO sfinfo ;
sf_count_t k, output_frames = 0 ;
print_test_name (__func__, filename) ;
sf_info_clear (&sfinfo) ;
for (k = 0 ; k < BUFFER_LEN ; k++)
output [k] = 0x1020304 ;
sfinfo.samplerate = 44100 ;
sfinfo.frames = ARRAY_LEN (output) ;
sfinfo.channels = 1 ;
sfinfo.format = SF_FORMAT_RF64 | SF_FORMAT_PCM_32 ;
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_TRUE) != SF_TRUE, "\n\nLine %d: sf_command failed.\n", __LINE__) ;
while (output_frames * sizeof (output [0]) < 0x100000000)
{ test_write_int_or_die (file, 0, output, ARRAY_LEN (output), __LINE__) ;
output_frames += ARRAY_LEN (output) ;
} ;
sf_close (file) ;
sf_info_clear (&sfinfo) ;
file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
exit_if_true (sfinfo.format != (SF_FORMAT_RF64 | SF_FORMAT_PCM_32), "\n\nLine %d: RF64 to WAV downgrade should have failed.\n", __LINE__) ;
exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ;
exit_if_true (sfinfo.frames != output_frames, "\n\nLine %d: Incorrect number of frames in file (%d should be %d).\n", __LINE__, (int) sfinfo.frames, (int) output_frames) ;
check_log_buffer_or_die (file, __LINE__) ;
sf_close (file) ;
puts ("ok") ;
unlink (filename) ;
return ;
} /* rf64_long_file_downgrade_test */