--- sox-14.4.2.old/ChangeLog +++ sox-14.4.2/ChangeLog @@ -972,7 +972,7 @@ o The "filter" effect could go into infinite drain mode. Now only drain 1 buffer. noisered as well. - o SoX was ignoring user aborts (ctrl-c) if it occured during + o SoX was ignoring user aborts (ctrl-c) if it occurred during effect drain operations. This was bad if effects had bugs and stuck in infinite loop. o Stop SoX from crashing when file type could not be auto --- sox-14.4.2.old/libsox.3 +++ sox-14.4.2/libsox.3 @@ -175,7 +175,7 @@ successfully read or written. If an error occurs, or the end-of-file is reached, the return value is a short item count or SOX_EOF. TODO: \fBsox_read\fR does not distiguish between end-of-file and error. Need -an feof() and ferror() concept to determine which occured. +an feof() and ferror() concept to determine which occurred. .P Upon successful completion \fBsox_close\fR returns 0. Otherwise, SOX_EOF is returned. In either case, any further access (including another --- sox-14.4.2.old/libsox.txt +++ sox-14.4.2/libsox.txt @@ -148,7 +148,7 @@ or written. If an error occurs, or the end-of-file is reached, the return value is a short item count or SOX_EOF. TODO: sox_read does not distiguish between end-of-file and error. Need an feof() and ferror() - concept to determine which occured. + concept to determine which occurred. Upon successful completion sox_close returns 0. Otherwise, SOX_EOF is returned. In either case, any further access (including another call to --- sox-14.4.2.old/sox.1 +++ sox-14.4.2/sox.1 @@ -2699,7 +2699,7 @@ .ne 6 .TS center; -lB lw52. +lB lw51. \-M/\-I/\-L Phase response = minimum/intermediate/linear \-s Steep filter (band-width = 99%) \-a Allow aliasing/imaging above the pass-band --- sox-14.4.2.old/src/Makefile.am +++ sox-14.4.2/src/Makefile.am @@ -95,7 +95,7 @@ libsox_la_CFLAGS = @WARN_CFLAGS@ libsox_la_LDFLAGS = @APP_LDFLAGS@ -version-info @SHLIB_VERSION@ \ - -export-symbols-regex '^(sox_.*|lsx_(check_read_params|(close|open)_dllibrary|(debug(_more|_most)?|fail|report|warn)_impl|eof|fail_errno|filelength|find_(enum_(text|value)|file_extension)|getopt(_init)?|lpc10_(create_(de|en)coder_state|(de|en)code)|raw(read|write)|read(_b_buf|buf|chars)|realloc|rewind|seeki|sigfigs3p?|strcasecmp|tell|unreadb|write(b|_b_buf|buf|s)))$$' + -export-symbols-regex '^(sox_.*|lsx_(([cm]|re)alloc.*|check_read_params|(close|open)_dllibrary|(debug(_more|_most)?|fail|report|warn)_impl|eof|error|fail_errno|filelength|find_(enum_(text|value)|file_extension)|flush|getopt(_init)?|lpc10_(create_(de|en)coder_state|(de|en)code)|raw(read|write)|read(_b_buf|buf|chars)|rewind|seeki|sigfigs3p?|strcasecmp|strdup|tell|unreadb|write(b|_b_buf|buf|s)))$$' if HAVE_WIN32_LTDL libsox_la_SOURCES += win32-ltdl.c win32-ltdl.h --- sox-14.4.2.old/src/adpcm.c +++ sox-14.4.2/src/adpcm.c @@ -71,6 +71,11 @@ { 392,-232} }; +extern void *lsx_ms_adpcm_alloc(unsigned chans) +{ + return lsx_malloc(chans * sizeof(MsState_t)); +} + static inline sox_sample_t AdpcmDecode(sox_sample_t c, MsState_t *state, sox_sample_t sample1, sox_sample_t sample2) { @@ -102,6 +107,7 @@ /* lsx_ms_adpcm_block_expand_i() outputs interleaved samples into one output buffer */ const char *lsx_ms_adpcm_block_expand_i( + void *priv, unsigned chans, /* total channels */ int nCoef, const short *coef, @@ -113,7 +119,7 @@ const unsigned char *ip; unsigned ch; const char *errmsg = NULL; - MsState_t state[4]; /* One decompressor state for each channel */ + MsState_t *state = priv; /* One decompressor state for each channel */ /* Read the four-byte header for each channel */ ip = ibuff; --- sox-14.4.2.old/src/adpcm.h +++ sox-14.4.2/src/adpcm.h @@ -29,8 +29,11 @@ /* default coef sets */ extern const short lsx_ms_adpcm_i_coef[7][2]; +extern void *lsx_ms_adpcm_alloc(unsigned chans); + /* lsx_ms_adpcm_block_expand_i() outputs interleaved samples into one output buffer */ extern const char *lsx_ms_adpcm_block_expand_i( + void *priv, unsigned chans, /* total channels */ int nCoef, const short *coef, --- sox-14.4.2.old/src/aiff.c +++ sox-14.4.2/src/aiff.c @@ -62,7 +62,6 @@ size_t ssndsize = 0; char *annotation; char *author; - char *comment = NULL; char *copyright; char *nametext; @@ -270,6 +269,7 @@ free(annotation); } else if (strncmp(buf, "COMT", (size_t)4) == 0) { + char *comment = NULL; rc = commentChunk(&comment, "Comment:", ft); if (rc) { /* Fail already called in function */ @@ -609,6 +609,11 @@ At 48 kHz, 16 bits stereo, this gives ~3 hours of audio. Sorry, the AIFF format does not provide for an indefinite number of samples. */ + if (ft->signal.channels >= (0x7f000000 / (ft->encoding.bits_per_sample >> 3))) + { + lsx_fail_errno(ft, SOX_EOF, "too many channels for AIFF header"); + return SOX_EOF; + } return(aiffwriteheader(ft, (uint64_t) 0x7f000000 / ((ft->encoding.bits_per_sample>>3)*ft->signal.channels))); } --- sox-14.4.2.old/src/effects_i_dsp.c +++ sox-14.4.2/src/effects_i_dsp.c @@ -357,11 +357,14 @@ double scale, sox_bool dc_norm) { int i, m = num_taps - 1; - double * h = malloc(num_taps * sizeof(*h)), sum = 0; + double * h = calloc(num_taps, sizeof(*h)), sum = 0; double mult = scale / lsx_bessel_I_0(beta), mult1 = 1 / (.5 * m + rho); assert(Fc >= 0 && Fc <= 1); lsx_debug("make_lpf(n=%i Fc=%.7g β=%g ρ=%g dc-norm=%i scale=%g)", num_taps, Fc, beta, rho, dc_norm, scale); + if (!h) + return NULL; + for (i = 0; i <= m / 2; ++i) { double z = i - .5 * m, x = z * M_PI, y = z * mult1; h[i] = x? sin(Fc * x) / x : Fc; --- sox-14.4.2.old/src/fap.c +++ sox-14.4.2/src/fap.c @@ -26,7 +26,7 @@ static sox_format_handler_t handler; handler = *lsx_sndfile_format_fn(); handler.description = - "Ensoniq PARIS digitial audio editing system (little endian)"; + "Ensoniq PARIS digital audio editing system (little endian)"; handler.names = names; handler.write_formats = write_encodings; return &handler; --- sox-14.4.2.old/src/fft4g.c +++ sox-14.4.2/src/fft4g.c @@ -322,6 +322,9 @@ void cdft(int n, int isgn, double *a, int *ip, double *w) { + if (n > FFT4G_MAX_SIZE) + return; + if (n > (ip[0] << 2)) { makewt(n >> 2, ip, w); } @@ -344,6 +347,9 @@ int nw, nc; double xi; + if (n > FFT4G_MAX_SIZE) + return; + nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; @@ -384,6 +390,9 @@ int j, nw, nc; double xr; + if (n > FFT4G_MAX_SIZE) + return; + nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; @@ -435,6 +444,9 @@ int j, nw, nc; double xr; + if (n > FFT4G_MAX_SIZE) + return; + nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; @@ -486,6 +498,9 @@ int j, k, l, m, mh, nw, nc; double xr, xi, yr, yi; + if (n > FFT4G_MAX_SIZE) + return; + nw = ip[0]; if (n > (nw << 3)) { nw = n >> 3; @@ -576,6 +591,9 @@ int j, k, l, m, mh, nw, nc; double xr, xi, yr, yi; + if (n > FFT4G_MAX_SIZE) + return; + nw = ip[0]; if (n > (nw << 3)) { nw = n >> 3; --- sox-14.4.2.old/src/fft4g.h +++ sox-14.4.2/src/fft4g.h @@ -13,6 +13,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define FFT4G_MAX_SIZE 262144 + void lsx_cdft(int, int, double *, int *, double *); void lsx_rdft(int, int, double *, int *, double *); void lsx_ddct(int, int, double *, int *, double *); --- sox-14.4.2.old/src/flac.c +++ sox-14.4.2/src/flac.c @@ -119,9 +119,10 @@ p->total_samples = metadata->data.stream_info.total_samples; } else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + const FLAC__StreamMetadata_VorbisComment *vc = &metadata->data.vorbis_comment; size_t i; - if (metadata->data.vorbis_comment.num_comments == 0) + if (vc->num_comments == 0) return; if (ft->oob.comments != NULL) { @@ -129,8 +130,9 @@ return; } - for (i = 0; i < metadata->data.vorbis_comment.num_comments; ++i) - sox_append_comment(&ft->oob.comments, (char const *) metadata->data.vorbis_comment.comments[i].entry); + for (i = 0; i < vc->num_comments; ++i) + if (vc->comments[i].entry) + sox_append_comment(&ft->oob.comments, (char const *) vc->comments[i].entry); } } --- sox-14.4.2.old/src/formats.c +++ sox-14.4.2/src/formats.c @@ -572,6 +572,7 @@ free(ft->priv); free(ft->filename); free(ft->filetype); + sox_delete_comments(&ft->oob.comments); free(ft); return NULL; } --- sox-14.4.2.old/src/formats_i.c +++ sox-14.4.2/src/formats_i.c @@ -19,6 +19,7 @@ */ #include "sox_i.h" +#include #include #include #include @@ -60,13 +61,24 @@ if (ft->seekable) ft->data_start = lsx_tell(ft); - if (channels && ft->signal.channels && ft->signal.channels != channels) + if (channels && ft->signal.channels && ft->signal.channels != channels) { lsx_warn("`%s': overriding number of channels", ft->filename); - else ft->signal.channels = channels; + } else if (channels > SHRT_MAX) { + lsx_fail_errno(ft, EINVAL, "implausibly large number of channels"); + return SOX_EOF; + } else { + ft->signal.channels = channels; + } - if (rate && ft->signal.rate && ft->signal.rate != rate) + if (rate && ft->signal.rate && ft->signal.rate != rate) { lsx_warn("`%s': overriding sample rate", ft->filename); - else ft->signal.rate = rate; + /* Since NaN comparisons yield false, the negation rejects them. */ + } else if (!(rate > 0)) { + lsx_fail_errno(ft, EINVAL, "invalid rate value"); + return SOX_EOF; + } else { + ft->signal.rate = rate; + } if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding) lsx_warn("`%s': overriding encoding type", ft->filename); --- sox-14.4.2.old/src/hcom.c +++ sox-14.4.2/src/hcom.c @@ -73,6 +73,14 @@ size_t pos; /* Where next byte goes */ } priv_t; +static int dictvalid(int n, int size, int left, int right) +{ + if (n > 0 && left < 0) + return 1; + + return (unsigned)left < size && (unsigned)right < size; +} + static int startread(sox_format_t * ft) { priv_t *p = (priv_t *) ft->priv; @@ -133,6 +141,11 @@ return (SOX_EOF); } lsx_readw(ft, &dictsize); + if (dictsize == 0 || dictsize > 511) + { + lsx_fail_errno(ft, SOX_EHDR, "Implausible dictionary size in HCOM header"); + return SOX_EOF; + } /* Translate to sox parameters */ ft->encoding.encoding = SOX_ENCODING_HCOM; @@ -150,10 +163,20 @@ lsx_debug("%d %d", p->dictionary[i].dict_leftson, p->dictionary[i].dict_rightson); + if (!dictvalid(i, dictsize, p->dictionary[i].dict_leftson, + p->dictionary[i].dict_rightson)) { + free(p->dictionary); + p->dictionary = NULL; + lsx_fail_errno(ft, SOX_EHDR, "Invalid dictionary"); + return SOX_EOF; + } } rc = lsx_skipbytes(ft, (size_t) 1); /* skip pad byte */ - if (rc) + if (rc) { + free(p->dictionary); + p->dictionary = NULL; return rc; + } /* Initialized the decompression engine */ p->checksum = checksum; @@ -235,6 +258,8 @@ { register priv_t *p = (priv_t *) ft->priv; + free(p->dictionary); + p->dictionary = NULL; if (p->huffcount != 0) { lsx_fail_errno(ft,SOX_EFMT,"not all HCOM data read"); @@ -245,8 +270,6 @@ lsx_fail_errno(ft,SOX_EFMT,"checksum error in HCOM data"); return (SOX_EOF); } - free(p->dictionary); - p->dictionary = NULL; return (SOX_SUCCESS); } @@ -428,13 +451,14 @@ { priv_t *p = (priv_t *) ft->priv; unsigned char *compressed_data = p->data; - size_t compressed_len = p->pos; + int32_t compressed_len = p->pos; int rc = SOX_SUCCESS; /* Compress it all at once */ - if (compressed_len) - compress(ft, &compressed_data, (int32_t *)&compressed_len); - free(p->data); + if (compressed_len) { + compress(ft, &compressed_data, &compressed_len); + free(p->data); + } /* Write the header */ lsx_writebuf(ft, "\000\001A", (size_t) 3); /* Dummy file name "A" */ --- sox-14.4.2.old/src/paf.c +++ sox-14.4.2/src/paf.c @@ -26,7 +26,7 @@ static sox_format_handler_t handler; handler = *lsx_sndfile_format_fn(); handler.description = - "Ensoniq PARIS digitial audio editing system (big endian)"; + "Ensoniq PARIS digital audio editing system (big endian)"; handler.names = names; handler.write_formats = write_encodings; return &handler; --- sox-14.4.2.old/src/sox-fmt.c +++ sox-14.4.2/src/sox-fmt.c @@ -46,7 +46,9 @@ lsx_readdw(ft, &comments_bytes)) return SOX_EOF; - if (((headers_bytes + 4) & 7) || headers_bytes < FIXED_HDR + comments_bytes || + if (((headers_bytes + 4) & 7) || + comments_bytes > 0x40000000 || /* max 1 GB */ + headers_bytes < FIXED_HDR + comments_bytes || (num_channels > 65535)) /* Reserve top 16 bits */ { lsx_fail_errno(ft, SOX_EHDR, "invalid sox file format header"); return SOX_EOF; --- sox-14.4.2.old/src/sox_sample_test.h +++ sox-14.4.2/src/sox_sample_test.h @@ -19,6 +19,7 @@ #undef NDEBUG /* Must undef above assert.h or other that might include it. */ #endif #include +#include #include "sox.h" #define TEST_UINT(bits) \ --- sox-14.4.2.old/src/sphere.c +++ sox-14.4.2/src/sphere.c @@ -63,7 +63,8 @@ return (SOX_EOF); } - header_size -= (strlen(buf) + 1); + bytes_read = strlen(buf); + header_size -= bytes_read >= header_size ? header_size : bytes_read + 1; while (strncmp(buf, "end_head", (size_t)8) != 0) { if (strncmp(buf, "sample_n_bytes", (size_t)14) == 0) @@ -105,7 +106,8 @@ return (SOX_EOF); } - header_size -= (strlen(buf) + 1); + bytes_read = strlen(buf); + header_size -= bytes_read >= header_size ? header_size : bytes_read + 1; } if (!bytes_per_sample) --- sox-14.4.2.old/src/testall.sh +++ sox-14.4.2/src/testall.sh @@ -67,3 +67,4 @@ t vox -r 8130 t wav t wve +t wav -e gsm-full-rate --- sox-14.4.2.old/src/voc.c +++ sox-14.4.2/src/voc.c @@ -351,6 +351,11 @@ v->block_remaining = 0; return done; } + if(uc == 0) { + lsx_fail_errno(ft, EINVAL, "invalid rate value"); + v->block_remaining = 0; + return done; + } *buf = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,); lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf, ft->clips)); ++buf; @@ -614,6 +619,10 @@ v->rate = new_rate_32; ft->signal.rate = new_rate_32; lsx_readb(ft, &uc); + if (uc <= 1) { + lsx_fail_errno(ft, SOX_EFMT, "2 bits per word required"); + return (SOX_EOF); + } v->size = uc; lsx_readb(ft, &(v->channels)); lsx_readw(ft, &(v->format)); /* ANN: added format */ --- sox-14.4.2.old/src/vorbis.c +++ sox-14.4.2/src/vorbis.c @@ -229,6 +229,7 @@ free(vb->buf); ov_clear(vb->vf); + free(vb->vf); return (SOX_SUCCESS); } @@ -270,8 +271,11 @@ vc.comment_lengths[i] = strlen(text); } } - vorbis_analysis_headerout( /* Build the packets */ - &ve->vd, &vc, &header_main, &header_comments, &header_codebooks); + if (vorbis_analysis_headerout( /* Build the packets */ + &ve->vd, &vc, &header_main, &header_comments, &header_codebooks) < 0) { + ret = HEADER_ERROR; + goto cleanup; + } ogg_stream_packetin(&ve->os, &header_main); /* And stream them out */ ogg_stream_packetin(&ve->os, &header_comments); @@ -280,6 +284,7 @@ while (ogg_stream_flush(&ve->os, &ve->og) && ret == HEADER_OK) if (!oe_write_page(&ve->og, ft)) ret = HEADER_ERROR; +cleanup: for (i = 0; i < vc.comments; ++i) free(vc.user_comments[i]); free(vc.user_comments); @@ -401,6 +406,7 @@ vorbis_block_clear(&ve->vb); vorbis_dsp_clear(&ve->vd); vorbis_info_clear(&ve->vi); + free(ve); return (SOX_SUCCESS); } --- sox-14.4.2.old/src/wav.c +++ sox-14.4.2/src/wav.c @@ -82,6 +82,7 @@ /* following used by *ADPCM wav files */ unsigned short nCoefs; /* ADPCM: number of coef sets */ short *lsx_ms_adpcm_i_coefs; /* ADPCM: coef sets */ + void *ms_adpcm_data; /* Private data of adpcm decoder */ unsigned char *packet; /* Temporary buffer for packets */ short *samples; /* interleaved samples buffer */ short *samplePtr; /* Pointer to current sample */ @@ -127,7 +128,7 @@ /* work with partial blocks. Specs say it should be null */ /* padded but I guess this is better than trailing quiet. */ samplesThisBlock = lsx_ima_samples_in((size_t)0, (size_t)ft->signal.channels, bytesRead, (size_t) 0); - if (samplesThisBlock == 0) + if (samplesThisBlock == 0 || samplesThisBlock > wav->samplesPerBlock) { lsx_warn("Premature EOF on .wav input file"); return 0; @@ -175,7 +176,7 @@ } } - errmsg = lsx_ms_adpcm_block_expand_i(ft->signal.channels, wav->nCoefs, wav->lsx_ms_adpcm_i_coefs, wav->packet, wav->samples, samplesThisBlock); + errmsg = lsx_ms_adpcm_block_expand_i(wav->ms_adpcm_data, ft->signal.channels, wav->nCoefs, wav->lsx_ms_adpcm_i_coefs, wav->packet, wav->samples, samplesThisBlock); if (errmsg) lsx_warn("%s", errmsg); @@ -442,7 +443,7 @@ } else { - lsx_fail_errno(ft, SOX_EHDR, "Cannot yet read block sizes of arbitary RF64 chunks, cannot find chunk '%s'", Label); + lsx_fail_errno(ft, SOX_EHDR, "Cannot yet read block sizes of arbitrary RF64 chunks, cannot find chunk '%s'", Label); return SOX_EOF; } } @@ -505,7 +506,7 @@ unsigned short wChannels; /* number of channels */ uint32_t dwSamplesPerSecond; /* samples per second per channel */ uint32_t dwAvgBytesPerSec;/* estimate of bytes per second needed */ - uint16_t wBitsPerSample; /* bits per sample */ + uint16_t wBitsPerSample = 0; /* bits per sample */ uint32_t wFmtSize; uint16_t wExtSize = 0; /* extended field for non-PCM */ @@ -712,6 +713,11 @@ else lsx_report("User options overriding channels read in .wav header"); + if (ft->signal.channels == 0) { + lsx_fail_errno(ft, SOX_EHDR, "Channel count is zero"); + return SOX_EOF; + } + if (ft->signal.rate == 0 || ft->signal.rate == dwSamplesPerSecond) ft->signal.rate = dwSamplesPerSecond; else @@ -786,6 +792,7 @@ /* nCoefs, lsx_ms_adpcm_i_coefs used by adpcm.c */ wav->lsx_ms_adpcm_i_coefs = lsx_malloc(wav->nCoefs * 2 * sizeof(short)); + wav->ms_adpcm_data = lsx_ms_adpcm_alloc(wChannels); { int i, errct=0; for (i=0; len>=2 && i < 2*wav->nCoefs; i++) { @@ -947,6 +954,11 @@ break; default: + if (ft->encoding.bits_per_sample == 0) + { + lsx_fail_errno(ft, SOX_EHDR, "WAV file bits per sample is zero"); + return SOX_EOF; + } wav->numSamples = div_bits(qwDataLength, ft->encoding.bits_per_sample) / ft->signal.channels; ft->signal.length = wav->numSamples * ft->signal.channels; } @@ -1211,6 +1223,7 @@ free(wav->packet); free(wav->samples); free(wav->lsx_ms_adpcm_i_coefs); + free(wav->ms_adpcm_data); free(wav->comment); wav->comment = NULL; @@ -1374,6 +1387,12 @@ long blocksWritten = 0; sox_bool isExtensible = sox_false; /* WAVE_FORMAT_EXTENSIBLE? */ + if (ft->signal.channels > UINT16_MAX) { + lsx_fail_errno(ft, SOX_EOF, "Too many channels (%u)", + ft->signal.channels); + return SOX_EOF; + } + dwSamplesPerSecond = ft->signal.rate; wChannels = ft->signal.channels; wBitsPerSample = ft->encoding.bits_per_sample; --- sox-14.4.2.old/src/wavpack.c +++ sox-14.4.2/src/wavpack.c @@ -65,6 +65,10 @@ char msg[80]; p->codec = WavpackOpenFileInputEx(&io_fns, ft, NULL, msg, OPEN_NORMALIZE, 0); + if (!p->codec) { + lsx_fail_errno(ft, SOX_EHDR, "%s", msg); + return SOX_EOF; + } ft->encoding.bits_per_sample = WavpackGetBytesPerSample(p->codec) << 3; ft->signal.channels = WavpackGetNumChannels(p->codec); if (WavpackGetSampleRate(p->codec) && ft->signal.rate && ft->signal.rate != WavpackGetSampleRate(p->codec)) @@ -108,6 +112,10 @@ uint64_t size64; p->codec = WavpackOpenFileOutput(ft_write_b_buf, ft, NULL); + if (!p->codec) { + lsx_fail_errno(ft, SOX_ENOMEM, "WavPack error creating output instance"); + return SOX_EOF; + } memset(&config, 0, sizeof(config)); config.bytes_per_sample = ft->encoding.bits_per_sample >> 3; config.bits_per_sample = ft->encoding.bits_per_sample; --- sox-14.4.2.old/src/xa.c +++ sox-14.4.2/src/xa.c @@ -143,6 +143,12 @@ lsx_report("User options overriding rate read in .xa header"); } + if (ft->signal.channels == 0 || ft->signal.channels > UINT16_MAX) { + lsx_fail_errno(ft, SOX_EFMT, "invalid channel count %d", + ft->signal.channels); + return SOX_EOF; + } + /* Check for supported formats */ if (ft->encoding.bits_per_sample != 16) { lsx_fail_errno(ft, SOX_EFMT, "%d-bit sample resolution not supported.", --- sox-14.4.2.old/src/xmalloc.c +++ sox-14.4.2/src/xmalloc.c @@ -41,3 +41,13 @@ return ptr; } + +void *lsx_realloc_array(void *p, size_t n, size_t size) +{ + if (n > (size_t)-1 / size) { + lsx_fail("malloc size overflow"); + exit(2); + } + + return lsx_realloc(p, n * size); +} --- sox-14.4.2.old/src/xmalloc.h +++ sox-14.4.2/src/xmalloc.h @@ -23,12 +23,14 @@ #include #include +LSX_RETURN_VALID void *lsx_realloc_array(void *p, size_t n, size_t size); + #define lsx_malloc(size) lsx_realloc(NULL, (size)) #define lsx_calloc(n,s) (((n)*(s))? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL) #define lsx_Calloc(v,n) v = lsx_calloc(n,sizeof(*(v))) #define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL) #define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL) -#define lsx_valloc(v,n) v = lsx_malloc((n)*sizeof(*(v))) -#define lsx_revalloc(v,n) v = lsx_realloc(v, (n)*sizeof(*(v))) +#define lsx_valloc(v,n) v = lsx_realloc_array(NULL, n, sizeof(*(v))) +#define lsx_revalloc(v,n) v = lsx_realloc_array(v, n, sizeof(*(v))) #endif