shithub: opus

Download patch

ref: d5a8136218977ef1bdcadb2c883b96106755654d
parent: d6ae25a8be0548626433aad7d6d577636231a251
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Mon May 28 20:28:50 EDT 2018

Avoiding leaks when opus_demo exits with an error

This gets rid of false positives in static analysis
(see https://trac.webkit.org/changeset/232236/webkit)

--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -79,14 +79,7 @@
          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
 }
 
-static void check_encoder_option(int decode_only, const char *opt)
-{
-   if (decode_only)
-   {
-      fprintf(stderr, "option %s is only for encoding\n", opt);
-      exit(EXIT_FAILURE);
-   }
-}
+#define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0)
 
 static const int silk8_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
@@ -218,7 +211,8 @@
 {
     int err;
     char *inFile, *outFile;
-    FILE *fin, *fout;
+    FILE *fin=NULL;
+    FILE *fout=NULL;
     OpusEncoder *enc=NULL;
     OpusDecoder *dec=NULL;
     int args;
@@ -225,8 +219,8 @@
     int len[2];
     int frame_size, channels;
     opus_int32 bitrate_bps=0;
-    unsigned char *data[2];
-    unsigned char *fbytes;
+    unsigned char *data[2] = {NULL, NULL};
+    unsigned char *fbytes=NULL;
     opus_int32 sampling_rate;
     int use_vbr;
     int max_payload_bytes;
@@ -240,7 +234,8 @@
     int k;
     opus_int32 skip=0;
     int stop=0;
-    short *in, *out;
+    short *in=NULL;
+    short *out=NULL;
     int application=OPUS_APPLICATION_AUDIO;
     double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
     double tot_samples=0;
@@ -268,11 +263,12 @@
     int remaining=0;
     int variable_duration=OPUS_FRAMESIZE_ARG;
     int delayed_decision=0;
+    int ret = EXIT_FAILURE;
 
     if (argc < 5 )
     {
        print_usage( argv );
-       return EXIT_FAILURE;
+       goto failure;
     }
 
     tot_in=tot_out=0;
@@ -291,7 +287,7 @@
     if (!decode_only && argc < 7 )
     {
        print_usage( argv );
-       return EXIT_FAILURE;
+       goto failure;
     }
 
     if (!decode_only)
@@ -303,7 +299,7 @@
        else if (strcmp(argv[args], "audio")!=0) {
           fprintf(stderr, "unknown application: %s\n", argv[args]);
           print_usage(argv);
-          return EXIT_FAILURE;
+          goto failure;
        }
        args++;
     }
@@ -316,7 +312,7 @@
     {
         fprintf(stderr, "Supported sampling rates are 8000, 12000, "
                 "16000, 24000 and 48000.\n");
-        return EXIT_FAILURE;
+        goto failure;
     }
     frame_size = sampling_rate/50;
 
@@ -326,7 +322,7 @@
     if (channels < 1 || channels > 2)
     {
         fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     if (!decode_only)
@@ -366,7 +362,7 @@
                 fprintf(stderr, "Unknown bandwidth %s. "
                                 "Supported are NB, MB, WB, SWB, FB.\n",
                                 argv[ args + 1 ]);
-                return EXIT_FAILURE;
+                goto failure;
             }
             args += 2;
         } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
@@ -393,7 +389,7 @@
                 fprintf(stderr, "Unsupported frame size: %s ms. "
                                 "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
                                 argv[ args + 1 ]);
-                return EXIT_FAILURE;
+                goto failure;
             }
             args += 2;
         } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
@@ -480,7 +476,7 @@
         } else {
             printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
             print_usage( argv );
-            return EXIT_FAILURE;
+            goto failure;
         }
     }
 
@@ -491,7 +487,7 @@
     {
         fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
                           MAX_PACKET);
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     inFile = argv[argc-2];
@@ -499,7 +495,7 @@
     if (!fin)
     {
         fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
-        return EXIT_FAILURE;
+        goto failure;
     }
     if (mode_list)
     {
@@ -517,8 +513,7 @@
     if (!fout)
     {
         fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
-        fclose(fin);
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     if (!decode_only)
@@ -527,9 +522,7 @@
        if (err != OPUS_OK)
        {
           fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
-          fclose(fin);
-          fclose(fout);
-          return EXIT_FAILURE;
+          goto failure;
        }
        opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
        opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
@@ -551,9 +544,7 @@
        if (err != OPUS_OK)
        {
           fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
-          fclose(fin);
-          fclose(fout);
-          return EXIT_FAILURE;
+          goto failure;
        }
     }
 
@@ -729,9 +720,7 @@
             if (len[toggle] < 0)
             {
                 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
-                fclose(fin);
-                fclose(fout);
-                return EXIT_FAILURE;
+                goto failure;
             }
             curr_mode_count += frame_size;
             if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
@@ -748,7 +737,7 @@
            if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
            {
               fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
-              return EXIT_FAILURE;
+              goto failure;
            }
            len[toggle] = new_len;
         }
@@ -759,16 +748,16 @@
             int_to_char(len[toggle], int_field);
             if (fwrite(int_field, 1, 4, fout) != 4) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             int_to_char(enc_final_range[toggle], int_field);
             if (fwrite(int_field, 1, 4, fout) != 4) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             tot_samples += nb_encoded;
         } else {
@@ -811,7 +800,7 @@
                        }
                        if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
                           fprintf(stderr, "Error writing.\n");
-                          return EXIT_FAILURE;
+                          goto failure;
                        }
                        tot_out += output_samples-skip;
                     }
@@ -837,9 +826,7 @@
                          (long)count,
                          (unsigned long)enc_final_range[toggle^use_inbandfec],
                          (unsigned long)dec_final_range);
-            fclose(fin);
-            fclose(fout);
-            return EXIT_FAILURE;
+            goto failure;
         }
 
         lost_prev = lost;
@@ -888,15 +875,18 @@
        fprintf(stderr, "bitrate statistics are undefined\n");
     }
     silk_TimerSave("opus_timing.txt");
+    ret = EXIT_SUCCESS;
+failure:
     opus_encoder_destroy(enc);
     opus_decoder_destroy(dec);
     free(data[0]);
-    if (use_inbandfec)
-        free(data[1]);
-    fclose(fin);
-    fclose(fout);
+    free(data[1]);
+    if (fin)
+        fclose(fin);
+    if (fout)
+        fclose(fout);
     free(in);
     free(out);
     free(fbytes);
-    return EXIT_SUCCESS;
+    return ret;
 }