changeset 29858:6dc298d3261c

Handle malformed sound headers which do not specify number of frames (bug #60888). * audioread.cc (Faudioinfo): Return -1 for "TotalSamples" and "Duration" fields if number of frames is not specified in audio header. * audioread.cc (Faudioread): Emit an informative error if an attempt is made to read a file which does not specify the number of frames.
author Rik <rik@octave.org>
date Wed, 07 Jul 2021 12:15:11 -0700
parents 0b01806bb663
children 4583e97411a2
files libinterp/dldfcn/audioread.cc
diffstat 1 files changed, 19 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/audioread.cc	Tue Jul 06 23:16:14 2021 -0400
+++ b/libinterp/dldfcn/audioread.cc	Wed Jul 07 12:15:11 2021 -0700
@@ -90,6 +90,12 @@
 
   octave::unwind_action close_open_file ([=] () { sf_close (file); });
 
+  // FIXME: It would be nicer to use a C++ expandable data container and
+  // read a file of unknown length into memory in chunks and determine the
+  // number of samples after reading.  See bug #60888.
+  if (info.frames == SF_COUNT_MAX)
+    error ("audioread: malformed header does not specify number of samples");
+
   OCTAVE_LOCAL_BUFFER (double, data, info.frames * info.channels);
 
   sf_read_double (file, data, info.frames * info.channels);
@@ -624,11 +630,20 @@
   result.assign ("CompressionMethod", "");
   result.assign ("NumChannels", info.channels);
   result.assign ("SampleRate", info.samplerate);
-  result.assign ("TotalSamples", info.frames);
+  double dframes;
+  if (info.frames != SF_COUNT_MAX)
+    dframes = info.frames;
+  else
+    dframes = -1;
+  result.assign ("TotalSamples", dframes);
 
-  double dframes = info.frames;
-  double drate = info.samplerate;
-  result.assign ("Duration", dframes / drate);
+  if (dframes != -1)
+    {
+      double drate = info.samplerate;
+      result.assign ("Duration", dframes / drate);
+    }
+  else
+    result.assign ("Duration", -1);
 
   int bits;
   switch (info.format & SF_FORMAT_SUBMASK)