From 27c08870ba172782f6406045007b6ff32a4f7329 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 27 Oct 2021 20:40:04 +0200 Subject: [PATCH] string: Introduce arr_alloc(). Change all callers of alloc() which pass a product of two integers as the allocation size to call the new function instead. This function aborts if the multiplication overflows. With arr_alloc() in place, alloc() reduces to a trivial wrapper which calls new arr_alloc() with the first argument equal to one. --- aac_afh.c | 2 +- aacdec_filter.c | 2 +- aft.c | 2 +- audiod.c | 2 +- client.c | 2 +- command.c | 2 +- fec.c | 10 +++++----- fecdec_filter.c | 2 +- filter.c | 2 +- flacdec_filter.c | 2 +- imdct.c | 6 +++--- interactive.c | 2 +- mp3_afh.c | 2 +- mp3dec_filter.c | 2 +- ogg_afh_common.c | 2 +- opusdec_filter.c | 2 +- para.h | 1 - play.c | 4 ++-- resample_filter.c | 6 +++--- spxdec_filter.c | 2 +- string.c | 36 +++++++++++++++++++++++------------- string.h | 1 + sync_filter.c | 2 +- vss.c | 2 +- wma_afh.c | 4 ++-- wmadec_filter.c | 4 ++-- yy/mp.y | 2 +- 27 files changed, 59 insertions(+), 49 deletions(-) diff --git a/aac_afh.c b/aac_afh.c index c4081f05..16838419 100644 --- a/aac_afh.c +++ b/aac_afh.c @@ -282,7 +282,7 @@ static int aac_afh_rewrite_tags(const char *map, size_t mapsize, metadata.count = rv; PARA_NOTICE_LOG("%d metadata item(s) found\n", rv); - metadata.tags = alloc((metadata.count + 5) * sizeof(mp4ff_tag_t)); + metadata.tags = arr_alloc(metadata.count + 5, sizeof(mp4ff_tag_t)); for (i = 0; i < metadata.count; i++) { mp4ff_tag_t *tag = metadata.tags + i; diff --git a/aacdec_filter.c b/aacdec_filter.c index 64baa48c..53a8853d 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -136,7 +136,7 @@ next_buffer: consumed += frame_info.bytesconsumed; if (!frame_info.samples) goto success; - btrbuf = alloc(2 * frame_info.samples); + btrbuf = arr_alloc(2, frame_info.samples); for (i = 0; i < frame_info.samples; i++) { short sh = ((short *)outbuf)[i]; write_int16_host_endian(btrbuf + loaded, sh); diff --git a/aft.c b/aft.c index 991cb777..f690e819 100644 --- a/aft.c +++ b/aft.c @@ -1224,7 +1224,7 @@ static int sort_matching_paths(struct ls_options *options) int (*compar)(const void *, const void *); int i; - options->data_ptr = alloc(nmemb * sizeof(*options->data_ptr)); + options->data_ptr = arr_alloc(nmemb, sizeof(*options->data_ptr)); for (i = 0; i < nmemb; i++) options->data_ptr[i] = options->data + i; diff --git a/audiod.c b/audiod.c index 4aef61b0..fbcde91c 100644 --- a/audiod.c +++ b/audiod.c @@ -393,7 +393,7 @@ static void parse_config_or_die(void) n = OPT_GIVEN(USER_ALLOW); if (n == 0) return; - uid_whitelist = alloc(n * sizeof(uid_t)); + uid_whitelist = arr_alloc(n, sizeof(uid_t)); for (i = 0; i < n; i++) { const char *arg = lls_string_val(i, OPT_RESULT(USER_ALLOW)); int32_t val; diff --git a/client.c b/client.c index 5cb2309d..ee7d980e 100644 --- a/client.c +++ b/client.c @@ -435,7 +435,7 @@ static void select_completer(struct i9e_completion_info *ci, goto free_moods; num_pl = ret; n = num_moods + num_pl; - mops = alloc((n + 1) * sizeof(char *)); + mops = arr_alloc(n + 1, sizeof(char *)); for (i = 0; i < num_moods; i++) mops[i] = make_message("m/%s", moods[i]); for (i = 0; i < num_pl; i++) diff --git a/command.c b/command.c index d38f387d..407a1c9f 100644 --- a/command.c +++ b/command.c @@ -834,7 +834,7 @@ static int run_command(struct command_context *cc, struct iovec *iov) for (i = 0; p < end; i++) p += strlen(p) + 1; argc = i; - argv = alloc((argc + 1) * sizeof(char *)); + argv = arr_alloc(argc + 1, sizeof(char *)); for (i = 0, p = iov->iov_base; p < end; i++) { argv[i] = para_strdup(p); p += strlen(p) + 1; diff --git a/fec.c b/fec.c index ce2bc4fd..932e0693 100644 --- a/fec.c +++ b/fec.c @@ -97,7 +97,7 @@ static void init_mul_table(void) static unsigned char *alloc_matrix(int rows, int cols) { - return alloc(rows * cols); + return arr_alloc(rows, cols); } /* @@ -245,9 +245,9 @@ static void matmul(unsigned char *a, unsigned char *b, unsigned char *c, static int invert_mat(unsigned char *src, int k) { int irow, icol, row, col, ix, error; - int *indxc = alloc(k * sizeof(int)); - int *indxr = alloc(k * sizeof(int)); - int *ipiv = alloc(k * sizeof(int)); /* elements used as pivots */ + int *indxc = arr_alloc(k, sizeof(int)); + int *indxr = arr_alloc(k, sizeof(int)); + int *ipiv = arr_alloc(k, sizeof(int)); /* elements used as pivots */ unsigned char c, *p, *id_row = alloc_matrix(1, k), *temp_row = alloc_matrix(1, k); @@ -607,7 +607,7 @@ int fec_decode(struct fec_parms *parms, unsigned char **data, int *idx, if (ret < 0) return ret; /* do the actual decoding */ - slice = alloc(k * sizeof(unsigned char *)); + slice = arr_alloc(k, sizeof(unsigned char *)); for (row = 0; row < k; row++) { if (idx[row] >= k) { slice[row] = zalloc(sz); diff --git a/fecdec_filter.c b/fecdec_filter.c index 8efb2af7..a720a7a7 100644 --- a/fecdec_filter.c +++ b/fecdec_filter.c @@ -225,7 +225,7 @@ static int add_slice(char *buf, struct fecdec_group *fg) } if (fg->num_slices == 0) { fg->num_slices = fg->h.slices_per_group; - fg->idx = alloc(fg->num_slices * sizeof(int)); + fg->idx = arr_alloc(fg->num_slices, sizeof(int)); fg->data = zalloc(fg->num_slices * sizeof(unsigned char *)); } r = fg->num_received_slices; diff --git a/filter.c b/filter.c index 04640692..adfa8e10 100644 --- a/filter.c +++ b/filter.c @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) EMBRACE(.name = "stdin")); stdin_task_register(sit, &s); - fns = alloc(OPT_GIVEN(FILTER) * sizeof(*fns)); + fns = arr_alloc(OPT_GIVEN(FILTER), sizeof(*fns)); for (i = 0, parent = sit->btrn; i < OPT_GIVEN(FILTER); i++) { const char *fa = lls_string_val(i, OPT_RESULT(FILTER)); const char *name; diff --git a/flacdec_filter.c b/flacdec_filter.c index d3a481cf..8747a4be 100644 --- a/flacdec_filter.c +++ b/flacdec_filter.c @@ -135,7 +135,7 @@ static FLAC__StreamDecoderWriteStatus write_cb( struct btr_node *btrn = fn->btrn; size_t k, n = frame->header.blocksize; unsigned channels = FLAC__stream_decoder_get_channels(decoder); - char *outbuffer = alloc(n * channels * 2); + char *outbuffer = arr_alloc(n, channels * 2); if (channels == 1) { for (k = 0; k < n; k++) { diff --git a/imdct.c b/imdct.c index d49ae852..2e1089f1 100644 --- a/imdct.c +++ b/imdct.c @@ -336,7 +336,7 @@ static int fft_init(struct fft_context *s, int nbits) s->nbits = nbits; n = 1 << nbits; - s->revtab = alloc(n * sizeof(uint16_t)); + s->revtab = arr_alloc(n, sizeof(uint16_t)); for (j = 4; j <= nbits; j++) { int k = 1 << j; double freq = 2 * M_PI / k; @@ -371,8 +371,8 @@ int imdct_init(int nbits, struct mdct_context **result) s->nbits = nbits; s->n = n; n4 = n >> 2; - s->tcos = alloc(n4 * sizeof(fftsample_t)); - s->tsin = alloc(n4 * sizeof(fftsample_t)); + s->tcos = arr_alloc(n4, sizeof(fftsample_t)); + s->tsin = arr_alloc(n4, sizeof(fftsample_t)); for (i = 0; i < n4; i++) { alpha = 2 * M_PI * (i + 1.0 / 8.0) / n; diff --git a/interactive.c b/interactive.c index 98882ce6..01f25fb3 100644 --- a/interactive.c +++ b/interactive.c @@ -693,7 +693,7 @@ char **i9e_complete_commands(const char *word, struct i9e_completer *completers) if (is_prefix(word, cmd, len)) match_count++; } - matches = alloc((match_count + 1) * sizeof(*matches)); + matches = arr_alloc(match_count + 1, sizeof(*matches)); for (i = 0, match_count = 0; (cmd = completers[i].name); i++) if (is_prefix(word, cmd, len)) matches[match_count++] = para_strdup(cmd); diff --git a/mp3_afh.c b/mp3_afh.c index a42042e9..d7493ac0 100644 --- a/mp3_afh.c +++ b/mp3_afh.c @@ -598,7 +598,7 @@ static int mp3_read_info(unsigned char *map, size_t numbytes, int fd, const char *tag_versions[] = {"no", "id3v1", "id3v2", "id3v1+id3v2"}; afhi->chunks_total = 0; - afhi->chunk_table = alloc(chunk_table_size * sizeof(uint32_t)); + afhi->chunk_table = arr_alloc(chunk_table_size, sizeof(uint32_t)); while (1) { int freq, br; struct timeval tmp, cct; /* current chunk time */ diff --git a/mp3dec_filter.c b/mp3dec_filter.c index 9403a71d..75b05275 100644 --- a/mp3dec_filter.c +++ b/mp3dec_filter.c @@ -144,7 +144,7 @@ decode: } fn->min_iqs = 0; mad_synth_frame(&pmd->synth, &pmd->frame); - outbuffer = alloc(pmd->synth.pcm.length * 2 * pmd->channels); + outbuffer = arr_alloc(pmd->synth.pcm.length, 2 * pmd->channels); loaded = 0; for (i = 0; i < pmd->synth.pcm.length; i++) { int sample = MAD_TO_SHORT(pmd->synth.pcm.samples[0][i]); diff --git a/ogg_afh_common.c b/ogg_afh_common.c index 0570656e..3a5c263c 100644 --- a/ogg_afh_common.c +++ b/ogg_afh_common.c @@ -167,7 +167,7 @@ int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi, PARA_INFO_LOG("%" PRIu32 " seconds, %d frames/chunk\n", afhi->seconds_total, frames_per_chunk); ct_size = 250; - afhi->chunk_table = alloc(ct_size * sizeof(uint32_t)); + afhi->chunk_table = arr_alloc(ct_size, sizeof(uint32_t)); afhi->chunk_table[0] = 0; afhi->chunk_table[1] = afhi->header_len; oss.returned = afhi->header_len; diff --git a/opusdec_filter.c b/opusdec_filter.c index 942cce37..d30de0b6 100644 --- a/opusdec_filter.c +++ b/opusdec_filter.c @@ -193,7 +193,7 @@ static int decode_packet(struct opusdec_context *ctx, ogg_packet *op, /* don't care for anything except opus eos */ if (op->e_o_s && ctx->os.serialno == ctx->opus_serialno) ctx->eos = true; - output = alloc(sizeof(short) * MAX_FRAME_SIZE * ctx->channels); + output = arr_alloc(sizeof(short) * ctx->channels, MAX_FRAME_SIZE); ret = opus_multistream_decode(ctx->st, (unsigned char *)op->packet, op->bytes, output, MAX_FRAME_SIZE, 0); if (ret < 0) { diff --git a/para.h b/para.h index b406818b..50ec7eaa 100644 --- a/para.h +++ b/para.h @@ -44,7 +44,6 @@ typeof(x) _x = (x); \ _x > 0? _x : -_x; }) - extern __printf_2_3 void (*para_log)(int, const char*, ...); /** * Define a standard log function that always writes to stderr. diff --git a/play.c b/play.c index d46c16cd..92685013 100644 --- a/play.c +++ b/play.c @@ -288,7 +288,7 @@ static int shuffle_compare(__a_unused const void *a, __a_unused const void *b) static void init_shuffle_map(void) { unsigned n, num_inputs = lls_num_inputs(play_lpr); - shuffle_map = alloc(num_inputs * sizeof(unsigned)); + shuffle_map = arr_alloc(num_inputs, sizeof(unsigned)); for (n = 0; n < num_inputs; n++) shuffle_map[n] = n; if (!OPT_GIVEN(RANDOMIZE)) @@ -651,7 +651,7 @@ static char **get_mapped_keyseqs(void) char **result; int i; - result = alloc((NUM_MAPPED_KEYS + 1) * sizeof(char *)); + result = arr_alloc(NUM_MAPPED_KEYS + 1, sizeof(char *)); FOR_EACH_MAPPED_KEY(i) { char *seq = get_key_map_seq(i); result[i] = seq; diff --git a/resample_filter.c b/resample_filter.c index 6540c3e9..ebf85a4a 100644 --- a/resample_filter.c +++ b/resample_filter.c @@ -167,10 +167,10 @@ static int resample_frames(int16_t *in, size_t num_frames, bool have_more, data.output_frames = num_frames * ctx->ratio + 1; out_samples = data.output_frames * ctx->channels; - in_float = alloc(num_samples * sizeof(float)); + in_float = arr_alloc(num_samples, sizeof(float)); src_short_to_float_array(in, in_float, num_samples); data.data_in = in_float; - data.data_out = alloc(out_samples * sizeof(float)); + data.data_out = arr_alloc(out_samples, sizeof(float)); ret = src_process(ctx->src_state, &data); free(in_float); if (ret != 0) { @@ -179,7 +179,7 @@ static int resample_frames(int16_t *in, size_t num_frames, bool have_more, return -E_LIBSAMPLERATE; } out_samples = data.output_frames_gen * ctx->channels; - out = alloc(out_samples * sizeof(short)); + out = arr_alloc(out_samples, sizeof(short)); src_float_to_short_array(data.data_out, out, out_samples); free(data.data_out); *result = out; diff --git a/spxdec_filter.c b/spxdec_filter.c index 18b50267..9dc7c065 100644 --- a/spxdec_filter.c +++ b/spxdec_filter.c @@ -171,7 +171,7 @@ static int speexdec_write_frames(int packet_no, if (new_frame_size <= 0) continue; samples = new_frame_size * psd->shi.channels; - btr_output = alloc(2 * samples); + btr_output = arr_alloc(samples, 2); for (i = 0; i < samples; i++) btr_output[i] = read_u16(output + i + skip_idx); btr_add_output((char *)btr_output, samples * 2, btrn); diff --git a/string.c b/string.c index f98b199b..f01c8392 100644 --- a/string.c +++ b/string.c @@ -43,6 +43,25 @@ __must_check void *arr_realloc(void *ptr, size_t nmemb, size_t size) return ptr; } +/** + * Allocate an array, abort on failure or bugs. + * + * \param nmemb See \ref arr_realloc(). + * \param size See \ref arr_realloc(). + * + * Like \ref arr_realloc(), this aborts on invalid arguments, integer overflow + * and allocation errors. + * + * \return A pointer to newly allocated memory which is suitably aligned for + * any kind of variable. + * + * \sa See \ref arr_realloc(). + */ +__must_check __malloc void *arr_alloc(size_t nmemb, size_t size) +{ + return arr_realloc(NULL, nmemb, size); +} + /** * Paraslash's version of realloc(). * @@ -76,16 +95,7 @@ __must_check void *para_realloc(void *p, size_t size) */ __must_check __malloc void *alloc(size_t size) { - void *p; - - assert(size); - p = malloc(size); - if (!p) { - PARA_EMERG_LOG("malloc failed (size = %zu), aborting\n", - size); - exit(EXIT_FAILURE); - } - return p; + return arr_alloc(1, size); } /** @@ -741,7 +751,7 @@ void free_argv(char **argv) static int create_argv_offset(int offset, const char *buf, const char *delim, char ***result) { - char *word, **argv = alloc((offset + 1) * sizeof(char *)); + char *word, **argv = arr_alloc(offset + 1, sizeof(char *)); const char *p; int i, ret; @@ -1029,7 +1039,7 @@ __must_check int strwidth(const char *s, size_t *result) return -ERRNO_TO_PARA_ERROR(errno); if (num_wchars == 0) return 0; - dest = alloc((num_wchars + 1) * sizeof(*dest)); + dest = arr_alloc(num_wchars + 1, sizeof(*dest)); src = s; memset(&state, 0, sizeof(state)); num_wchars = mbsrtowcs(dest, &src, num_wchars, &state); @@ -1084,7 +1094,7 @@ __must_check int sanitize_str(const char *src, size_t max_width, num_wchars = mbsrtowcs(NULL, &src, 0, &state); if (num_wchars == (size_t)-1) return -ERRNO_TO_PARA_ERROR(errno); - wcs = alloc((num_wchars + 1) * sizeof(*wcs)); + wcs = arr_alloc(num_wchars + 1, sizeof(*wcs)); memset(&state, 0, sizeof(state)); num_wchars = mbsrtowcs(wcs, &src, num_wchars + 1, &state); assert(num_wchars != (size_t)-1); diff --git a/string.h b/string.h index 45c359f3..3efe6878 100644 --- a/string.h +++ b/string.h @@ -71,6 +71,7 @@ __must_check void *arr_realloc(void *ptr, size_t nmemb, size_t size); __must_check void *para_realloc(void *p, size_t size); __must_check __malloc void *alloc(size_t size); __must_check __malloc void *zalloc(size_t size); +__must_check __malloc void *arr_alloc(size_t nmemb, size_t size); __must_check __malloc char *para_strdup(const char *s); __printf_2_0 unsigned xvasprintf(char **result, const char *fmt, va_list ap); diff --git a/sync_filter.c b/sync_filter.c index 9c1767e4..d322395d 100644 --- a/sync_filter.c +++ b/sync_filter.c @@ -176,7 +176,7 @@ static void *sync_setup(const struct lls_parse_result *lpr) r_b = FILTER_CMD_OPT_RESULT(SYNC, BUDDY, lpr); n = lls_opt_given(r_b); - sbi = alloc(n * sizeof(*sbi)); + sbi = arr_alloc(n, sizeof(*sbi)); PARA_INFO_LOG("initializing buddy info array of length %u\n", n); for (i = 0; i < n; i++) { const char *url = lls_string_val(i, r_b); diff --git a/vss.c b/vss.c index c6c57845..667d4cac 100644 --- a/vss.c +++ b/vss.c @@ -335,7 +335,7 @@ static int initialize_fec_client(struct fec_client *fc, struct vss_task *vsst) ret = fec_new(k, n, &fc->parms); if (ret < 0) return ret; - fc->src_data = alloc(k * sizeof(char *)); + fc->src_data = arr_alloc(k, sizeof(char *)); for (i = 0; i < k; i++) fc->src_data[i] = alloc(fc->mps); fc->enc_buf = alloc(fc->mps); diff --git a/wma_afh.c b/wma_afh.c index a6fbecca..8bff7cfc 100644 --- a/wma_afh.c +++ b/wma_afh.c @@ -195,7 +195,7 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, uint32_t packet_size size_t ct_size = 250; int ret, count = 0, num_frames, num_superframes; - afhi->chunk_table = alloc(ct_size * sizeof(uint32_t)); + afhi->chunk_table = arr_alloc(ct_size, sizeof(uint32_t)); afhi->chunk_table[0] = 0; afhi->chunk_table[1] = afhi->header_len; @@ -622,7 +622,7 @@ static int wma_rewrite_tags(const char *map, size_t mapsize, if (top.reserved2 != 2) return -E_NO_WMA; p++; /* objects start at p */ - top.objects = alloc(top.num_objects * sizeof(struct asf_object)); + top.objects = arr_alloc(top.num_objects, sizeof(struct asf_object)); ret = read_asf_objects(p, top.size - (p - map), top.num_objects, top.objects, &ton); if (ret < 0) diff --git a/wmadec_filter.c b/wmadec_filter.c index 1f308785..d9a08881 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -160,8 +160,8 @@ static void init_coef_vlc(struct private_wmadec_data *pwd, int sidx, int didx) int i, l, j, k, level, n = src->n; init_vlc(dst, VLCBITS, n, src->huffbits, src->huffcodes, 4); - pwd->run_table[didx] = alloc(n * sizeof(uint16_t)); - pwd->level_table[didx] = alloc(n * sizeof(uint16_t)); + pwd->run_table[didx] = arr_alloc(n, sizeof(uint16_t)); + pwd->level_table[didx] = arr_alloc(n, sizeof(uint16_t)); i = 2; level = 1; k = 0; diff --git a/yy/mp.y b/yy/mp.y index f94d2408..8df4f20e 100644 --- a/yy/mp.y +++ b/yy/mp.y @@ -86,7 +86,7 @@ static struct mp_ast_node *ast_node_new_binary(int id, struct mp_ast_node *left, { struct mp_ast_node *node = ast_node_raw(id); node->num_children = 2; - node->children = alloc(2 * sizeof(struct mp_ast_node *)); + node->children = arr_alloc(2, sizeof(struct mp_ast_node *)); node->children[0] = left; node->children[1] = right; return node; -- 2.39.2