shithub: dumb

Download patch

ref: 98f6464a85a41fb0c4801df589c825011506fb76
parent: 6d815d2f620af548f0d7c9c00281c16656c5f1b1
author: Christopher Snowhill <kode54@gmail.com>
date: Tue Sep 12 12:28:27 EDT 2017

Harden LPC with a bit of error handling.

--- a/include/internal/lpc.h
+++ b/include/internal/lpc.h
@@ -19,6 +19,6 @@
 #define _V_LPC_H_
 
 struct DUMB_IT_SIGDATA;
-extern void dumb_it_add_lpc(struct DUMB_IT_SIGDATA *sigdata);
+extern int dumb_it_add_lpc(struct DUMB_IT_SIGDATA *sigdata);
 
 #endif
--- a/src/helpers/lpc.c
+++ b/src/helpers/lpc.c
@@ -55,12 +55,12 @@
 /* Input : n elements of time doamin data
    Output: m lpc coefficients, excitation energy */
 
-static float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
+static float vorbis_lpc_from_data(float *data,float *lpci,long n,long m){
   double *aut=alloca(sizeof(*aut)*(m+1));
   double *lpc=alloca(sizeof(*lpc)*(m));
   double error;
   double epsilon;
-  int i,j;
+  long i,j;
 
   /* autocorrelation, p+1 lag coefficients */
   j=m+1;
@@ -127,7 +127,7 @@
   return error;
 }
 
-static void vorbis_lpc_predict(float *coeff,float *prime,int m,
+static void vorbis_lpc_predict(float *coeff,float *prime,long m,
                      float *data,long n){
 
   /* in: coeff[0...m-1] LPC coefficients
@@ -167,7 +167,7 @@
 
 /* This extra sample padding is really only needed by the FIR resampler, but it helps the other resamplers as well. */
 
-void dumb_it_add_lpc(struct DUMB_IT_SIGDATA *sigdata){
+int dumb_it_add_lpc(struct DUMB_IT_SIGDATA *sigdata){
     float lpc[lpc_order * 2];
     float lpc_input[lpc_max * 2];
     float lpc_output[lpc_extra * 2];
@@ -175,11 +175,12 @@
     signed char * s8;
     signed short * s16;
 
-    int n, o, offset, lpc_samples;
+    long n, o, offset, lpc_samples;
 
     for ( n = 0; n < sigdata->n_samples; n++ ) {
         IT_SAMPLE * sample = sigdata->sample + n;
-        if ( ( sample->flags & ( IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP) ) == IT_SAMPLE_EXISTS ) {
+        if ( ( sample->flags & ( IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP) ) == IT_SAMPLE_EXISTS &&
+			 sample->data != NULL ) {
             /* If we have enough sample data to train the filter, use the filter to generate the padding */
             if ( sample->length >= lpc_order ) {
                 lpc_samples = sample->length;
@@ -218,6 +219,9 @@
                     if ( sample->flags & IT_SAMPLE_16BIT )
                     {
                         s16 = ( signed short * ) realloc( sample->data, ( sample->length + lpc_extra ) * 2 * sizeof(short) );
+						if ( !s16 )
+							return -1;
+						
                         sample->data = s16;
 
                         s16 += sample->length * 2;
@@ -232,6 +236,9 @@
                     else
                     {
                         s8 = ( signed char * ) realloc( sample->data, ( sample->length + lpc_extra ) * 2 );
+						if ( !s8 )
+							return -1;
+						
                         sample->data = s8;
 
                         s8 += sample->length * 2;
@@ -272,6 +279,9 @@
                     if ( sample->flags & IT_SAMPLE_16BIT )
                     {
                         s16 = ( signed short * ) realloc( sample->data, ( sample->length + lpc_extra ) * sizeof(short) );
+						if (!s16)
+							return -1;
+						
                         sample->data = s16;
 
                         s16 += sample->length;
@@ -285,6 +295,9 @@
                     else
                     {
                         s8 = ( signed char * ) realloc( sample->data, sample->length + lpc_extra );
+						if ( !s8 )
+							return -1;
+						
                         sample->data = s8;
 
                         s8 += sample->length;
@@ -300,6 +313,7 @@
             else
             /* Otherwise, pad with silence. */
             {
+				void *data;
                 offset = sample->length;
                 lpc_samples = lpc_extra;
 
@@ -312,9 +326,15 @@
                 offset *= n;
                 lpc_samples *= n;
 
-                sample->data = realloc( sample->data, offset + lpc_samples );
-                memset( (char*)sample->data + offset, 0, lpc_samples );
+                data = realloc( sample->data, offset + lpc_samples );
+				if (!data)
+					return -1;
+				sample->data = data;
+				
+                memset( (char*)data + offset, 0, lpc_samples );
             }
         }
     }
+	
+	return 0;
 }
--- a/src/it/itrender.c
+++ b/src/it/itrender.c
@@ -5410,7 +5410,10 @@
 	//sigrenderer->max_output = 0;
 
 	if ( !(sigdata->flags & IT_WAS_PROCESSED) ) {
-		dumb_it_add_lpc( sigdata );
+		if ( dumb_it_add_lpc( sigdata ) < 0 ) {
+			_dumb_it_end_sigrenderer( sigrenderer );
+			return NULL;
+		}
 
 		sigdata->flags |= IT_WAS_PROCESSED;
 	}