check size of peak file before attempting to use it. Rebuild from scratch if necessary.
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 3 Jun 2015 17:47:58 +0000 (13:47 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 3 Jun 2015 17:47:58 +0000 (13:47 -0400)
libs/ardour/audiosource.cc

index f9dcaf23c508c689645724a8a6f960ab14c0aa02..beb53a79bb6db58d7742cb93f53caf8d512f7cd7 100644 (file)
@@ -356,6 +356,33 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t
        framecnt_t read_npeaks = npeaks;
        framecnt_t zero_fill = 0;
 
+       GStatBuf statbuf;
+
+       expected_peaks = (cnt / (double) samples_per_file_peak);
+       if (g_stat (peakpath.c_str(), &statbuf) != 0) {
+               error << string_compose (_("Cannot open peakfile @ %1 for size check (%2)"), peakpath, strerror (errno)) << endmsg;
+               return -1;
+       }
+
+       /* check actual size of the peakfile is at least large enough for all
+        * the data in the audio file. if it is too short, assume that a crash
+        * or other error truncated it, and rebuild it from scratch.
+        */
+       
+       const off_t expected_file_size = (_length / (double) samples_per_file_peak) * sizeof (PeakData);
+
+       if (statbuf.st_size < expected_file_size) {
+               warning << string_compose (_("peak file %1 is truncated from %2 to %3"), peakpath, expected_file_size, statbuf.st_size) << endmsg;
+               const_cast<AudioSource*>(this)->build_peaks_from_scratch ();
+               if (g_stat (peakpath.c_str(), &statbuf) != 0) {
+                       error << string_compose (_("Cannot open peakfile @ %1 for size check (%2) after rebuild"), peakpath, strerror (errno)) << endmsg;
+               }
+               if (statbuf.st_size < expected_file_size) {
+                       fatal << "peak file is still truncated after rebuild" << endmsg;
+                       /*NOTREACHED*/
+               }
+       }
+
        ScopedFileDescriptor sfd (::open (peakpath.c_str(), O_RDONLY));
 
        if (sfd < 0) {
@@ -363,9 +390,9 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t
                return -1;
        }
                                  
-       expected_peaks = (cnt / (double) samples_per_file_peak);
        scale = npeaks/expected_peaks;
 
+
        DEBUG_TRACE (DEBUG::Peaks, string_compose (" ======>RP: npeaks = %1 start = %2 cnt = %3 len = %4 samples_per_visual_peak = %5 expected was %6 ... scale =  %7 PD ptr = %8\n"
                        , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));