RF64: Fix an RF64_AUTO_DOWNGRADE bug 27/162527/1
authorErik de Castro Lopo <erikd@mega-nerd.com>
Sun, 16 Apr 2017 00:44:28 +0000 (10:44 +1000)
committerSeungbae Shin <seungbae.shin@samsung.com>
Thu, 30 Nov 2017 06:08:41 +0000 (15:08 +0900)
Also add a test for this. The test is disabled by default because it
needs to write a 4 Gig file.

Change-Id: If9a18f4f6147e08cfa6f7f35ff66131434f0db20
Closes: https://github.com/erikd/libsndfile/issues/238

src/rf64.c
tests/misc_test.c

index a42d474..02dd904 100644 (file)
@@ -339,6 +339,11 @@ rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                                        } ;
                                break ;
 
+                       case PAD_MARKER :
+                               psf_log_printf (psf, "%M : %d\n", marker, chunk_size) ;
+                               psf_binheader_readf (psf, "j", chunk_size) ;
+                               break ;
+
                        default :
                                        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) ;
@@ -659,7 +664,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
 
        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, "m4884", JUNK_MARKER, 20, 0, 0, 0, 0) ;
+               psf_binheader_writef (psf, "m4z", JUNK_MARKER, 24, 24) ;
                add_fact_chunk = 1 ;
                }
        else
index 90a9d01..7352ada 100644 (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
 ** 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    wavex_amb_test (const char *filename) ;
 static void rf64_downgrade_test (const char *filename) ;
+static void rf64_long_file_downgrade_test (const char *filename) ;
 
 int
 main (int argc, char *argv [])
@@ -145,6 +146,9 @@ main (int argc, char *argv [])
                filesystem_full_test (SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
                permission_test ("readonly.rf64", SF_FORMAT_RF64) ;
                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++ ;
                } ;
 
@@ -471,3 +475,52 @@ rf64_downgrade_test (const char *filename)
 
        return ;
 } /* 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 */