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;
}