shithub: sox

Download patch

ref: 2f0ef325d4588af7a70453547fa6b4d0b703818e
parent: 5d6d8c3f66bb6aad2da4529879a8effbc2fe9efa
author: robs <robs>
date: Sun Jan 21 04:34:39 EST 2007

Fix crash when effect fails to start

--- a/src/sox.c
+++ b/src/sox.c
@@ -93,8 +93,8 @@
 static void update_status(void);
 static void volumechange(st_sample_t * buf, st_ssize_t len, file_info_t fo);
 static void parse_effects(int argc, char **argv);
-static void check_effects(void);
-static int start_effects(void);
+static void build_effects_table(void);
+static int start_all_effects(void);
 static int flow_effect_out(void);
 static int flow_effect(int);
 static int drain_effect_out(void);
@@ -681,7 +681,7 @@
  */
 
 static void process(void) {
-  int e, flowstatus = ST_SUCCESS;
+  int e, flowstatus;
   size_t current_input = 0;
   st_size_t s, f;
   st_ssize_t ilen[MAX_INPUT_FILES];
@@ -762,11 +762,10 @@
   for (f = 0; f < input_count; f++)
     file_desc[f]->signal.rate = file_desc[f]->signal.rate * globalinfo.speed + .5;
 
-  /* build efftab */
-  check_effects();
+  build_effects_table();
 
-  /* Start all effects */
-  flowstatus = start_effects();
+  if (start_all_effects() != ST_SUCCESS)
+    exit(2); /* Failing effect should have displayed an error message */
 
   /* Allocate output buffers for effects */
   for (e = 0; e < neffects; e++) {
@@ -809,135 +808,129 @@
   for(e = 1; e < neffects; e++)
     efftab[e].odone = efftab[e].olen = 0;
       
-  /* If start functions set flowstatus to ST_EOF, skip both flow and
-     drain; we have to have this "if" because after flow flowstatus is
-     supposed to be ST_EOF, so we can't test that in order to know
-     whether to drain. */
-  if (flowstatus == 0) {
-    /* Run input data through effects and get more until olen == 0 
-     * (or ST_EOF) or user-abort.
-     */
-    signal(SIGINT, sigint);
-    signal(SIGTERM, sigint);
-    do {
-      if (combine_method == SOX_CONCAT) {
-        ilen[0] = st_read(file_desc[current_input], efftab[0].obuf, 
-                          (st_ssize_t)ST_BUFSIZ);
-        if (ilen[0] > ST_BUFSIZ) {
-          st_warn("WARNING: Corrupt value of %d!  Assuming 0 bytes read.", ilen);
-          ilen[0] = 0;
+  /* Run input data through effects and get more until olen == 0 
+   * (or ST_EOF) or user-abort.
+   */
+  signal(SIGINT, sigint);
+  signal(SIGTERM, sigint);
+  do {
+    if (combine_method == SOX_CONCAT) {
+      ilen[0] = st_read(file_desc[current_input], efftab[0].obuf, 
+                        (st_ssize_t)ST_BUFSIZ);
+      if (ilen[0] > ST_BUFSIZ) {
+        st_warn("WARNING: Corrupt value of %d!  Assuming 0 bytes read.", ilen);
+        ilen[0] = 0;
+      }
+          
+      if (ilen[0] == ST_EOF) {
+        efftab[0].olen = 0;
+        if (file_desc[current_input]->st_errno)
+          fprintf(stderr, file_desc[current_input]->st_errstr);
+      } else
+        efftab[0].olen = ilen[0];
+          
+      read_samples += efftab[0].olen;
+          
+      /* Some file handlers claim 0 bytes instead of returning
+       * ST_EOF.  In either case, attempt to go to the next
+       * input file.
+       */
+      if (ilen[0] == ST_EOF || efftab[0].olen == 0) {
+        if (current_input < input_count - 1) {
+          current_input++;
+          input_samples = file_desc[current_input]->length;
+          read_samples = 0;
+          show_file_progress(current_input);
+          continue;
         }
-            
-        if (ilen[0] == ST_EOF) {
-          efftab[0].olen = 0;
-          if (file_desc[current_input]->st_errno)
-            fprintf(stderr, file_desc[current_input]->st_errstr);
-        } else
-          efftab[0].olen = ilen[0];
-            
-        read_samples += efftab[0].olen;
-            
-        /* Some file handlers claim 0 bytes instead of returning
-         * ST_EOF.  In either case, attempt to go to the next
-         * input file.
-         */
-        if (ilen[0] == ST_EOF || efftab[0].olen == 0) {
-          if (current_input < input_count - 1) {
-            current_input++;
-            input_samples = file_desc[current_input]->length;
-            read_samples = 0;
-            show_file_progress(current_input);
-            continue;
-          }
+      }
+      volumechange(efftab[0].obuf, efftab[0].olen, file_opts[current_input]);
+    } else if (combine_method == SOX_MIX) {
+      for (f = 0; f < input_count; f++) {
+        ilen[f] = st_read(file_desc[f], ibuf[f], (st_ssize_t)ST_BUFSIZ);
+              
+        if (ilen[f] == ST_EOF) {
+          ilen[f] = 0;
+          if (file_desc[f]->st_errno) 
+            fprintf(stderr, file_desc[f]->st_errstr);
         }
-        volumechange(efftab[0].obuf, efftab[0].olen, file_opts[current_input]);
-      } else if (combine_method == SOX_MIX) {
+              
+        /* Only count read samples for first file in mix */
+        if (f == 0)
+          read_samples += efftab[0].olen;
+        
+        volumechange(ibuf[f], ilen[f], file_opts[f]);
+      }
+      
+      /* FIXME: Should report if the size of the reads are not
+       * the same.
+       */
+      efftab[0].olen = 0;
+      for (f = 0; f < input_count; f++)
+        if ((st_size_t)ilen[f] > efftab[0].olen)
+          efftab[0].olen = ilen[f];
+          
+      for (s = 0; s < efftab[0].olen; s++) {
+        /* Mix audio by summing samples together. 
+         * Input side volume changes are performed above. */
         for (f = 0; f < input_count; f++) {
-          ilen[f] = st_read(file_desc[f], ibuf[f], (st_ssize_t)ST_BUFSIZ);
-                
-          if (ilen[f] == ST_EOF) {
-            ilen[f] = 0;
-            if (file_desc[f]->st_errno) 
-              fprintf(stderr, file_desc[f]->st_errstr);
-          }
-                
-          /* Only count read samples for first file in mix */
           if (f == 0)
-            read_samples += efftab[0].olen;
-          
-          volumechange(ibuf[f], ilen[f], file_opts[f]);
-        }
-        
-        /* FIXME: Should report if the size of the reads are not
-         * the same.
-         */
-        efftab[0].olen = 0;
-        for (f = 0; f < input_count; f++)
-          if ((st_size_t)ilen[f] > efftab[0].olen)
-            efftab[0].olen = ilen[f];
-            
-        for (s = 0; s < efftab[0].olen; s++) {
-          /* Mix audio by summing samples together. 
-           * Input side volume changes are performed above. */
-          for (f = 0; f < input_count; f++) {
-            if (f == 0)
-              efftab[0].obuf[s] =
-                (s<(st_size_t)ilen[f]) ? ibuf[f][s] : 0;
-            else if (s < (st_size_t)ilen[f]) {
-              /* Cast to double prevents integer overflow */
-              double sample = efftab[0].obuf[s] + (double)ibuf[f][s];
-              efftab[0].obuf[s] = ST_ROUND_CLIP_COUNT(sample, mixing_clips);
-            }
+            efftab[0].obuf[s] =
+              (s<(st_size_t)ilen[f]) ? ibuf[f][s] : 0;
+          else if (s < (st_size_t)ilen[f]) {
+            /* Cast to double prevents integer overflow */
+            double sample = efftab[0].obuf[s] + (double)ibuf[f][s];
+            efftab[0].obuf[s] = ST_ROUND_CLIP_COUNT(sample, mixing_clips);
           }
         }
-      } else {                 /* combine_method == SOX_MERGE */
-        efftab[0].olen = 0;
-        for (f = 0; f < input_count; ++f) {
-          ilen[f] = st_read(file_desc[f], ibuf[f], ST_BUFSIZ / input_count);
-          if (ilen[f] == ST_EOF) {
-            ilen[f] = 0;
-            if (file_desc[f]->st_errno)
-              fprintf(stderr, file_desc[f]->st_errstr);
-          }
-          if ((st_size_t)ilen[f] > efftab[0].olen)
-            efftab[0].olen = ilen[f];
-          volumechange(ibuf[f], ilen[f], file_opts[f]);
+      }
+    } else {                 /* combine_method == SOX_MERGE */
+      efftab[0].olen = 0;
+      for (f = 0; f < input_count; ++f) {
+        ilen[f] = st_read(file_desc[f], ibuf[f], ST_BUFSIZ / input_count);
+        if (ilen[f] == ST_EOF) {
+          ilen[f] = 0;
+          if (file_desc[f]->st_errno)
+            fprintf(stderr, file_desc[f]->st_errstr);
         }
-          
-        for (s = 0; s < efftab[0].olen; s++)
-          for (f = 0; f < input_count; f++)
-            efftab[0].obuf[s * input_count + f] =
-              (s < (st_size_t)ilen[f]) * ibuf[f][s];
-
-        read_samples += efftab[0].olen;
-        efftab[0].olen *= input_count;
+        if ((st_size_t)ilen[f] > efftab[0].olen)
+          efftab[0].olen = ilen[f];
+        volumechange(ibuf[f], ilen[f], file_opts[f]);
       }
+        
+      for (s = 0; s < efftab[0].olen; s++)
+        for (f = 0; f < input_count; f++)
+          efftab[0].obuf[s * input_count + f] =
+            (s < (st_size_t)ilen[f]) * ibuf[f][s];
 
-      efftab[0].odone = 0;
+      read_samples += efftab[0].olen;
+      efftab[0].olen *= input_count;
+    }
 
-      if (efftab[0].olen == 0)
-        break;
+    efftab[0].odone = 0;
 
-      flowstatus = flow_effect_out();
+    if (efftab[0].olen == 0)
+      break;
 
-      if (show_progress)
-        update_status();
+    flowstatus = flow_effect_out();
 
-      /* Quit reading/writing on user aborts.  This will close
-       * the files nicely as if an EOF was reached on read. */
-      if (user_abort)
-        break;
+    if (show_progress)
+      update_status();
 
-      /* If there's an error, don't try to write more. */
-      if (ofile->st_errno)
-        break;
-    } while (flowstatus == 0);
+    /* Quit reading/writing on user aborts.  This will close
+     * the files nicely as if an EOF was reached on read. */
+    if (user_abort)
+      break;
 
-    /* Drain the effects; don't write if output is indicating errors. */
-    if (ofile->st_errno == 0)
-      drain_effect_out();
-  }
+    /* If there's an error, don't try to write more. */
+    if (ofile->st_errno)
+      break;
+  } while (flowstatus == 0);
 
+  /* Drain the effects; don't write if output is indicating errors. */
+  if (ofile->st_errno == 0)
+    drain_effect_out();
+
   if (show_progress)
     fputs("\n\n", stderr);
 
@@ -1009,7 +1002,7 @@
  * Smart ruleset for multiple effects in sequence.
  *      Puts user-specified effect in right place.
  */
-static void check_effects(void)
+static void build_effects_table(void)
 {
   int i;
   int needchan = 0, needrate = 0, haschan = 0, hasrate = 0;
@@ -1166,7 +1159,7 @@
   }
 }
 
-static int start_effects(void)
+static int start_all_effects(void)
 {
   int e, ret = ST_SUCCESS;