shithub: sox

Download patch

ref: 4cc26362506d3bf8cfd66a15b9229ee54fe1fcd5
parent: 8ffd05c7ad124cfe652022e5ad9598a3d4d31de8
author: Ulrich Klauer <ulrich@chirlu.de>
date: Mon Oct 10 17:05:23 EDT 2011

Fix several memory leaks

Jin-Myung Won pointed out in bug #3309913 that example1.c needs to free
its effects after adding (a copy of) them to the chain. This same problem
was present also in other example programs and in SoX itself. (Perhaps it
should be documented somewhere that sox_add_effect() duplicates the effect
structure?)

While at it, I found and resolved more leaks in SoX's file handling and
combiner. There is still a leak due to lsx_usage_lines() left.

--- a/ChangeLog
+++ b/ChangeLog
@@ -34,7 +34,7 @@
   o Added use_threads variable to sox_globals. This should be used to enable
     or disable use of parallel effects processing instead of directly calling
     omp_set_num_threads. (Doug Cook)
-  o Fix to effects pipeline to let fade affect specify time from end of
+  o Fix to effects pipeline to let fade effect specify time from end of
     file again. (cbagwell and Thor Andreassen)
   o Fix man page default error for splice effect. (Ulrich Klauer)
   o Enable support for -plot option on biquad effect. (Ulrich Klauer)
@@ -47,6 +47,10 @@
   o Fixed man page description for unsigned samples and change
     CVS to git references. (Ulrich Klauer)
   o When using pipes (-p) on Windows, set file mode to binary. (cbagwell)
+
+Other bug fixes:
+
+  o Fix several memory leaks. [3309913] (Jin-Myung Won and Ulrich Klauer)
 
 sox-14.3.2	2011-02-27
 ----------
--- a/src/effects_i.c
+++ b/src/effects_i.c
@@ -37,7 +37,7 @@
   if (!*usage) {
     size_t i, len;
     for (len = i = 0; i < n; len += strlen(lines[i++]) + 1);
-    *usage = lsx_malloc(len);
+    *usage = lsx_malloc(len); /* FIXME: this memory will never be freed */
     strcpy(*usage, lines[0]);
     for (i = 1; i < n; ++i) {
       strcat(*usage, "\n");
--- a/src/example0.c
+++ b/src/example0.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "sox.h"
+#include <stdlib.h>
 #include <stdio.h>
 #include <assert.h>
 
@@ -60,6 +61,7 @@
   args[0] = (char *)in, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   /* This becomes the first `effect' in the chain */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Create the `vol' effect, and initialise it with the desired parameters: */
   e = sox_create_effect(sox_find_effect("vol"));
@@ -66,6 +68,7 @@
   args[0] = "3dB", assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   /* Add the effect to the end of the effects processing chain: */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Create the `flanger' effect, and initialise it with default parameters: */
   e = sox_create_effect(sox_find_effect("flanger"));
@@ -72,6 +75,7 @@
   assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
   /* Add the effect to the end of the effects processing chain: */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* The last effect in the effect chain must be something that only consumes
    * samples; in this case, we use the built-in handler that outputs
@@ -79,6 +83,7 @@
   e = sox_create_effect(sox_find_effect("output"));
   args[0] = (char *)out, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Flow samples through the effects processing chain until EOF is reached */
   sox_flow_effects(chain, NULL, NULL);
--- a/src/example1.c
+++ b/src/example1.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "sox.h"
+#include <stdlib.h>
 #include <stdio.h>
 #include <assert.h>
 
@@ -131,6 +132,7 @@
   e = sox_create_effect(input_handler());
   /* This becomes the first `effect' in the chain */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Create the `vol' effect, and initialise it with the desired parameters: */
   e = sox_create_effect(sox_find_effect("vol"));
@@ -137,6 +139,7 @@
   assert(sox_effect_options(e, 1, vol) == SOX_SUCCESS);
   /* Add the effect to the end of the effects processing chain: */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Create the `flanger' effect, and initialise it with default parameters: */
   e = sox_create_effect(sox_find_effect("flanger"));
@@ -143,6 +146,7 @@
   assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
   /* Add the effect to the end of the effects processing chain: */
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* The last effect in the effect chain must be something that only consumes
    * samples; in this case, we have defined an output handler that outputs
@@ -149,6 +153,7 @@
    * data to an audio file */
   e = sox_create_effect(output_handler());
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   /* Flow samples through the effects processing chain until EOF is reached */
   sox_flow_effects(chain, NULL, NULL);
--- a/src/example3.c
+++ b/src/example3.c
@@ -73,15 +73,18 @@
   e = sox_create_effect(sox_find_effect("input"));
   args[0] = (char *)in, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   e = sox_create_effect(sox_find_effect("trim"));
   args[0] = "10", assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
+  free(e);
 
   if (in->signal.rate != out->signal.rate) {
     e = sox_create_effect(sox_find_effect("rate"));
     assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
     assert(sox_add_effect(chain, e, &in->signal, &out->signal) == SOX_SUCCESS);
+    free(e);
   }
 
   if (in->signal.channels != out->signal.channels) {
@@ -88,11 +91,13 @@
     e = sox_create_effect(sox_find_effect("channels"));
     assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
     assert(sox_add_effect(chain, e, &in->signal, &out->signal) == SOX_SUCCESS);
+    free(e);
   }
 
   e = sox_create_effect(sox_find_effect("output"));
   args[0] = (char *)out, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
   assert(sox_add_effect(chain, e, &in->signal, &out->signal) == SOX_SUCCESS);
+  free(e);
 
   sox_flow_effects(chain, NULL, NULL);
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -223,6 +223,7 @@
     if (files[i]->ft) {
       sox_close(files[i]->ft);
     }
+    free(files[i]->filename);
     free(files[i]);
   }
 
@@ -236,6 +237,7 @@
       }
       sox_close(ofile->ft); /* Assume we can unlink a file before closing it. */
     }
+    free(ofile->filename);
     free(ofile);
   }
 
@@ -583,10 +585,13 @@
   input_combiner_t * z = (input_combiner_t *) effp->priv;
   size_t i;
 
-  if (is_parallel(combine_method))
+  if (is_parallel(combine_method)) {
     /* Free input buffers now that they are not used */
     for (i = 0; i < input_count; i++)
       free(z->ibuf[i]);
+    free(z->ibuf);
+  }
+  free(z->ilen);
 
   return SOX_SUCCESS;
 }
@@ -686,6 +691,7 @@
 
   if (add_effect(chain, effp, signal, &ofile->ft->signal, guard) != SOX_SUCCESS)
     exit(2); /* The effects chain should have displayed an error message */
+  free(effp);
 }
 
 static void init_eff_chains(void)
@@ -987,14 +993,17 @@
   if (chain->length == 0) {
     effp = sox_create_effect(input_combiner_effect_fn());
     sox_add_effect(chain, effp, &signal, &ofile->ft->signal);
+    free(effp);
   }
 
   /* Add user specified effects; stop before `dither' */
   for (i = 0; i < nuser_effects[current_eff_chain] &&
-      strcmp(user_efftab[i]->handler.name, "dither"); i++)
+      strcmp(user_efftab[i]->handler.name, "dither"); i++) {
     if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal,
           &guard) != SOX_SUCCESS)
       exit(2); /* Effects chain should have displayed an error message */
+    free(user_efftab[i]);
+  }
 
   /* Add auto effects if still needed at this point */
   if (signal.channels < ofile->ft->signal.channels &&
@@ -1017,10 +1026,12 @@
     auto_effect(chain, "dither", 0, NULL, &signal, &guard);
 
   /* Add user specified effects from `dither' onwards */
-  for (; i < nuser_effects[current_eff_chain]; i++, guard = 2)
+  for (; i < nuser_effects[current_eff_chain]; i++, guard = 2) {
     if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal,
           &guard) != SOX_SUCCESS)
       exit(2); /* Effects chain should have displayed an error message */
+    free(user_efftab[i]);
+  }
 
   if (!save_output_eff)
   {
@@ -1028,6 +1039,7 @@
     effp = sox_create_effect(output_effect_fn());
     if (sox_add_effect(chain, effp, &signal, &ofile->ft->signal) != SOX_SUCCESS)
       exit(2);
+    free(effp);
   }
   else
   {