From bbad36f3d81fea36b7d6cf520be299ab5a68bf0a Mon Sep 17 00:00:00 2001 From: Rob Davies Date: Wed, 15 Apr 2026 16:52:09 +0100 Subject: [PATCH 1/3] Add wrappers for malloc, realloc with a calloc-like interface Help avoid bugs due to integer wrap-around when calculating sizes to pass to malloc() or realloc(). calloc() is better in this respect as it takes two parameters (number and size) and catches overflows when multiplying them together. The new interfaces provide similar functions for malloc() and realloc(), along with additional ones to handle cases that commonly occur in the code base. All the functions are static inlines, so it should be possible for the optimiser to simplify the code in the cases where overflow cannot occur (for example, due to the size of the data types actually being passed in). The interfaces are: * Saturating arithmetic Primitives used to build the later functions. - hts_add_sat2(a, b) returns (a + b) or SIZE_MAX on overflow - hts_add_sat3(a, b, c) returns (a + b + c) or SIZE_MAX on overflow - hts_prod_sat2(a, b) returns (a * b) or SIZE_MAX on overflow * Wrappers around malloc() - hts_malloc(size_t size) For use with the saturating arithmetic functions above. Catches over-large allocations before they get to malloc(). Prevents spurious gcc warnings about very large allocations, and allows the optimiser to convert the overflow cases to an early exit. - hts_malloc_p(size_t a, size_t b) Replaces malloc(a * b) - hts_malloc_ps(size_t sz, size_t a, size_t b) Replaces malloc(sz * (a + b)) - hts_malloc_pse(size_t sz, size_t a, size_t b, size_t extra) Replaces malloc(sz * (a + b) + extra) * Wrappers around calloc() - hts_calloc(size_t size, size_t num) For use with the saturating arithmetic functions above. Catches over-large allocations before they get to calloc(). Prevents spurious gcc warnings about very large allocations, and allows the optimiser to convert the overflow cases to an early exit. - hts_calloc_ps(size_t sz, size_t a, size_t b) Replaces calloc(a + b, sz) - hts_calloc_pse(size_t sz, size_t a, size_t b, size_t extra) Replaces calloc(sz * (a + b) + extra, 1) * Wrappers around realloc() - hts_realloc(void *orig, size_t size) For use with the saturating arithmetic functions above. Catches over-large allocations before they get to realloc(). Prevents spurious gcc warnings about very large allocations, and allows the optimiser to convert the overflow cases to an early exit. - hts_realloc_p(void *orig, size_t a, size_t b) Replaces realloc(orig, a * b) - hts_realloc_ps(void *orig, size_t sz, size_t a, size_t b) Replaces realloc(orig, sz * (a + b)) - hts_realloc_pse(void *orig, size_t sz, size_t a, size_t b, size_t extra) Replaces realloc(orig, sz * (a + b) + extra) --- htslib/hts_alloc.h | 360 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 htslib/hts_alloc.h diff --git a/htslib/hts_alloc.h b/htslib/hts_alloc.h new file mode 100644 index 000000000..41d7eefb8 --- /dev/null +++ b/htslib/hts_alloc.h @@ -0,0 +1,360 @@ +/* hts_alloc.h -- Allocation functions. + + Copyright (C) 2026 Genome Research Ltd. + + Author: Rob Davies + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. */ + +#ifndef HTSLIB_HTS_ALLOC_H +#define HTSLIB_HTS_ALLOC_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Compute saturating addition of two size_t inputs + * + * @return sum of @p a and @p b, or SIZE_MAX if the sum would overflow + */ + +static inline size_t hts_add_sat2(size_t a, size_t b) { + size_t r = a + b; + return r >= a ? r : SIZE_MAX; +} + +/** + * Compute saturating addition of three size_t inputs + * + * @return sum of @p a, @p b and @p c, or SIZE_MAX if the sum would overflow + */ + +static inline size_t hts_add_sat3(size_t a, size_t b, size_t c) { + return hts_add_sat2(hts_add_sat2(a, b), c); +} + +/** + * Compute saturating product of two size_t inputs + * + * @return product of @p a, and @p b, or SIZE_MAX if the sum would overflow + */ + +static inline size_t hts_prod_sat2(size_t a, size_t b) { + const size_t safe_limit = ((size_t) 1) << (sizeof(size_t) * 8 / 2); + if (a < safe_limit && b < safe_limit) + return a * b; + if (a == 0) + return 0; + if ((SIZE_MAX / a) < b) + return SIZE_MAX; + return a * b; +} + +#define HTS_SIZE_LIMIT (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) + +/** + * Allocate memory with checks for overflow + * + * @param size Number of bytes to allocate + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be @p size bytes. NULL will be returned + * if the product is too big for a size_t or ptrdiff_t, or if the memory + * could not be allocated. + * + * @note Using this function helps avoid -Walloc-size-larger-than warnings + * from gcc, which doesn't like attempts to malloc more than PTRDIFF_MAX. + * + */ + +static inline void * hts_malloc(size_t size) { + if (size >= HTS_SIZE_LIMIT) { + errno = ENOMEM; + return NULL; + } + return malloc(size); +} + +/** + * Allocate memory with checks for overflow, product of sizes + * + * @param a First term of product + * @param b Secord term of product + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be @p a * @p b bytes. NULL will be returned + * if the product is too big for a size_t or ptrdiff_t, or if the memory + * could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = malloc(number * sizeof(*ptr)); + * @endcode + * as it will detect cases where the product could overflow. + */ + +static inline void * hts_malloc_p(size_t a, size_t b) { + size_t prod = hts_prod_sat2(a, b); + return hts_malloc(prod); +} + +/** + * Allocate memory with checks for overflow, product of sum of sizes + * + * @param sz Size of item + * @param a First term of sum + * @param b Secord term of sum + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be @p sz * (@p a + @p b) bytes. NULL will be + * returned if the product is too big for a size_t or ptrdiff_t, or if the + * memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = malloc((a + b) * sizeof(*ptr)); + * @endcode + * as it will detect cases where the sum and/or product could overflow. + */ + +static inline void * hts_malloc_ps(size_t sz, size_t a, size_t b) { + size_t sum = hts_add_sat2(a, b); + size_t prod = hts_prod_sat2(sz, sum); + return hts_malloc(prod); +} + +/** + * Allocate memory with checks for overflow, product of sum of sizes plus extra bytes + * + * @param sz Element size + * @param a First term of sum + * @param b Second term of sum + * @param extra Extra space to allocate, in bytes + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be (@p a + @p b) * @p sz + @p extra bytes. + * NULL will be returned if the total is too big for a size_t or + * ptrdiff_t, or if the memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = malloc((a + b) * sizeof(*ptr) + extra); + * @endcode + * as it will detect cases where the sums and/or product could overflow. + */ + +static inline void * hts_malloc_pse(size_t sz, size_t a, size_t b, size_t extra) { + size_t sum = hts_add_sat2(a, b); + size_t prod = hts_prod_sat2(sz, sum); + size_t bytes = hts_add_sat2(prod, extra); + return hts_malloc(bytes); +} + +/** + * Allocate and clear memory with checks for overflow + * + * @param sz Size in bytes of each element + * @param num Number of elements + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be @p size bytes. NULL will be returned + * if the product is too big for a size_t or ptrdiff_t, or if the memory + * could not be allocated. + * + * @note Using this function helps avoid -Walloc-size-larger-than warnings + * from gcc, which doesn't like attempts to malloc more than PTRDIFF_MAX. + * + * @note In this function the size parameter is listed first to match + * the other hts_alloc interfaces, which is the opposite way round to calloc(). + * In practice this makes no difference as the values get multiplied together. + */ + +static inline void * hts_calloc(size_t sz, size_t num) { + if (num >= HTS_SIZE_LIMIT || sz >= HTS_SIZE_LIMIT) { + errno = ENOMEM; + return NULL; + } + return calloc(num, sz); +} + +/** + * Allocate and clear memory with checks for overflow, product of sum of sizes + * + * @param sz Element size + * @param a First term of sum + * @param b Second term of sum + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be (@p a + @p b) * @p sz + @p extra bytes. + * NULL will be returned if the total is too big for a size_t or + * ptrdiff_t, or if the memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = calloc(a + b, sizeof(*ptr)); + * @endcode + * as it will detect cases where the sum could overflow. + */ + +static inline void * hts_calloc_ps(size_t sz, size_t a, size_t b) { + size_t sum = hts_add_sat2(a, b); + return hts_calloc(sz, sum); +} + +/** + * Allocate and clear memory with checks for overflow + * + * @param sz Element size + * @param a First term of sum + * @param b Second term of sum + * @param extra Extra space to allocate, in bytes + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be (@p a + @p b) * @p sz + @p extra bytes. + * NULL will be returned if the total is too big for a size_t or + * ptrdiff_t, or if the memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = calloc((a + b) * sizeof(*ptr) + extra, 1); + * @endcode + * as it will detect cases where the sums and/or product could overflow. + */ + +static inline void * hts_calloc_pse(size_t sz, size_t a, size_t b, size_t extra) { + size_t sum = hts_add_sat2(a, b); + size_t prod = hts_prod_sat2(sz, sum); + size_t bytes = hts_add_sat2(prod, extra); + return hts_calloc(1, bytes); +} + +/** + * Rellocate memory with checks for overflow + * + * @return Pointer to the allocated memory, or NULL on error + */ + +static inline void * hts_realloc(void *orig, size_t size) { + if (size >= HTS_SIZE_LIMIT) { + errno = ENOMEM; + return NULL; + } + return realloc(orig, size); +} + +/** + * Rellocate memory with checks for overflow + * + * @param sz Size of item + * @param a First term of sum + * @param b Secord term of sum + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be @p sz * (@p a + @p b) bytes. NULL will be + * returned if the product is too big for a size_t or ptrdiff_t, or if the + * memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = realloc(orig, (a + b) * sizeof(*ptr)); + * @endcode + * as it will detect cases where the sum and/or product could overflow. + */ + +static inline void * hts_realloc_p(void *orig, size_t a, size_t b) { + size_t prod = hts_prod_sat2(a, b); + return hts_realloc(orig, prod); +} + +/** + * Rellocate memory with checks for overflow + * + * @param sz Element size + * @param a First term of sum + * @param b Second term of sum + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be (@p a + @p b) * @p sz bytes. + * NULL will be returned if the total is too big for a size_t or + * ptrdiff_t, or if the memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = realloc(orig, (a + b) * sizeof(*ptr)); + * @endcode + * as it will detect cases where the sum and/or product could overflow. + */ + +static inline void * hts_realloc_ps(void *orig, size_t sz, size_t a, size_t b) { + size_t sum = hts_add_sat2(a, b); + size_t prod = hts_prod_sat2(sz, sum); + return hts_realloc(orig, prod); +} + +/** + * Rellocate memory with checks for overflow + * + * @param sz Element size + * @param a First term of sum + * @param b Second term of sum + * @param extra Extra space to allocate, in bytes + * + * @return Pointer to the allocated memory, or NULL on error + * + * The total allocated will be (@p a + @p b) * @p sz + @p extra bytes. + * NULL will be returned if the total is too big for a size_t or + * ptrdiff_t, or if the memory could not be allocated. + * + * This function is a safer replacement for the idiom + * @code{c} + * ptr = realloc(orig, (a + b) * sizeof(*ptr) + extra); + * @endcode + * as it will detect cases where the sums and/or product could overflow. + */ + +static inline void * hts_realloc_pse(void *orig, size_t sz, size_t a, size_t b, + size_t extra) { + size_t sum = hts_add_sat2(a, b); + size_t prod = hts_prod_sat2(sz, sum); + size_t bytes = hts_add_sat2(prod, extra); + return hts_realloc(orig, bytes); +} + +#undef HTS_SIZE_LIMIT + +#ifdef __cplusplus +} +#endif + +#endif /* HTSLIB_HTS_ALLOC_H */ From f17dfbce6878e47e6f96e39ae07b5f67833d58f6 Mon Sep 17 00:00:00 2001 From: Rob Davies Date: Thu, 7 May 2026 15:25:33 +0100 Subject: [PATCH 2/3] Add hts_alloc tests --- .gitignore | 1 + Makefile | 6 + test/test_alloc.c | 327 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+) create mode 100644 test/test_alloc.c diff --git a/.gitignore b/.gitignore index 6aee57ace..a485dce54 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ shlib-exports-*.txt /test/sam /test/ref_cache/*.tmp.* /test/tabix/*.tmp.* +/test/test_alloc /test/test-bcf-sr /test/test-bcf-translate /test/test-bcf_set_variant_type diff --git a/Makefile b/Makefile index 6eab6ca6e..2edabd8bc 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,7 @@ BUILT_TEST_PROGRAMS = \ test/pileup_mod \ test/plugins-dlhts \ test/sam \ + test/test_alloc \ test/test_bgzf \ test/test_expr \ test/test_faidx \ @@ -682,6 +683,7 @@ SRC = $(srcprefix) # MSYS2_ARG_CONV_EXCL="*" make check check test: all $(HTSCODECS_TEST_TARGETS) test/hts_endian + test/test_alloc test/test_expr test/test_kfunc test/test_khash @@ -748,6 +750,9 @@ test/plugins-dlhts: test/plugins-dlhts.o test/sam: test/sam.o libhts.a $(CC) $(LDFLAGS) -o $@ test/sam.o libhts.a $(LIBS) -lpthread +test/test_alloc: test/test_alloc.o + $(CC) $(LDFLAGS) -o $@ test/test_alloc.o + test/test_bgzf: test/test_bgzf.o libhts.a $(CC) $(LDFLAGS) -o $@ test/test_bgzf.o libhts.a $(LIBS) -lpthread @@ -872,6 +877,7 @@ test/pileup.o: test/pileup.c config.h $(htslib_sam_h) $(htslib_kstring_h) test/pileup_mod.o: test/pileup_mod.c config.h $(htslib_sam_h) test/plugins-dlhts.o: test/plugins-dlhts.c config.h test/sam.o: test/sam.c config.h $(htslib_hts_defs_h) $(htslib_sam_h) $(htslib_faidx_h) $(htslib_khash_h) $(htslib_hts_log_h) +test/test_alloc.o: test/test_alloc.c config.h $(htslib_hts_alloc_h) test/test_bgzf.o: test/test_bgzf.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_hts_log_h) $(hfile_internal_h) test/test_expr.o: test/test_expr.c config.h $(htslib_hts_expr_h) test/test_kfunc.o: test/test_kfunc.c config.h $(htslib_kfunc_h) diff --git a/test/test_alloc.c b/test/test_alloc.c new file mode 100644 index 000000000..b7c23f39d --- /dev/null +++ b/test/test_alloc.c @@ -0,0 +1,327 @@ +/* test_alloc.c -- hts_alloc unit tests + + Copyright (C) 2026 Genome Research Ltd. + + Author: Rob Davies + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include +#include "../htslib/hts_alloc.h" + +typedef struct { + size_t a; + size_t b; + size_t expected; +} test_case_t; + +static int try_add_sat2(size_t a, size_t b, size_t expected, int verbose) { + size_t r_ab = hts_add_sat2(a, b); + size_t r_ba = hts_add_sat2(b, a); + int fails = 0; + if (r_ab != expected) { + fails++; + fprintf(stderr, + "Failed: hts_add_sat2(%zu, %zu) got %zu expected %zu\n", + a, b, r_ab, expected); + } else if (verbose) { + fprintf(stderr, "hts_add_sat2(%zu, %zu) = %zu\n", a, b, r_ab); + } + if (r_ba != expected) { + fails++; + fprintf(stderr, + "Failed: hts_add_sat2(%zu, %zu) got %zu expected %zu\n", + b, a, r_ba, expected); + } else if (verbose) { + fprintf(stderr, "hts_add_sat2(%zu, %zu) = %zu\n", b, a, r_ba); + } + return fails; +} + +static int test_add_sat2(int verbose) { + const test_case_t tests[] = { + { 0, 0, 0 }, + { 0, 1, 1 }, + { 1, 1, 2 }, + { 0, SIZE_MAX - 1, SIZE_MAX - 1 }, + { 1, SIZE_MAX - 1, SIZE_MAX }, + { 2, SIZE_MAX - 1, SIZE_MAX }, + { 0, SIZE_MAX, SIZE_MAX }, + { 0, SIZE_MAX, SIZE_MAX }, + { SIZE_MAX, SIZE_MAX, SIZE_MAX }, + }; + size_t n; + int fails = 0; + + for (n = 0; n < sizeof(tests)/sizeof(tests[0]); n++) { + fails += try_add_sat2(tests[n].a, tests[n].b, tests[n].expected, verbose); + } + return fails; +} + +static int try_prod_sat2(size_t a, size_t b, size_t expected, int verbose) { + size_t r_ab = hts_prod_sat2(a, b); + size_t r_ba = hts_prod_sat2(b, a); + int fails = 0; + if (r_ab != expected) { + fails++; + fprintf(stderr, + "Failed: hts_prod_sat2(%zu, %zu) got %zu expected %zu\n", + a, b, r_ab, expected); + } else if (verbose) { + fprintf(stderr, "hts_prod_sat2(%zu, %zu) = %zu\n", a, b, r_ab); + } + if (r_ba != expected) { + fails++; + fprintf(stderr, + "Failed: hts_prod_sat2(%zu, %zu) got %zu expected %zu\n", + b, a, r_ba, expected); + } else if (verbose) { + fprintf(stderr, "hts_prod_sat2(%zu, %zu) = %zu\n", b, a, r_ba); + } + return fails; +} + +static int test_prod_sat2(int verbose) { + const test_case_t tests[] = { + { 0, 0, 0 }, + { 0, 1, 0 }, + { 1, 1, 1 }, + { 2, 3, 6 }, + { 0, SIZE_MAX, 0 }, + { 1, SIZE_MAX - 1, SIZE_MAX - 1 }, + { 2, SIZE_MAX - 1, SIZE_MAX }, + { 0, SIZE_MAX, 0 }, + { 1, SIZE_MAX, SIZE_MAX }, + { 2, SIZE_MAX, SIZE_MAX }, + { SIZE_MAX, SIZE_MAX, SIZE_MAX }, + }; + size_t n, size_bits = sizeof(size_t) * 8; + int fails = 0; + + for (n = 0; n < sizeof(tests)/sizeof(tests[0]); n++) { + fails += try_prod_sat2(tests[n].a, tests[n].b, tests[n].expected, + verbose); + } + + for (n = 0; n < size_bits; n++) { + size_t a = ((size_t) 1) << n; + size_t b = ((size_t) 1) << (size_bits - 1 - n); + // Should not overflow + fails += try_prod_sat2(a, b, ((size_t) 1) << (size_bits - 1), verbose); + if (n > 0) { + // Should overflow + fails += try_prod_sat2(a, b * 2, SIZE_MAX, verbose); + } + } + + return fails; +} + +static void ptr2hex(char *out, size_t sz, void *ptr) { + if (ptr) { + snprintf(out, sz, "0x%p", ptr); + } else { + snprintf(out, sz, "NULL"); + } +} + +static int alloc_result(const char *prefix, size_t a, size_t b, + const char *suffix, void *ptr, size_t should_work, + int verbose) { + char pbuf[32]; + int failed = 0; + if ((ptr != NULL) ^ should_work) { + failed = 1; + ptr2hex(pbuf, sizeof(pbuf), ptr); + fprintf(stderr, "Failed: %s%zu, %zu%s got %s expected %s\n", + prefix, a, b, suffix, pbuf, should_work ? "pointer" : "NULL"); + } else if (verbose) { + ptr2hex(pbuf, sizeof(pbuf), ptr); + fprintf(stderr, "%s%zu, %zu%s = %s\n", prefix, a, b, suffix, pbuf); + } + return failed; +} + +static int test_malloc(unsigned long max_mb, int verbose) { + const size_t size_limit = PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX; + const size_t max_bytes = hts_prod_sat2(1024*1024, max_mb); + test_case_t tests[] = { + { 1, 1, 1 }, + { max_bytes, 1, 1 }, + { 1, max_bytes, 1 }, + { max_bytes / 2, 2, 1 }, + { 2, max_bytes / 2, 1 }, + { size_limit, 1, 0 }, + { 1, size_limit, 0 }, + { 2, SIZE_MAX / 2 + 100, 0 }, + { SIZE_MAX / 2 + 100, 2, 0 }, + }; + size_t n; + int fails = 0, i; + for (n = 0; n < sizeof(tests)/sizeof(tests[0]); n++) { + void *ptr = hts_malloc_p(tests[n].a, tests[n].b); + fails += alloc_result("hts_malloc_p(", tests[n].a, tests[n].b, ")", + ptr, tests[n].expected, verbose); + free(ptr); + + if (tests[n].b > 100) { + char suffix[32]; + ptr = hts_malloc_ps(tests[n].a, tests[n].b - 100, 100); + fails += alloc_result("hts_malloc_ps(", + tests[n].a, tests[n].b - 100, ", 100)", + ptr, tests[n].expected, verbose); + free(ptr); + + ptr = hts_calloc_ps(tests[n].a, tests[n].b - 100, 100); + fails += alloc_result("hts_calloc_ps(", + tests[n].a, tests[n].b - 100, ", 100)", + ptr, tests[n].expected, verbose); + free(ptr); + + snprintf(suffix, sizeof(suffix), ", %zu)", tests[n].a * 100); + ptr = hts_malloc_pse(tests[n].a, tests[n].b - 100, 0, + tests[n].a * 100); + fails += alloc_result("hts_malloc_pse(", + tests[n].a, tests[n].b - 100, suffix, + ptr, tests[n].expected, verbose); + free(ptr); + + ptr = hts_calloc_pse(tests[n].a, tests[n].b - 100, 0, + tests[n].a * 100); + fails += alloc_result("hts_calloc_pse(", + tests[n].a, tests[n].b - 100, suffix, + ptr, tests[n].expected, verbose); + free(ptr); + } + + if (tests[n].expected) { + ptr = hts_malloc_ps(tests[n].a, tests[n].b, size_limit); + fails += alloc_result("hts_malloc_ps(", + tests[n].a, tests[n].b, ", size_limit)", + ptr, 0, verbose); + free(ptr); + + ptr = hts_malloc_pse(tests[n].a, tests[n].b, 0, size_limit); + fails += alloc_result("hts_malloc_pse(", + tests[n].a, tests[n].b, ", 0, size_limit)", + ptr, 0, verbose); + free(ptr); + } + + for (i = 0; i < 2; i++) { + // i == 0 start with a NULL pointer + // i == 1 start with an allocted pointer + void *tmp = i ? malloc(1) : NULL; + const char *prefix = i ? "hts_realloc_p(ptr, " : "hts_realloc_p(NULL, "; + ptr = hts_realloc_p(tmp, tests[n].a, tests[n].b); + fails += alloc_result(prefix, tests[n].a, tests[n].b, ")", + ptr, tests[n].expected, verbose); + free(ptr ? ptr : tmp); + + if (tests[n].b > 100) { + char suffix[32]; + tmp = i ? malloc(1) : NULL; + prefix = i ? "hts_realloc_ps(ptr, " : "hts_realloc_ps(NULL, "; + ptr = hts_realloc_ps(tmp, tests[n].a, tests[n].b - 100, 100); + fails += alloc_result(prefix, + tests[n].a, tests[n].b - 100, ", 100)", + ptr, tests[n].expected, verbose); + free(ptr ? ptr : tmp); + + tmp = i ? malloc(1) : NULL; + prefix = i ? "hts_realloc_pse(ptr, " : "hts_realloc_pse(NULL, "; + snprintf(suffix, sizeof(suffix), ", %zu)", tests[n].a * 100); + ptr = hts_realloc_pse(tmp, tests[n].a, tests[n].b - 100, 0, + tests[n].a * 100); + fails += alloc_result(prefix, + tests[n].a, tests[n].b - 100, suffix, + ptr, tests[n].expected, verbose); + free(ptr ? ptr : tmp); + } + + if (tests[n].expected) { + tmp = i ? malloc(1) : NULL; + prefix = i ? "hts_realloc_ps(ptr, " : "hts_realloc_ps(NULL, "; + ptr = hts_realloc_ps(tmp, tests[n].a, tests[n].b, size_limit); + fails += alloc_result("hts_realloc_ps(NULL, ", + tests[n].a, tests[n].b, ", size_limit)", + ptr, 0, verbose); + free(ptr ? ptr : tmp); + + tmp = i ? malloc(1) : NULL; + prefix = i ? "hts_realloc_pse(ptr, " : "hts_realloc_pse(NULL, "; + ptr = hts_realloc_pse(tmp, tests[n].a, tests[n].b, 0, size_limit); + fails += alloc_result("hts_realloc_pse(NULL, ", + tests[n].a, tests[n].b, ", 0, size_limit)", + ptr, 0, verbose); + free(ptr ? ptr : tmp); + } + } + } + return fails; +} + +void show_help(FILE *fp) { + fprintf(fp, "Usage: test_alloc [-m ] [-v]\n"); +} + +int main(int argc, char **argv) { + int fails = 0; + int verbose = 0; + unsigned long max_mb = 10, max_max_mb = sizeof(size_t) > 4 ? 50000 : 2100; + int opt; + + while ((opt = getopt(argc, argv, "m:v")) > 0) { + switch (opt) { + case 'm': + max_mb = strtoul(optarg, NULL, 0); + if (max_mb < 1 || max_mb > max_max_mb) { + fprintf(stderr, "test_alloc: -m should be between 1 and %lu\n", + max_max_mb); + show_help(stderr); + return EXIT_FAILURE; + } + break; + case 'v': + verbose = 1; + break; + case 'h': + show_help(stdout); + return EXIT_SUCCESS; + default: + fprintf(stderr, "test_alloc: Unknown option '%c'\n", opt); + show_help(stderr); + return EXIT_FAILURE; + } + } + + fails += test_add_sat2(verbose); + fails += test_prod_sat2(verbose); + fails += test_malloc(max_mb, verbose); + if (fails > 0) { + fprintf(stderr, "test_alloc: %d tests failed\n", fails); + } + return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} From ee317af243605ff0fbdbcac0d862c0d2e36d1c5c Mon Sep 17 00:00:00 2001 From: Rob Davies Date: Mon, 20 Apr 2026 11:25:45 +0100 Subject: [PATCH 3/3] Use malloc wrappers --- Makefile | 74 +++++++++++++++++++------------------- annot-tsv.c | 9 ++--- bcf_sr_sort.c | 10 ++++-- bgzf.c | 15 ++++---- bgzip.c | 4 ++- cram/cram_codecs.c | 27 +++++++------- cram/cram_decode.c | 15 ++++---- cram/cram_encode.c | 28 ++++++++------- cram/cram_external.c | 7 ++-- cram/cram_index.c | 9 ++--- cram/cram_io.c | 14 ++++---- cram/cram_stats.c | 9 ++--- cram/pooled_alloc.c | 5 +-- cram/string_alloc.c | 3 +- faidx.c | 5 +-- header.c | 42 +++++++++++----------- hfile_libcurl.c | 5 +-- hfile_s3.c | 11 +++--- hts.c | 34 +++++++++--------- hts_expr.c | 7 ++-- htslib/kbitset.h | 5 +-- htslib/ksort.h | 6 ++-- htslib_vars.mk | 5 +-- kstring.c | 5 +-- probaln.c | 5 +-- realn.c | 5 +-- ref_cache/listener.c | 5 +-- ref_cache/log_files.c | 3 +- ref_cache/main.c | 10 +++--- ref_cache/poll_wrap_poll.c | 15 ++++---- regidx.c | 9 ++--- sam.c | 20 ++++++----- synced_bcf_reader.c | 22 +++++++----- tabix.c | 5 +-- tbx.c | 5 +-- test/test-bcf-sr.c | 3 +- test/test-vcf-api.c | 3 +- test/test_khash.c | 5 +-- thread_pool.c | 5 +-- vcf.c | 50 +++++++++++++------------- vcfutils.c | 8 +++-- 41 files changed, 297 insertions(+), 235 deletions(-) diff --git a/Makefile b/Makefile index 2edabd8bc..ddbfff899 100644 --- a/Makefile +++ b/Makefile @@ -495,49 +495,49 @@ hts-object-files: $(LIBHTS_OBJS) $(CC) -shared $(LDFLAGS) -o $@ $< hts.dll.a $(LIBS) -bgzf.o bgzf.pico: bgzf.c config.h $(htslib_hts_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_thread_pool_h) $(htslib_hts_endian_h) cram/pooled_alloc.h $(hts_internal_h) $(bgzf_internal_h) $(htslib_khash_h) +bgzf.o bgzf.pico: bgzf.c config.h $(htslib_hts_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_thread_pool_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) cram/pooled_alloc.h $(hts_internal_h) $(bgzf_internal_h) $(htslib_khash_h) errmod.o errmod.pico: errmod.c config.h $(htslib_hts_h) $(htslib_ksort_h) $(htslib_hts_os_h) -kstring.o kstring.pico: kstring.c config.h $(htslib_kstring_h) -header.o header.pico: header.c config.h $(textutils_internal_h) $(header_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_kseq_h) +kstring.o kstring.pico: kstring.c config.h $(htslib_kstring_h) $(htslib_hts_alloc_h) +header.o header.pico: header.c config.h $(textutils_internal_h) $(header_h) $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_hts_alloc_h) $(htslib_kseq_h) hfile.o hfile.pico: hfile.c config.h $(htslib_hfile_h) $(hfile_internal_h) $(htslib_kstring_h) $(hts_internal_h) $(htslib_khash_h) hfile_gcs.o hfile_gcs.pico: hfile_gcs.c config.h $(htslib_hts_h) $(htslib_kstring_h) $(hfile_internal_h) -hfile_libcurl.o hfile_libcurl.pico: hfile_libcurl.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_kstring_h) $(htslib_khash_h) -hfile_s3.o hfile_s3.pico: hfile_s3.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_kstring_h) $(hts_time_funcs_h) -hts.o hts.pico: hts.c config.h os/lzma_stub.h $(htslib_hts_h) $(htslib_bgzf_h) $(cram_h) $(htslib_hfile_h) $(htslib_hts_endian_h) version.h config_vars.h $(hts_internal_h) $(hfile_internal_h) $(sam_internal_h) $(htslib_hts_expr_h) $(htslib_hts_os_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_ksort_h) $(htslib_tbx_h) $(htscodecs_htscodecs_h) -hts_expr.o hts_expr.pico: hts_expr.c config.h $(htslib_hts_expr_h) $(htslib_hts_log_h) $(textutils_internal_h) +hfile_libcurl.o hfile_libcurl.pico: hfile_libcurl.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_kstring_h) $(htslib_khash_h) +hfile_s3.o hfile_s3.pico: hfile_s3.c config.h $(hfile_internal_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_kstring_h) $(hts_time_funcs_h) +hts.o hts.pico: hts.c config.h os/lzma_stub.h $(htslib_hts_h) $(htslib_bgzf_h) $(cram_h) $(htslib_hfile_h) $(htslib_hts_endian_h) version.h config_vars.h $(hts_internal_h) $(hfile_internal_h) $(sam_internal_h) $(htslib_hts_alloc_h) $(htslib_hts_expr_h) $(htslib_hts_os_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_ksort_h) $(htslib_tbx_h) $(htscodecs_htscodecs_h) +hts_expr.o hts_expr.pico: hts_expr.c config.h $(htslib_hts_expr_h) $(htslib_hts_alloc_h) $(htslib_hts_log_h) $(textutils_internal_h) hts_os.o hts_os.pico: hts_os.c config.h $(htslib_hts_defs_h) os/rand.c -vcf.o vcf.pico: vcf.c config.h $(fuzz_settings_h) $(htslib_vcf_h) $(htslib_bgzf_h) $(htslib_tbx_h) $(htslib_hfile_h) $(hts_internal_h) $(htslib_khash_str2int_h) $(htslib_kstring_h) $(htslib_sam_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_hts_endian_h) $(bgzf_internal_h) -sam.o sam.pico: sam.c config.h $(fuzz_settings_h) $(htslib_hts_defs_h) $(htslib_sam_h) $(htslib_bgzf_h) $(cram_h) $(hts_internal_h) $(sam_internal_h) $(htslib_hfile_h) $(htslib_hts_endian_h) $(htslib_hts_expr_h) $(header_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_kstring_h) +vcf.o vcf.pico: vcf.c config.h $(fuzz_settings_h) $(htslib_vcf_h) $(htslib_bgzf_h) $(htslib_tbx_h) $(htslib_hfile_h) $(hts_internal_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) $(htslib_khash_str2int_h) $(htslib_kstring_h) $(htslib_sam_h) $(htslib_khash_h) $(htslib_kseq_h) $(bgzf_internal_h) +sam.o sam.pico: sam.c config.h $(fuzz_settings_h) $(htslib_hts_defs_h) $(htslib_sam_h) $(htslib_bgzf_h) $(cram_h) $(hts_internal_h) $(sam_internal_h) $(htslib_hfile_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) $(htslib_hts_expr_h) $(header_h) $(htslib_khash_h) $(htslib_kseq_h) $(htslib_kstring_h) sam_mods.o sam_mods.pico: sam_mods.c config.h $(htslib_sam_h) $(textutils_internal_h) simd.o simd.pico: simd.c config.h $(htslib_sam_h) $(sam_internal_h) -tbx.o tbx.pico: tbx.c config.h $(htslib_tbx_h) $(htslib_bgzf_h) $(htslib_hts_endian_h) $(hts_internal_h) $(htslib_khash_h) -faidx.o faidx.pico: faidx.c config.h $(htslib_bgzf_h) $(htslib_faidx_h) $(htslib_hfile_h) $(htslib_khash_h) $(htslib_kstring_h) $(hts_internal_h) -bcf_sr_sort.o bcf_sr_sort.pico: bcf_sr_sort.c config.h $(bcf_sr_sort_h) $(htslib_khash_str2int_h) $(htslib_kbitset_h) -synced_bcf_reader.o synced_bcf_reader.pico: synced_bcf_reader.c config.h $(htslib_synced_bcf_reader_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_bgzf_h) $(htslib_thread_pool_h) $(bcf_sr_sort_h) +tbx.o tbx.pico: tbx.c config.h $(htslib_tbx_h) $(htslib_bgzf_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) $(hts_internal_h) $(htslib_khash_h) +faidx.o faidx.pico: faidx.c config.h $(htslib_bgzf_h) $(htslib_faidx_h) $(htslib_hfile_h) $(htslib_hts_alloc_h) $(htslib_khash_h) $(htslib_kstring_h) $(hts_internal_h) +bcf_sr_sort.o bcf_sr_sort.pico: bcf_sr_sort.c config.h $(bcf_sr_sort_h) $(htslib_khash_str2int_h) $(htslib_kbitset_h) $(htslib_hts_alloc_h) +synced_bcf_reader.o synced_bcf_reader.pico: synced_bcf_reader.c config.h $(htslib_synced_bcf_reader_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_bgzf_h) $(htslib_hts_alloc_h) $(htslib_thread_pool_h) $(bcf_sr_sort_h) vcf_sweep.o vcf_sweep.pico: vcf_sweep.c config.h $(htslib_vcf_sweep_h) $(htslib_bgzf_h) -vcfutils.o vcfutils.pico: vcfutils.c config.h $(htslib_vcfutils_h) $(htslib_kbitset_h) +vcfutils.o vcfutils.pico: vcfutils.c config.h $(htslib_vcfutils_h) $(htslib_hts_alloc_h) $(htslib_kbitset_h) kfunc.o kfunc.pico: kfunc.c config.h $(htslib_kfunc_h) -regidx.o regidx.pico: regidx.c config.h $(htslib_hts_h) $(htslib_kstring_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_regidx_h) $(hts_internal_h) +regidx.o regidx.pico: regidx.c config.h $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_kstring_h) $(htslib_kseq_h) $(htslib_khash_str2int_h) $(htslib_regidx_h) $(hts_internal_h) region.o region.pico: region.c config.h $(htslib_hts_h) $(htslib_khash_h) md5.o md5.pico: md5.c config.h $(htslib_hts_h) $(htslib_hts_endian_h) multipart.o multipart.pico: multipart.c config.h $(htslib_kstring_h) $(hts_internal_h) $(hfile_internal_h) plugin.o plugin.pico: plugin.c config.h $(hts_internal_h) $(htslib_kstring_h) -probaln.o probaln.pico: probaln.c config.h $(htslib_hts_h) -realn.o realn.pico: realn.c config.h $(htslib_hts_h) $(htslib_sam_h) +probaln.o probaln.pico: probaln.c config.h $(htslib_hts_h) $(htslib_hts_alloc_h) +realn.o realn.pico: realn.c config.h $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_sam_h) textutils.o textutils.pico: textutils.c config.h $(htslib_hfile_h) $(htslib_kstring_h) $(htslib_sam_h) $(hts_internal_h) -cram/cram_codecs.o cram/cram_codecs.pico: cram/cram_codecs.c config.h $(fuzz_settings_h) $(htslib_hts_endian_h) $(htscodecs_varint_h) $(htscodecs_pack_h) $(htscodecs_rle_h) $(cram_h) -cram/cram_decode.o cram/cram_decode.pico: cram/cram_decode.c config.h $(cram_h) $(cram_os_h) $(htslib_hts_h) $(htslib_hfile_h) -cram/cram_encode.o cram/cram_encode.pico: cram/cram_encode.c config.h $(cram_h) $(cram_os_h) $(sam_internal_h) $(htslib_hts_h) $(htslib_hts_endian_h) $(textutils_internal_h) -cram/cram_external.o cram/cram_external.pico: cram/cram_external.c config.h $(htscodecs_rANS_static4x16_h) $(htslib_hfile_h) $(cram_h) -cram/cram_index.o cram/cram_index.pico: cram/cram_index.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(hts_internal_h) $(cram_h) $(cram_os_h) -cram/cram_io.o cram/cram_io.pico: cram/cram_io.c config.h os/lzma_stub.h $(fuzz_settings_h) $(cram_h) $(cram_os_h) $(htslib_hts_h) $(hts_internal_h) $(cram_open_trace_file_h) $(htscodecs_rANS_static_h) $(htscodecs_rANS_static4x16_h) $(htscodecs_arith_dynamic_h) $(htscodecs_tokenise_name3_h) $(htscodecs_fqzcomp_qual_h) $(htscodecs_varint_h) $(htslib_hfile_h) $(htslib_bgzf_h) $(htslib_faidx_h) $(hts_internal_h) -cram/cram_stats.o cram/cram_stats.pico: cram/cram_stats.c config.h $(cram_h) $(cram_os_h) +cram/cram_codecs.o cram/cram_codecs.pico: cram/cram_codecs.c config.h $(fuzz_settings_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) $(htscodecs_varint_h) $(htscodecs_pack_h) $(htscodecs_rle_h) $(cram_h) +cram/cram_decode.o cram/cram_decode.pico: cram/cram_decode.c config.h $(cram_h) $(cram_os_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_hfile_h) +cram/cram_encode.o cram/cram_encode.pico: cram/cram_encode.c config.h $(cram_h) $(cram_os_h) $(sam_internal_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_hts_endian_h) $(textutils_internal_h) +cram/cram_external.o cram/cram_external.pico: cram/cram_external.c config.h $(htscodecs_rANS_static4x16_h) $(htslib_hfile_h) $(htslib_hts_alloc_h) $(cram_h) +cram/cram_index.o cram/cram_index.pico: cram/cram_index.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_hts_alloc_h) $(hts_internal_h) $(cram_h) $(cram_os_h) +cram/cram_io.o cram/cram_io.pico: cram/cram_io.c config.h os/lzma_stub.h $(fuzz_settings_h) $(cram_h) $(cram_os_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(hts_internal_h) $(cram_open_trace_file_h) $(htscodecs_rANS_static_h) $(htscodecs_rANS_static4x16_h) $(htscodecs_arith_dynamic_h) $(htscodecs_tokenise_name3_h) $(htscodecs_fqzcomp_qual_h) $(htscodecs_varint_h) $(htslib_hfile_h) $(htslib_bgzf_h) $(htslib_faidx_h) $(hts_internal_h) +cram/cram_stats.o cram/cram_stats.pico: cram/cram_stats.c config.h $(cram_h) $(cram_os_h) $(htslib_hts_alloc_h) cram/mFILE.o cram/mFILE.pico: cram/mFILE.c config.h $(htslib_hts_log_h) $(cram_os_h) cram/mFILE.h cram/open_trace_file.o cram/open_trace_file.pico: cram/open_trace_file.c config.h $(cram_os_h) $(cram_open_trace_file_h) $(cram_misc_h) $(htslib_hfile_h) $(htslib_hts_log_h) $(htslib_hts_h) -cram/pooled_alloc.o cram/pooled_alloc.pico: cram/pooled_alloc.c config.h cram/pooled_alloc.h $(cram_misc_h) -cram/string_alloc.o cram/string_alloc.pico: cram/string_alloc.c config.h cram/string_alloc.h -thread_pool.o thread_pool.pico: thread_pool.c config.h $(thread_pool_internal_h) $(htslib_hts_log_h) $(hts_internal_h) +cram/pooled_alloc.o cram/pooled_alloc.pico: cram/pooled_alloc.c config.h cram/pooled_alloc.h $(cram_misc_h) $(htslib_hts_alloc_h) +cram/string_alloc.o cram/string_alloc.pico: cram/string_alloc.c config.h cram/string_alloc.h $(htslib_hts_alloc_h) +thread_pool.o thread_pool.pico: thread_pool.c config.h $(thread_pool_internal_h) $(htslib_hts_alloc_h) $(htslib_hts_log_h) $(hts_internal_h) htscodecs/htscodecs/arith_dynamic.o htscodecs/htscodecs/arith_dynamic.pico: htscodecs/htscodecs/arith_dynamic.c config.h $(htscodecs_arith_dynamic_h) $(htscodecs_varint_h) $(htscodecs_pack_h) $(htscodecs_utils_h) $(htscodecs_c_simple_model_h) htscodecs/htscodecs/fqzcomp_qual.o htscodecs/htscodecs/fqzcomp_qual.pico: htscodecs/htscodecs/fqzcomp_qual.c config.h $(htscodecs_fqzcomp_qual_h) $(htscodecs_varint_h) $(htscodecs_utils_h) $(htscodecs_c_simple_model_h) @@ -574,10 +574,10 @@ tabix: tabix.o libhts.a ref_cache/ref-cache: $(REF_CACHE_OBJS) $(CC) $(LDFLAGS) $(REF_CACHE_EXTRA_LD_FLAGS) -o $@ $(REF_CACHE_OBJS) -lcurl -annot-tsv.o: annot-tsv.c config.h $(htslib_hts_h) $(htslib_hts_defs_h) $(htslib_khash_str2int_h) $(htslib_kstring_h) $(htslib_kseq_h) $(htslib_bgzf_h) $(htslib_regidx_h) $(textutils_internal_h) -bgzip.o: bgzip.c config.h $(htslib_bgzf_h) $(htslib_hts_h) $(htslib_hfile_h) +annot-tsv.o: annot-tsv.c config.h $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_hts_defs_h) $(htslib_khash_str2int_h) $(htslib_kstring_h) $(htslib_kseq_h) $(htslib_bgzf_h) $(htslib_regidx_h) $(textutils_internal_h) +bgzip.o: bgzip.c config.h $(htslib_bgzf_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_hfile_h) htsfile.o: htsfile.c config.h $(htslib_hfile_h) $(htslib_hts_h) $(htslib_sam_h) $(htslib_vcf_h) -tabix.o: tabix.c config.h $(htslib_tbx_h) $(htslib_sam_h) $(htslib_vcf_h) $(htslib_kseq_h) $(htslib_bgzf_h) $(htslib_hts_h) $(htslib_regidx_h) $(htslib_hts_defs_h) $(htslib_hts_log_h) $(htslib_thread_pool_h) +tabix.o: tabix.c config.h $(htslib_tbx_h) $(htslib_sam_h) $(htslib_vcf_h) $(htslib_kseq_h) $(htslib_bgzf_h) $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_regidx_h) $(htslib_hts_defs_h) $(htslib_hts_log_h) $(htslib_thread_pool_h) # ref_cache dependencies ref_cache_cmsg_wrap_h = ref_cache/cmsg_wrap.h @@ -598,12 +598,12 @@ ref_cache_upstream_h = ref_cache/upstream.h $(ref_cache_types_h) ref_cache/cmsg_wrap.o: ref_cache/cmsg_wrap.c config.h $(ref_cache_cmsg_wrap_h) ref_cache/http_parser.o: ref_cache/http_parser.c config.h $(ref_cache_http_parser_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_request_handler_h) $(ref_cache_server_h) cram/pooled_alloc.h -ref_cache/listener.o: ref_cache/listener.c config.h $(ref_cache_listener_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_poll_wrap_h) -ref_cache/log_files.o: ref_cache/log_files.c config.h $(ref_cache_log_files_h) $(ref_cache_options_h) -ref_cache/main.o: ref_cache/main.c config.h $(ref_cache_listener_h) $(ref_cache_log_files_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_ping_h) $(ref_cache_poll_wrap_h) $(ref_cache_server_h) $(ref_cache_upstream_h) +ref_cache/listener.o: ref_cache/listener.c config.h $(ref_cache_listener_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_poll_wrap_h) $(htslib_hts_alloc_h) +ref_cache/log_files.o: ref_cache/log_files.c config.h $(ref_cache_log_files_h) $(ref_cache_options_h) $(htslib_hts_alloc_h) +ref_cache/main.o: ref_cache/main.c config.h $(ref_cache_listener_h) $(ref_cache_log_files_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_ping_h) $(ref_cache_poll_wrap_h) $(ref_cache_server_h) $(ref_cache_upstream_h) $(htslib_hts_alloc_h) ref_cache/ping.o: ref_cache/ping.c config.h $(ref_cache_ping_h) $(ref_cache_misc_h) $(ref_cache_options_h) ref_cache/poll_wrap_epoll.o: ref_cache/poll_wrap_epoll.c config.h $(ref_cache_poll_wrap_h) cram/pooled_alloc.h -ref_cache/poll_wrap_poll.o: ref_cache/poll_wrap_poll.c config.h $(ref_cache_poll_wrap_h) cram/pooled_alloc.h +ref_cache/poll_wrap_poll.o: ref_cache/poll_wrap_poll.c config.h $(ref_cache_poll_wrap_h) $(htslib_hts_alloc_h) cram/pooled_alloc.h ref_cache/ref_files.o: ref_cache/ref_files.c config.h $(ref_cache_ref_files_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_upstream_h) ref_cache/request_handler.o: ref_cache/request_handler.c config.h $(ref_cache_request_handler_h) $(ref_cache_http_parser_h) $(ref_cache_misc_h) $(ref_cache_options_h) $(ref_cache_ref_files_h) $(ref_cache_transaction_h) $(ref_cache_upstream_h) ref_cache/sendfile_wrap.o: ref_cache/sendfile_wrap.c config.h $(ref_cache_sendfile_wrap_h) @@ -881,7 +881,7 @@ test/test_alloc.o: test/test_alloc.c config.h $(htslib_hts_alloc_h) test/test_bgzf.o: test/test_bgzf.c config.h $(htslib_bgzf_h) $(htslib_hfile_h) $(htslib_hts_log_h) $(hfile_internal_h) test/test_expr.o: test/test_expr.c config.h $(htslib_hts_expr_h) test/test_kfunc.o: test/test_kfunc.c config.h $(htslib_kfunc_h) -test/test_khash.o: test/test_khash.c config.h $(htslib_khash_h) $(htslib_kroundup_h) +test/test_khash.o: test/test_khash.c config.h $(htslib_hts_alloc_h) $(htslib_khash_h) $(htslib_kroundup_h) test/test_kstring.o: test/test_kstring.c config.h $(htslib_kstring_h) kstring.c test/test_mod.o: test/test_mod.c config.h $(htslib_sam_h) test/test_nibbles.o: test/test_nibbles.c config.h $(htslib_sam_h) $(sam_internal_h) @@ -893,9 +893,9 @@ test/test_time_funcs.o: test/test_time_funcs.c config.h $(hts_time_funcs_h) test/test_view.o: test/test_view.c config.h $(cram_h) $(htslib_sam_h) $(htslib_vcf_h) $(htslib_hts_log_h) test/test_faidx.o: test/test_faidx.c config.h $(htslib_faidx_h) test/test_index.o: test/test_index.c config.h $(htslib_sam_h) $(htslib_vcf_h) -test/test-vcf-api.o: test/test-vcf-api.c config.h $(htslib_hts_h) $(htslib_vcf_h) $(htslib_vcfutils_h) $(htslib_kbitset_h) $(htslib_kstring_h) $(htslib_kseq_h) +test/test-vcf-api.o: test/test-vcf-api.c config.h $(htslib_hts_h) $(htslib_hts_alloc_h) $(htslib_vcf_h) $(htslib_vcfutils_h) $(htslib_kbitset_h) $(htslib_kstring_h) $(htslib_kseq_h) test/test-vcf-sweep.o: test/test-vcf-sweep.c config.h $(htslib_vcf_sweep_h) -test/test-bcf-sr.o: test/test-bcf-sr.c config.h $(htslib_hts_defs_h) $(htslib_synced_bcf_reader_h) $(htslib_hts_h) $(htslib_vcf_h) +test/test-bcf-sr.o: test/test-bcf-sr.c config.h $(htslib_hts_alloc_h) $(htslib_hts_defs_h) $(htslib_synced_bcf_reader_h) $(htslib_hts_h) $(htslib_vcf_h) test/test-bcf-translate.o: test/test-bcf-translate.c config.h $(htslib_vcf_h) test/test_introspection.o: test/test_introspection.c config.h $(htslib_hts_h) $(htslib_hfile_h) test/test-bcf_set_variant_type.o: test/test-bcf_set_variant_type.c config.h $(htslib_hts_h) vcf.c diff --git a/annot-tsv.c b/annot-tsv.c index 3c601c73a..7c657b777 100644 --- a/annot-tsv.c +++ b/annot-tsv.c @@ -38,6 +38,7 @@ #include #include #include "htslib/hts.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_defs.h" #include "htslib/khash_str2int.h" #include "htslib/kstring.h" @@ -151,7 +152,7 @@ static inline void nbp_add(nbp_t *nbp, hts_pos_t beg, hts_pos_t end) if ( nbp->n >= nbp->m ) { nbp->m += 2; - nbp->regs = realloc(nbp->regs, nbp->m*sizeof(*nbp->regs)); + nbp->regs = hts_realloc_p(nbp->regs, sizeof(*nbp->regs), nbp->m); if ( !nbp->regs ) error("Out of memory, failed to allocate %zu bytes\n",nbp->m*sizeof(*nbp->regs)); } nbp->regs[nbp->n - 2] = NBP_SET_BEG(beg); @@ -203,7 +204,7 @@ cols_t *cols_split(const char *line, cols_t *cols, char delim) if ( cols->n > cols->m ) { cols->m += 10; - cols->off = realloc(cols->off, sizeof(*cols->off)*cols->m); + cols->off = hts_realloc_p(cols->off, sizeof(*cols->off), cols->m); if ( !cols->off ) error("Out of memory, failed to allocate %zu bytes\n",sizeof(*cols->off)*cols->m); } cols->off[ cols->n - 1 ] = ss; @@ -253,7 +254,7 @@ void cols_append(cols_t *cols, char *str) if ( cols->n > cols->m ) { cols->m++; - cols->off = realloc(cols->off,sizeof(*cols->off)*cols->m); + cols->off = hts_realloc_p(cols->off, sizeof(*cols->off), cols->m); if ( !cols->off ) error("Out of memory, failed to allocate %zu bytes\n",sizeof(*cols->off)*cols->m); } cols->off[cols->n-1] = str; @@ -479,7 +480,7 @@ static int read_next_line(dat_t *dat) void sanity_check_columns(char *fname, hdr_t *hdr, cols_t *cols, int **col2idx, int force) { - *col2idx = (int*)malloc(sizeof(int)*cols->n); + *col2idx = hts_malloc_p(sizeof(int), cols->n); if ( !*col2idx ) error("Out of memory, failed to allocate %zu bytes\n",sizeof(int)*cols->n); int i, idx; for (i=0; in; i++) diff --git a/bcf_sr_sort.c b/bcf_sr_sort.c index 73be004c9..9f5e6f3a1 100644 --- a/bcf_sr_sort.c +++ b/bcf_sr_sort.c @@ -31,6 +31,7 @@ #include "bcf_sr_sort.h" #include "htslib/khash_str2int.h" #include "htslib/kbitset.h" +#include "htslib/hts_alloc.h" // Variant types and pair-wise compatibility of their combinations, see bcf_sr_init_scores() #define SR_REF 1 @@ -311,7 +312,9 @@ static char *grp_create_key(sr_sort_t *srt) if ( i>0 ) srt->charp[i][-1] = 0; } qsort(srt->charp, srt->noff, sizeof(*srt->charp), cmpstringp); - char *ret = (char*) malloc(srt->str.l + 1), *ptr = ret; + char *ret = hts_malloc_ps(sizeof(*ret), srt->str.l, 1), *ptr = ret; + if (!ret) + return NULL; for (i=0; inoff; i++) { int len = strlen(srt->charp[i]); @@ -461,7 +464,7 @@ static int bcf_sr_sort_set(bcf_srs_t *readers, sr_sort_t *srt, const char *chr, int mvcf = var->mvcf; var->nvcf++; hts_expand0(int*, var->nvcf, var->mvcf, var->vcf); - if ( mvcf != var->mvcf ) var->rec = (bcf1_t **) realloc(var->rec,sizeof(bcf1_t*)*var->mvcf); + if ( mvcf != var->mvcf ) var->rec = hts_realloc_p(var->rec, sizeof(bcf1_t*), var->mvcf); var->vcf[var->nvcf-1] = ireader; var->rec[var->nvcf-1] = line; @@ -600,7 +603,8 @@ int bcf_sr_sort_next(bcf_srs_t *readers, sr_sort_t *srt, const char *chr, hts_po srt->sr = readers; if ( srt->nsr < readers->nreaders ) { - srt->vcf_buf = (vcf_buf_t*) realloc(srt->vcf_buf,readers->nreaders*sizeof(vcf_buf_t)); + srt->vcf_buf = hts_realloc_p(srt->vcf_buf, sizeof(vcf_buf_t), + readers->nreaders); memset(srt->vcf_buf + srt->nsr, 0, sizeof(vcf_buf_t)*(readers->nreaders - srt->nsr)); if ( srt->msr < srt->nsr ) srt->msr = srt->nsr; } diff --git a/bgzf.c b/bgzf.c index 307c534d1..b28c29d7c 100644 --- a/bgzf.c +++ b/bgzf.c @@ -45,6 +45,7 @@ #include "htslib/bgzf.h" #include "htslib/hfile.h" #include "htslib/thread_pool.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_endian.h" #include "cram/pooled_alloc.h" #include "hts_internal.h" @@ -204,7 +205,7 @@ int bgzf_idx_push(BGZF *fp, hts_idx_t *hidx, int tid, hts_pos_t beg, hts_pos_t e if (ic->nentries >= ic->mentries) { int new_sz = ic->mentries ? ic->mentries*2 : 1024; - if (!(e = realloc(ic->e, new_sz * sizeof(*ic->e)))) { + if (!(e = hts_realloc_p(ic->e, sizeof(*ic->e), new_sz))) { pthread_mutex_unlock(&mt->idx_m); return -1; } @@ -391,7 +392,7 @@ static BGZF *bgzf_read_init(hFILE *hfpr, const char *filename) if (fp == NULL) return NULL; fp->is_write = 0; - fp->uncompressed_block = malloc(2 * BGZF_MAX_BLOCK_SIZE); + fp->uncompressed_block = hts_malloc_p(2, BGZF_MAX_BLOCK_SIZE); if (fp->uncompressed_block == NULL) { free(fp); return NULL; } fp->compressed_block = (char *)fp->uncompressed_block + BGZF_MAX_BLOCK_SIZE; fp->is_compressed = (n==18 && magic[0]==0x1f && magic[1]==0x8b); @@ -455,7 +456,7 @@ static BGZF *bgzf_write_init(const char *mode) } fp->is_compressed = 1; - fp->uncompressed_block = malloc(2 * BGZF_MAX_BLOCK_SIZE); + fp->uncompressed_block = hts_malloc_p(2, BGZF_MAX_BLOCK_SIZE); if (fp->uncompressed_block == NULL) goto mem_fail; fp->compressed_block = (char *)fp->uncompressed_block + BGZF_MAX_BLOCK_SIZE; @@ -1019,7 +1020,7 @@ int bgzf_read_block(BGZF *fp) if (!j || j->errcode == BGZF_ERR_MT) { if (!fp->mt->free_block) { - fp->uncompressed_block = malloc(2 * BGZF_MAX_BLOCK_SIZE); + fp->uncompressed_block = hts_malloc_p(2, BGZF_MAX_BLOCK_SIZE); if (fp->uncompressed_block == NULL) return -1; fp->compressed_block = (char *)fp->uncompressed_block + BGZF_MAX_BLOCK_SIZE; } // else it's already allocated with malloc, maybe even in-use. @@ -1417,7 +1418,8 @@ static void *bgzf_mt_writer(void *vp) { { fp->idx->moffs = fp->idx->noffs; kroundup32(fp->idx->moffs); - fp->idx->offs = (bgzidx1_t*) realloc(fp->idx->offs, fp->idx->moffs*sizeof(bgzidx1_t)); + fp->idx->offs = hts_realloc_p(fp->idx->offs, sizeof(bgzidx1_t), + fp->idx->moffs); if ( !fp->idx->offs ) goto err; } fp->idx->offs[ fp->idx->noffs-1 ].uaddr = fp->idx->offs[ fp->idx->noffs-2 ].uaddr + j->uncomp_len; @@ -2358,7 +2360,8 @@ int bgzf_index_add_block(BGZF *fp) { fp->idx->moffs = fp->idx->noffs; kroundup32(fp->idx->moffs); - fp->idx->offs = (bgzidx1_t*) realloc(fp->idx->offs, fp->idx->moffs*sizeof(bgzidx1_t)); + fp->idx->offs = hts_realloc_p(fp->idx->offs, sizeof(bgzidx1_t), + fp->idx->moffs); if ( !fp->idx->offs ) return -1; } fp->idx->offs[ fp->idx->noffs-1 ].uaddr = fp->idx->ublock_addr; diff --git a/bgzip.c b/bgzip.c index 459ea6c97..eda601e97 100644 --- a/bgzip.c +++ b/bgzip.c @@ -38,6 +38,7 @@ #include #include "htslib/bgzf.h" #include "htslib/hts.h" +#include "htslib/hts_alloc.h" #include "htslib/hfile.h" #ifdef _WIN32 @@ -352,7 +353,8 @@ int main(int argc, char **argv) fp = bgzf_open("-", out_mode); else { - char *name = malloc(strlen(argv[optind]) + 5); + char *name = hts_malloc_ps(sizeof(*name), + strlen(argv[optind]), 5); strcpy(name, argv[optind]); strcat(name, ".gz"); fp = bgzf_open(name, is_forced? out_mode : out_mode_exclusive); diff --git a/cram/cram_codecs.c b/cram/cram_codecs.c index f4ef18556..63690537d 100644 --- a/cram/cram_codecs.c +++ b/cram/cram_codecs.c @@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../fuzz_settings.h" #endif +#include "../htslib/hts_alloc.h" #include "../htslib/hts_endian.h" #if defined(HAVE_EXTERNAL_LIBHTSCODECS) @@ -268,12 +269,14 @@ static int store_bits_MSB(cram_block *block, uint64_t val, int nbits) { if (block->byte+8 >= block->alloc) { if (block->byte) { block->alloc *= 2; - block->data = realloc(block->data, block->alloc + 8); + block->data = hts_realloc_ps(block->data, sizeof(*block->data), + block->alloc, 8); if (!block->data) return -1; } else { block->alloc = 1024; - block->data = realloc(block->data, block->alloc + 8); + block->data = hts_realloc_ps(block->data, sizeof(*block->data), + block->alloc, 8); if (!block->data) return -1; block->data[0] = 0; // initialise first byte of buffer @@ -1975,7 +1978,7 @@ int cram_xdelta_encode_int(cram_slice *slice, cram_codec *c, int cram_xdelta_encode_char(cram_slice *slice, cram_codec *c, char *in, int in_size) { - char *dat = malloc(in_size*5); + char *dat = hts_malloc_p(5, in_size); if (!dat) return -1; char *cp = dat, *cp_end = dat + in_size*5; @@ -2269,7 +2272,7 @@ int cram_xrle_encode_flush(cram_codec *c) { c->u.e_xrle.to_flush_size = BLOCK_SIZE(c->out); } - out_len = malloc(c->u.e_xrle.to_flush_size+8); + out_len = hts_malloc_ps(sizeof(*out_len), c->u.e_xrle.to_flush_size, 8); if (!out_len) return -1; @@ -3122,7 +3125,7 @@ int cram_huffman_encode_store(cram_codec *c, cram_block *b, char *prefix, * * Therefore 6*ncodes + 5 + 5 + 1 + 5 is max memory */ - char *tmp = malloc(6*c->u.e_huffman.nvals+16); + char *tmp = hts_malloc_pse(6, c->u.e_huffman.nvals, 0, 16); char *tp = tmp, *tpend = tmp+6*c->u.e_huffman.nvals+16; if (!tmp) @@ -3196,10 +3199,10 @@ cram_codec *cram_huffman_encode_init(cram_stats *st, continue; if (nvals >= vals_alloc) { vals_alloc = vals_alloc ? vals_alloc*2 : 1024; - new_vals = realloc(vals, vals_alloc * sizeof(int)); + new_vals = hts_realloc_p(vals, sizeof(*vals), vals_alloc); if (!new_vals) goto nomem; vals = new_vals; - new_freqs = realloc(freqs, vals_alloc * sizeof(int)); + new_freqs = hts_realloc_p(freqs, sizeof(*freqs), vals_alloc); if (!new_freqs) goto nomem; freqs = new_freqs; } @@ -3218,10 +3221,10 @@ cram_codec *cram_huffman_encode_init(cram_stats *st, continue; if (nvals >= vals_alloc) { vals_alloc = vals_alloc ? vals_alloc*2 : 1024; - new_vals = realloc(vals, vals_alloc * sizeof(int)); + new_vals = hts_realloc_p(vals, sizeof(*vals), vals_alloc); if (!new_vals) goto nomem; vals = new_vals; - new_freqs = realloc(freqs, vals_alloc * sizeof(int)); + new_freqs = hts_realloc_p(freqs, sizeof(*freqs), vals_alloc); if (!new_freqs) goto nomem; freqs = new_freqs; } @@ -3236,10 +3239,10 @@ cram_codec *cram_huffman_encode_init(cram_stats *st, assert(nvals > 0); - new_freqs = realloc(freqs, 2*nvals*sizeof(*freqs)); + new_freqs = hts_realloc_p(freqs, 2 * sizeof(*freqs), nvals); if (!new_freqs) goto nomem; freqs = new_freqs; - lens = calloc(2*nvals, sizeof(*lens)); + lens = calloc(nvals, 2 * sizeof(*lens)); if (!lens) goto nomem; /* Inefficient, use pointers to form chain so we can insert and maintain @@ -3280,7 +3283,7 @@ cram_codec *cram_huffman_encode_init(cram_stats *st, /* Sort, need in a struct */ - if (!(codes = malloc(nvals * sizeof(*codes)))) + if (!(codes = hts_malloc_p(sizeof(*codes), nvals))) goto nomem; for (i = 0; i < nvals; i++) { codes[i].symbol = vals[i]; diff --git a/cram/cram_decode.c b/cram/cram_decode.c index cdc67ce55..cad58dfdf 100644 --- a/cram/cram_decode.c +++ b/cram/cram_decode.c @@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cram.h" #include "os.h" #include "../htslib/hts.h" +#include "../htslib/hts_alloc.h" #include "../htslib/hfile.h" //Whether CIGAR has just M or uses = and X to indicate match and mismatch @@ -178,7 +179,7 @@ cram_block_compression_hdr *cram_decode_compression_header(cram_fd *fd, free(hdr); return NULL; } - if (!(hdr->landmark = malloc(hdr->num_landmarks * sizeof(int32_t)))) { + if (!(hdr->landmark = hts_malloc_p(sizeof(int32_t), hdr->num_landmarks))) { free(hdr); return NULL; } @@ -629,7 +630,7 @@ int cram_dependent_data_series(cram_fd *fd, return 0; } - block_used = calloc(s->hdr->num_blocks+1, sizeof(int)); + block_used = hts_calloc_ps(sizeof(*block_used), s->hdr->num_blocks, 1); if (!block_used) return -1; @@ -1007,7 +1008,7 @@ cram_block_slice_hdr *cram_decode_slice_header(cram_fd *fd, cram_block *b) { free(hdr); return NULL; } - hdr->block_content_ids = malloc(hdr->num_content_ids * sizeof(int32_t)); + hdr->block_content_ids = hts_malloc_p(sizeof(int32_t), hdr->num_content_ids); if (!hdr->block_content_ids) { free(hdr); return NULL; @@ -1162,7 +1163,7 @@ static int cram_decode_seq(cram_fd *fd, cram_container *c, cram_slice *s, if (ncigar+2 >= cigar_alloc) { cigar_alloc = cigar_alloc ? cigar_alloc*2 : 1024; - if (!(cigar = realloc(s->cigar, cigar_alloc * sizeof(*cigar)))) + if (!(cigar = hts_realloc_p(s->cigar, sizeof(*cigar), cigar_alloc))) return -1; s->cigar = cigar; } @@ -1775,7 +1776,7 @@ static int cram_decode_seq(cram_fd *fd, cram_container *c, cram_slice *s, if (ncigar+1 >= cigar_alloc) { cigar_alloc = cigar_alloc ? cigar_alloc*2 : 1024; - if (!(cigar = realloc(s->cigar, cigar_alloc * sizeof(*cigar)))) + if (!(cigar = hts_realloc_p(s->cigar, sizeof(*cigar), cigar_alloc))) return -1; s->cigar = cigar; } @@ -1805,7 +1806,7 @@ static int cram_decode_seq(cram_fd *fd, cram_container *c, cram_slice *s, if (cig_len) { if (ncigar >= cigar_alloc) { cigar_alloc = cigar_alloc ? cigar_alloc*2 : 1024; - if (!(cigar = realloc(s->cigar, cigar_alloc * sizeof(*cigar)))) + if (!(cigar = hts_realloc_p(s->cigar, sizeof(*cigar), cigar_alloc))) return -1; s->cigar = cigar; } @@ -2400,7 +2401,7 @@ int cram_decode_slice(cram_fd *fd, cram_container *c, cram_slice *s, if (s->crecs) free(s->crecs); - if (!(s->crecs = malloc(s->hdr->num_records * sizeof(*s->crecs)))) + if (!(s->crecs = hts_malloc_p(sizeof(*s->crecs), s->hdr->num_records))) return -1; ref_id = s->hdr->ref_seq_id; diff --git a/cram/cram_encode.c b/cram/cram_encode.c index 00d2e48e0..12768cd28 100644 --- a/cram/cram_encode.c +++ b/cram/cram_encode.c @@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "os.h" #include "../sam_internal.h" // for nibble2base #include "../htslib/hts.h" +#include "../htslib/hts_alloc.h" #include "../htslib/hts_endian.h" #include "../textutils_internal.h" @@ -517,7 +518,7 @@ cram_block *cram_encode_slice_header(cram_fd *fd, cram_slice *s) { if (!b) return NULL; - cp = buf = malloc(22+16+5*(8+s->hdr->num_blocks)); + cp = buf = hts_malloc_pse(8, s->hdr->num_blocks, 5, 22+16); if (NULL == buf) { cram_free_block(b); return NULL; @@ -1119,8 +1120,10 @@ static int cram_encode_slice(cram_fd *fd, cram_container *c, c->num_records += s->hdr->num_records; int ntags = c->tags_used ? c->tags_used->n_occupied : 0; - s->block = calloc(DS_END + ntags*2, sizeof(s->block[0])); - s->hdr->block_content_ids = malloc(DS_END * sizeof(int32_t)); + s->block = hts_calloc_ps(sizeof(s->block[0]), DS_END, + hts_prod_sat2(ntags, 2)); + s->hdr->block_content_ids = hts_malloc_p(sizeof(*s->hdr->block_content_ids), + DS_END); if (!s->block || !s->hdr->block_content_ids) return -1; @@ -1213,8 +1216,9 @@ static int cram_encode_slice(cram_fd *fd, cram_container *c, { int i, j; - s->hdr->block_content_ids = realloc(s->hdr->block_content_ids, - s->hdr->num_blocks * sizeof(int32_t)); + s->hdr->block_content_ids = hts_realloc_p(s->hdr->block_content_ids, + sizeof(*s->hdr->block_content_ids), + s->hdr->num_blocks); if (!s->hdr->block_content_ids) return -1; @@ -1529,8 +1533,8 @@ static inline int extend_ref(char **ref, uint32_t (**hist)[5], hts_pos_t pos, return -1; *ref = tmp; - uint32_t (*tmp5)[5] = realloc(**hist, - (new_end - ref_start)*sizeof(**hist)); + uint32_t (*tmp5)[5] = hts_realloc_p(**hist, sizeof(**hist), + new_end - ref_start); if (!tmp5) return -1; *hist = tmp5; @@ -2103,7 +2107,7 @@ int cram_encode_container(cram_fd *fd, cram_container *c) { // slice can start aggregating them from the start again. if (c->tags_used->n_occupied) { int ntags = c->tags_used->n_occupied; - s->aux_block = calloc(ntags*2, sizeof(*s->aux_block)); + s->aux_block = calloc(hts_prod_sat2(ntags, 2), sizeof(*s->aux_block)); if (!s->aux_block) return -1; @@ -2474,7 +2478,7 @@ int cram_encode_container(cram_fd *fd, cram_container *c) { /* Compute landmarks */ /* Fill out slice landmarks */ c->num_landmarks = c->curr_slice; - c->landmark = malloc(c->num_landmarks * sizeof(*c->landmark)); + c->landmark = hts_malloc_p(sizeof(*c->landmark), c->num_landmarks); if (!c->landmark) return -1; @@ -2575,7 +2579,7 @@ static int cram_add_feature(cram_container *c, cram_slice *s, cram_record *r, cram_feature *f) { if (s->nfeatures >= s->afeatures) { s->afeatures = s->afeatures ? s->afeatures*2 : 1024; - s->features = realloc(s->features, s->afeatures*sizeof(*s->features)); + s->features = hts_realloc_p(s->features, sizeof(*s->features), s->afeatures); if (!s->features) return -1; } @@ -2806,7 +2810,7 @@ static sam_hrec_rg_t *cram_encode_aux(cram_fd *fd, bam_seq_t *b, // 2: Don't auto-decode NM (may be invalid) if (cf_tag && CRAM_MAJOR_VERS(fd->version) < 4) { // Temporary copy of aux so we can ammend it. - aux = malloc(aux_size+4); + aux = hts_malloc_ps(sizeof(*aux), aux_size, 4); if (!aux) return NULL; @@ -3484,7 +3488,7 @@ static int process_one_read(cram_fd *fd, cram_container *c, cr->ncigar = bam_cigar_len(b); while (cr->cigar + cr->ncigar >= s->cigar_alloc) { s->cigar_alloc = s->cigar_alloc ? s->cigar_alloc*2 : 1024; - s->cigar = realloc(s->cigar, s->cigar_alloc * sizeof(*s->cigar)); + s->cigar = hts_realloc_p(s->cigar, sizeof(*s->cigar), s->cigar_alloc); if (!s->cigar) return -1; } diff --git a/cram/cram_external.c b/cram/cram_external.c index 4943750dd..e1117fc2c 100644 --- a/cram/cram_external.c +++ b/cram/cram_external.c @@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include "../htslib/hfile.h" +#include "../htslib/hts_alloc.h" #include "cram.h" /* @@ -378,8 +379,8 @@ cram_cid2ds_t *cram_update_cid2ds_map(cram_block_compression_hdr *hdr, if (c2d->ds_idx >= c2d->ds_size) { c2d->ds_size += 100; c2d->ds_size *= 2; - ds_list *ds_new = realloc(c2d->ds, - c2d->ds_size * sizeof(*ds_new)); + ds_list *ds_new = hts_realloc_p(c2d->ds, sizeof(*ds_new), + c2d->ds_size); if (!ds_new) goto err; c2d->ds = ds_new; @@ -450,7 +451,7 @@ int *cram_cid2ds_query(cram_cid2ds_t *c2d, int content_id, int *n) { return NULL; if (!c2d->ds_a) { - c2d->ds_a = malloc(c2d->ds_idx * sizeof(int)); + c2d->ds_a = hts_malloc_p(sizeof(*c2d->ds_a), c2d->ds_idx); if (!c2d->ds_a) return NULL; } diff --git a/cram/cram_index.c b/cram/cram_index.c index b08ca5bfd..5660dfe92 100644 --- a/cram/cram_index.c +++ b/cram/cram_index.c @@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../htslib/bgzf.h" #include "../htslib/hfile.h" +#include "../htslib/hts_alloc.h" #include "../hts_internal.h" #include "cram.h" #include "os.h" @@ -287,8 +288,8 @@ int cram_index_load(cram_fd *fd, const char *fn, const char *fn_idx) { cram_index *new_idx; int new_sz = e.refid+2; size_t index_end = fd->index_sz * sizeof(*fd->index); - new_idx = realloc(fd->index, - new_sz * sizeof(*fd->index)); + new_idx = hts_realloc_p(fd->index, sizeof(*fd->index), + new_sz); if (!new_idx) goto fail; @@ -315,7 +316,7 @@ int cram_index_load(cram_fd *fd, const char *fn, const char *fn_idx) { if (idx->nslice+1 >= idx->nalloc) { cram_index *new_e; idx->nalloc = idx->nalloc ? idx->nalloc*2 : 16; - new_e = realloc(idx->e, idx->nalloc * sizeof(*idx->e)); + new_e = hts_realloc_p(idx->e, sizeof(*idx->e), idx->nalloc); if (!new_e) goto fail; @@ -329,7 +330,7 @@ int cram_index_load(cram_fd *fd, const char *fn, const char *fn_idx) { if (++idx_stack_ptr >= idx_stack_alloc) { cram_index **new_stack; idx_stack_alloc *= 2; - new_stack = realloc(idx_stack, idx_stack_alloc*sizeof(*idx_stack)); + new_stack = hts_realloc_p(idx_stack, sizeof(*idx_stack), idx_stack_alloc); if (!new_stack) goto fail; idx_stack = new_stack; diff --git a/cram/cram_io.c b/cram/cram_io.c index 28a035a63..d275e8a66 100644 --- a/cram/cram_io.c +++ b/cram/cram_io.c @@ -76,6 +76,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cram.h" #include "os.h" #include "../htslib/hts.h" +#include "../htslib/hts_alloc.h" #include "../hts_internal.h" #include "open_trace_file.h" @@ -2661,7 +2662,7 @@ static refs_t *refs_load_fai(refs_t *r_orig, const char *fn, int is_err) { int x; id_alloc = id_alloc ?id_alloc*2 : 16; - new_refs = realloc(r->ref_id, id_alloc * sizeof(*r->ref_id)); + new_refs = hts_realloc_p(r->ref_id, sizeof(*r->ref_id), id_alloc); if (!new_refs) goto err; r->ref_id = new_refs; @@ -2788,7 +2789,8 @@ static int refs_from_header(cram_fd *fd) { //fprintf(stderr, "refs_from_header for %p mode %c\n", fd, fd->mode); /* Existing refs are fine, as long as they're compatible with the hdr. */ - ref_entry **new_ref_id = realloc(r->ref_id, (r->nref + h->hrecs->nref) * sizeof(*r->ref_id)); + ref_entry **new_ref_id = hts_realloc_ps(r->ref_id, sizeof(*r->ref_id), + r->nref, h->hrecs->nref); if (!new_ref_id) return -1; r->ref_id = new_ref_id; @@ -3884,7 +3886,7 @@ cram_container *cram_read_container(cram_fd *fd) { return NULL; } #endif - if (c->num_landmarks && !(c->landmark = malloc(c->num_landmarks * sizeof(int32_t)))) { + if (c->num_landmarks && !(c->landmark = hts_malloc_p(sizeof(*c->landmark), c->num_landmarks))) { fd->err = errno; cram_free_container(c); return NULL; @@ -4514,9 +4516,9 @@ cram_slice *cram_new_slice(enum cram_content_type type, int nrecs) { s->block = NULL; s->block_by_id = NULL; s->last_apos = 0; - if (!(s->crecs = malloc(nrecs * sizeof(cram_record)))) goto err; + if (!(s->crecs = hts_malloc_p(sizeof(*s->crecs), nrecs))) goto err; s->cigar_alloc = 1024; - if (!(s->cigar = malloc(s->cigar_alloc * sizeof(*s->cigar)))) goto err; + if (!(s->cigar = hts_malloc_p(sizeof(*s->cigar), s->cigar_alloc))) goto err; s->ncigar = 0; if (!(s->seqs_blk = cram_new_block(EXTERNAL, 0))) goto err; @@ -4620,7 +4622,7 @@ cram_slice *cram_read_slice(cram_fd *fd) { /* Initialise encoding/decoding tables */ s->cigar_alloc = 1024; - if (!(s->cigar = malloc(s->cigar_alloc * sizeof(*s->cigar)))) goto err; + if (!(s->cigar = hts_malloc_p(sizeof(*s->cigar), s->cigar_alloc))) goto err; s->ncigar = 0; if (!(s->seqs_blk = cram_new_block(EXTERNAL, 0))) goto err; diff --git a/cram/cram_stats.c b/cram/cram_stats.c index d06b8ffb9..fe5d70201 100644 --- a/cram/cram_stats.c +++ b/cram/cram_stats.c @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cram.h" #include "os.h" +#include "../htslib/hts_alloc.h" cram_stats *cram_stats_create(void) { return calloc(1, sizeof(cram_stats)); @@ -146,8 +147,8 @@ enum cram_encoding cram_stats_encoding(cram_fd *fd, cram_stats *st) { continue; if (nvals >= vals_alloc) { vals_alloc = vals_alloc ? vals_alloc*2 : 1024; - int *vals_tmp = realloc(vals, vals_alloc * sizeof(int)); - int *freqs_tmp = realloc(freqs, vals_alloc * sizeof(int)); + int *vals_tmp = hts_realloc_p(vals, sizeof(*vals), vals_alloc); + int *freqs_tmp = hts_realloc_p(freqs, sizeof(*freqs), vals_alloc); if (!vals_tmp || !freqs_tmp) { free(vals_tmp ? vals_tmp : vals); free(freqs_tmp ? freqs_tmp : freqs); @@ -173,8 +174,8 @@ enum cram_encoding cram_stats_encoding(cram_fd *fd, cram_stats *st) { if (nvals >= vals_alloc) { vals_alloc = vals_alloc ? vals_alloc*2 : 1024; - int *vals_tmp = realloc(vals, vals_alloc * sizeof(int)); - int *freqs_tmp = realloc(freqs, vals_alloc * sizeof(int)); + int *vals_tmp = hts_realloc_p(vals, sizeof(*vals), vals_alloc); + int *freqs_tmp = hts_realloc_p(freqs, sizeof(*freqs), vals_alloc); if (!vals_tmp || !freqs_tmp) { free(vals_tmp ? vals_tmp : vals); free(freqs_tmp ? freqs_tmp : freqs); diff --git a/cram/pooled_alloc.c b/cram/pooled_alloc.c index 4601a7f35..21cf5cda2 100644 --- a/cram/pooled_alloc.c +++ b/cram/pooled_alloc.c @@ -37,6 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pooled_alloc.h" #include "misc.h" +#include "../htslib/hts_alloc.h" //#define DISABLE_POOLED_ALLOC //#define TEST_MAIN @@ -97,12 +98,12 @@ static pool_t *new_pool(pool_alloc_t *p) { size_t n = p->psize / p->dsize; pool_t *pool; - pool = realloc(p->pools, (p->npools + 1) * sizeof(*p->pools)); + pool = hts_realloc_ps(p->pools, sizeof(*p->pools), p->npools, 1); if (NULL == pool) return NULL; p->pools = pool; pool = &p->pools[p->npools]; - pool->pool = malloc(n * p->dsize); + pool->pool = hts_malloc_p(p->dsize, n); if (NULL == pool->pool) return NULL; pool->used = 0; diff --git a/cram/string_alloc.c b/cram/string_alloc.c index c339b1020..087d67907 100644 --- a/cram/string_alloc.c +++ b/cram/string_alloc.c @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "string_alloc.h" +#include "../htslib/hts_alloc.h" #define MIN_STR_SIZE 1024 @@ -77,7 +78,7 @@ static string_t *new_string_pool(string_alloc_t *a_str) { if (a_str->nstrings == a_str->max_strings) { size_t new_max = (a_str->max_strings | (a_str->max_strings >> 2)) + 1; - str = realloc(a_str->strings, new_max * sizeof(*a_str->strings)); + str = hts_realloc_p(a_str->strings, sizeof(*a_str->strings), new_max); if (NULL == str) return NULL; diff --git a/faidx.c b/faidx.c index c7fc022a8..039da994a 100644 --- a/faidx.c +++ b/faidx.c @@ -39,6 +39,7 @@ DEALINGS IN THE SOFTWARE. */ #include "htslib/bgzf.h" #include "htslib/faidx.h" #include "htslib/hfile.h" +#include "htslib/hts_alloc.h" #include "htslib/khash.h" #include "htslib/kstring.h" #include "hts_internal.h" @@ -111,7 +112,7 @@ static inline int fai_insert_index(faidx_t *idx, const char *name, uint64_t len, if (idx->n == idx->m) { char **tmp; idx->m = idx->m? idx->m<<1 : 16; - if (!(tmp = (char**)realloc(idx->name, sizeof(char*) * idx->m))) { + if (!(tmp = hts_realloc_p(idx->name, sizeof(char*), idx->m))) { hts_log_error("Out of memory"); return -1; } @@ -743,7 +744,7 @@ static char *fai_retrieve(const faidx_t *fai, const faidx1_t *val, } // Over-allocate so there is extra space for one end-of-line sequence - buffer = (char*)malloc((size_t) end - beg + val->line_len - val->line_blen + 1); + buffer = malloc(hts_add_sat3(end - beg, val->line_len - val->line_blen, 1)); if (!buffer) { *len = -1; return NULL; diff --git a/header.c b/header.c index 738f81814..627f64b98 100644 --- a/header.c +++ b/header.c @@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "header.h" #include "htslib/bgzf.h" #include "htslib/hfile.h" +#include "htslib/hts_alloc.h" #include "htslib/kseq.h" // Hash table for removing multiple lines from the header @@ -248,7 +249,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs, if (nref == hrecs->ref_sz) { size_t new_sz = hrecs->ref_sz >= 4 ? hrecs->ref_sz + (hrecs->ref_sz / 4) : 32; - sam_hrec_sq_t *new_ref = realloc(hrecs->ref, sizeof(*hrecs->ref) * new_sz); + sam_hrec_sq_t *new_ref = hts_realloc_p(hrecs->ref, sizeof(*hrecs->ref), new_sz); if (!new_ref) return -1; hrecs->ref = new_ref; @@ -300,7 +301,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs, if (nrg == hrecs->rg_sz) { size_t new_sz = hrecs->rg_sz >= 4 ? hrecs->rg_sz + hrecs->rg_sz / 4 : 4; - sam_hrec_rg_t *new_rg = realloc(hrecs->rg, sizeof(*hrecs->rg) * new_sz); + sam_hrec_rg_t *new_rg = hts_realloc_p(hrecs->rg, sizeof(*hrecs->rg), new_sz); if (!new_rg) return -1; hrecs->rg = new_rg; @@ -327,7 +328,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs, if (npg == hrecs->pg_sz) { size_t new_sz = hrecs->pg_sz >= 4 ? hrecs->pg_sz + hrecs->pg_sz / 4 : 4; - new_pg = realloc(hrecs->pg, sizeof(*hrecs->pg) * new_sz); + new_pg = hts_realloc_p(hrecs->pg, sizeof(*hrecs->pg), new_sz); if (!new_pg) return -1; hrecs->pg = new_pg; @@ -396,7 +397,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs, int *new_pg_end; int new_alloc = hrecs->npg_end_alloc ? hrecs->npg_end_alloc*2 : 4; - new_pg_end = realloc(hrecs->pg_end, new_alloc * sizeof(int)); + new_pg_end = hts_realloc_p(hrecs->pg_end, sizeof(int), new_alloc); if (!new_pg_end) return -1; hrecs->npg_end_alloc = new_alloc; @@ -611,7 +612,7 @@ static int sam_hrecs_vadd(sam_hrecs_t *hrecs, const char *type, va_list ap, ...) if (strncmp(type, "CO", 2)) { h_tag->len = 3 + strlen(val); - str = string_alloc(hrecs->str_pool, h_tag->len+1); + str = string_alloc(hrecs->str_pool, hts_add_sat2(h_tag->len, 1)); if (!str || snprintf(str, h_tag->len+1, "%2.2s:%s", key, val) < 0) return -1; h_tag->str = str; @@ -646,7 +647,7 @@ static int sam_hrecs_vadd(sam_hrecs_t *hrecs, const char *type, va_list ap, ...) if (strncmp(type, "CO", 2)) { h_tag->len = 3 + strlen(val); - str = string_alloc(hrecs->str_pool, h_tag->len+1); + str = string_alloc(hrecs->str_pool, hts_add_sat2(h_tag->len, 1)); if (!str || snprintf(str, h_tag->len+1, "%2.2s:%s", key, val) < 0) return -1; h_tag->str = str; @@ -1045,8 +1046,8 @@ static int sam_hrecs_parse_lines(sam_hrecs_t *hrecs, const char *hdr, size_t len return -1; if (hrecs->ref_sz < sq_count) { - sam_hrec_sq_t *new_ref = realloc(hrecs->ref, - sizeof(*hrecs->ref) * sq_count); + sam_hrec_sq_t *new_ref = hts_realloc_p(hrecs->ref, + sizeof(*hrecs->ref), sq_count); if (!new_ref) return -1; hrecs->ref = new_ref; @@ -1080,13 +1081,13 @@ int sam_hdr_update_target_arrays(sam_hdr_t *bh, const sam_hrecs_t *hrecs, // Grow arrays if necessary if (bh->n_targets < hrecs->nref) { - char **new_names = realloc(bh->target_name, - hrecs->nref * sizeof(*new_names)); + char **new_names = hts_realloc_p(bh->target_name, sizeof(*new_names), + hrecs->nref); if (!new_names) return -1; bh->target_name = new_names; - uint32_t *new_lens = realloc(bh->target_len, - hrecs->nref * sizeof(*new_lens)); + uint32_t *new_lens = hts_realloc_p(bh->target_len, sizeof(*new_lens), + hrecs->nref); if (!new_lens) return -1; bh->target_len = new_lens; @@ -1194,8 +1195,8 @@ static int sam_hrecs_refs_from_targets_array(sam_hrecs_t *hrecs, } if (hrecs->ref_sz < bh->n_targets) { - sam_hrec_sq_t *new_ref = realloc(hrecs->ref, - bh->n_targets * sizeof(*new_ref)); + sam_hrec_sq_t *new_ref = hts_realloc_p(hrecs->ref, sizeof(*new_ref), + bh->n_targets); if (!new_ref) return -1; @@ -1486,8 +1487,8 @@ int sam_hdr_build_from_sam_file(sam_hdr_t *hdr, htsFile* fp) { goto error; if (hrecs->ref_sz < sq_count) { - sam_hrec_sq_t *new_ref = realloc(hrecs->ref, - sizeof(*hrecs->ref) * sq_count); + sam_hrec_sq_t *new_ref = hts_realloc_p(hrecs->ref, + sizeof(*hrecs->ref), sq_count); if (!new_ref) goto error; hrecs->ref = new_ref; @@ -2482,7 +2483,7 @@ static int sam_hdr_link_pg(sam_hdr_t *bh) { return 0; hrecs->npg_end_alloc = hrecs->npg; - new_pg_end = realloc(hrecs->pg_end, hrecs->npg * sizeof(*new_pg_end)); + new_pg_end = hts_realloc_p(hrecs->pg_end, sizeof(*new_pg_end), hrecs->npg); if (!new_pg_end) return -1; hrecs->pg_end = new_pg_end; @@ -2578,7 +2579,8 @@ const char *sam_hdr_pg_id(sam_hdr_t *bh, const char *name) { name_len = strlen(name); if (name_len > 1000) name_len = 1000; if (hrecs->ID_buf_sz < name_len + name_extra) { - char *new_ID_buf = realloc(hrecs->ID_buf, name_len + name_extra); + char *new_ID_buf = realloc(hrecs->ID_buf, + hts_add_sat2(name_len, name_extra)); if (new_ID_buf == NULL) return NULL; hrecs->ID_buf = new_ID_buf; @@ -2662,7 +2664,7 @@ int sam_hdr_add_pg(sam_hdr_t *bh, const char *name, ...) { if (!specified_pp && hrecs->npg_end) { /* Copy ends array to avoid us looping while modifying it */ - int *end = malloc(hrecs->npg_end * sizeof(int)); + int *end = hts_malloc_p(sizeof(int), hrecs->npg_end); int i, nends = hrecs->npg_end; if (!end) @@ -2962,7 +2964,7 @@ int sam_hrecs_vupdate(sam_hrecs_t *hrecs, sam_hrec_type_t *type, va_list ap) { } tag->len = 3 + strlen(v); - str = string_alloc(hrecs->str_pool, tag->len+1); + str = string_alloc(hrecs->str_pool, hts_add_sat2(tag->len, 1)); if (!str) return -1; diff --git a/hfile_libcurl.c b/hfile_libcurl.c index d3872c42a..a82ee1863 100644 --- a/hfile_libcurl.c +++ b/hfile_libcurl.c @@ -42,6 +42,7 @@ DEALINGS IN THE SOFTWARE. */ #include "version.h" #endif #include "htslib/hts.h" // for hts_version() and hts_verbose +#include "htslib/hts_alloc.h" #include "htslib/kstring.h" #include "htslib/khash.h" @@ -353,8 +354,8 @@ static void libcurl_exit(void) static int append_header(hdrlist *hdrs, const char *data, int dup) { if (hdrs->num == hdrs->size) { unsigned int new_sz = hdrs->size ? hdrs->size * 2 : 4, i; - struct curl_slist *new_list = realloc(hdrs->list, - new_sz * sizeof(*new_list)); + struct curl_slist *new_list = hts_realloc_p(hdrs->list, + sizeof(*new_list), new_sz); if (!new_list) return -1; hdrs->size = new_sz; hdrs->list = new_list; diff --git a/hfile_s3.c b/hfile_s3.c index 30de86e27..71701d831 100644 --- a/hfile_s3.c +++ b/hfile_s3.c @@ -40,6 +40,7 @@ DEALINGS IN THE SOFTWARE. */ #include "version.h" #endif #include "htslib/hts.h" // for hts_version() and hts_verbose +#include "htslib/hts_alloc.h" #include "htslib/kstring.h" #include "hts_time_funcs.h" @@ -398,8 +399,8 @@ static char *escape_query(const char *qs) { char *escaped; length = strlen(qs); - alloced = length * 3 + 1; - if ((escaped = malloc(alloced)) == NULL) { + alloced = hts_add_sat2(hts_prod_sat2(length, 3), 1); + if ((escaped = hts_malloc(alloced)) == NULL) { return NULL; } @@ -426,9 +427,9 @@ static char *escape_path(const char *path) { char *escaped; length = strlen(path); - alloced = length * 3 + 1; + alloced = hts_add_sat2(hts_prod_sat2(length, 3), 1); - if ((escaped = malloc(alloced)) == NULL) { + if ((escaped = hts_malloc(alloced)) == NULL) { return NULL; } @@ -1018,7 +1019,7 @@ static int order_query_string(kstring_t *qs) { return -1; } - if ((queries = malloc(num_queries * sizeof(char*))) == NULL) + if ((queries = hts_malloc_p(sizeof(char*), num_queries)) == NULL) goto err; for (i = 0; i < num_queries; i++) { diff --git a/hts.c b/hts.c index 7af22fce7..bb16cdff4 100644 --- a/hts.c +++ b/hts.c @@ -59,6 +59,7 @@ DEALINGS IN THE SOFTWARE. */ #include "hts_internal.h" #include "hfile_internal.h" #include "sam_internal.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_expr.h" #include "htslib/hts_os.h" // drand48 @@ -2111,7 +2112,7 @@ char **hts_readlist(const char *string, int is_file, int *_n) } } // Try to shrink s to the minimum size needed - s_new = (char**)realloc(s, n * sizeof(char*)); + s_new = hts_realloc_p(s, sizeof(char*), n); if (!s_new) goto err; @@ -2166,7 +2167,7 @@ char **hts_readlines(const char *fn, int *_n) } } else return 0; // Try to shrink s to the minimum size needed - s_new = (char**)realloc(s, n * sizeof(char*)); + s_new = hts_realloc_p(s, sizeof(char*), n); if (!s_new) goto err; @@ -2334,7 +2335,8 @@ static inline int insert_to_b(bidx_t *b, int bin, uint64_t beg, uint64_t end) } } else if (l->n == l->m) { uint32_t new_m = l->m ? l->m << 1 : 1; - hts_pair64_t *new_list = realloc(l->list, new_m * sizeof(hts_pair64_t)); + hts_pair64_t *new_list = hts_realloc_p(l->list, + sizeof(hts_pair64_t), new_m); if (!new_list) return -1; l->list = new_list; l->m = new_m; @@ -2354,7 +2356,7 @@ static inline int insert_to_l(lidx_t *l, int64_t _beg, int64_t _end, uint64_t of size_t new_m = l->m * 2 > end + 1 ? l->m * 2 : end + 1; uint64_t *new_offset; - new_offset = (uint64_t*)realloc(l->offset, new_m * sizeof(uint64_t)); + new_offset = hts_realloc_p(l->offset, sizeof(uint64_t), new_m); if (!new_offset) return -1; // fill unused memory with (uint64_t)-1 @@ -2483,7 +2485,7 @@ static int compress_binning(hts_idx_t *idx, int i) hts_pair64_t *new_list; kroundup32(new_m); if (new_m > INT32_MAX) return -1; // Limited by index format - new_list = realloc(q->list, new_m * sizeof(*new_list)); + new_list = hts_realloc_p(q->list, sizeof(*new_list), new_m); if (!new_list) return -1; q->m = new_m; q->list = new_list; @@ -2566,11 +2568,11 @@ int hts_idx_push(hts_idx_t *idx, int tid, hts_pos_t beg, hts_pos_t end, uint64_t bidx_t **new_bidx; lidx_t *new_lidx; - new_bidx = (bidx_t**)realloc(idx->bidx, new_m * sizeof(bidx_t*)); + new_bidx = hts_realloc_p(idx->bidx, sizeof(bidx_t*), new_m); if (!new_bidx) return -1; idx->bidx = new_bidx; - new_lidx = (lidx_t*) realloc(idx->lidx, new_m * sizeof(lidx_t)); + new_lidx = hts_realloc_p(idx->lidx, sizeof(lidx_t), new_m); if (!new_lidx) return -1; idx->lidx = new_lidx; @@ -2653,7 +2655,7 @@ int hts_idx_tbi_name(hts_idx_t *idx, int tid, const char *name) { return idx->tbi_n; uint32_t len = strlen(name)+1; - uint8_t *tmp = (uint8_t *)realloc(idx->meta, idx->l_meta + len); + uint8_t *tmp = hts_realloc_ps(idx->meta, sizeof(*tmp), idx->l_meta, len); if (!tmp) return -1; @@ -2954,7 +2956,7 @@ static int idx_read_core(hts_idx_t *idx, BGZF *fp, int fmt) if (p->n < 0) return -3; if ((size_t) p->n > SIZE_MAX / sizeof(hts_pair64_t)) return -2; p->m = p->n; - p->list = (hts_pair64_t*)malloc(p->m * sizeof(hts_pair64_t)); + p->list = hts_malloc_p(sizeof(hts_pair64_t), p->m); if (p->list == NULL) return -2; if (bgzf_read(fp, p->list, ((size_t) p->n)<<4) != ((size_t) p->n)<<4) return -1; if (is_be) swap_bins(p); @@ -2968,7 +2970,7 @@ static int idx_read_core(hts_idx_t *idx, BGZF *fp, int fmt) if (l->n < 0) return -3; if ((size_t) l->n > SIZE_MAX / sizeof(uint64_t)) return -2; l->m = l->n; - l->offset = (uint64_t*)malloc(l->n * sizeof(uint64_t)); + l->offset = hts_malloc_p(sizeof(uint64_t), l->n); if (l->offset == NULL) return -2; if (bgzf_read(fp, l->offset, l->n << 3) != l->n << 3) return -1; if (is_be) for (j = 0; j < l->n; ++j) ed_swap_8p(&l->offset[j]); @@ -3004,7 +3006,7 @@ static hts_idx_t *idx_read(const char *fn) if (is_be) for (i = 0; i < 3; ++i) ed_swap_4p(&x[i]); if (x[2]) { if (SIZE_MAX - x[2] < 1) goto fail; // Prevent possible overflow - if ((meta = (uint8_t*)malloc((size_t) x[2] + 1)) == NULL) goto fail; + if ((meta = hts_malloc_ps(sizeof(*meta), x[2], 1)) == NULL) goto fail; if (bgzf_read(fp, meta, x[2]) != x[2]) goto fail; // Prevent possible strlen past the end in tbx_index_load2 meta[x[2]] = '\0'; @@ -3029,7 +3031,7 @@ static hts_idx_t *idx_read(const char *fn) n = le_to_u32(&x[7*4]); // location of l_nm if (n > UINT32_MAX - 29) goto fail; // Prevent possible overflow idx->l_meta = 28 + n; - if ((idx->meta = (uint8_t*)malloc(idx->l_meta + 1)) == NULL) goto fail; + if ((idx->meta = hts_malloc_ps(sizeof(*idx->meta), idx->l_meta, 1)) == NULL) goto fail; // copy format, col_seq, col_beg, col_end, meta, skip, l_nm // N.B. left in little-endian byte order. memcpy(idx->meta, &x[1*4], 28); @@ -3069,7 +3071,7 @@ int hts_idx_set_meta(hts_idx_t *idx, uint32_t l_meta, uint8_t *meta, errno = ENOMEM; return -1; } - new_meta = malloc(l + 1); + new_meta = hts_malloc_ps(sizeof(*new_meta), l, 1); if (!new_meta) return -1; memcpy(new_meta, meta, l); // Prevent possible strlen past the end in tbx_index_load2 @@ -3206,7 +3208,7 @@ static inline int reg2bins(int64_t beg, int64_t end, hts_itr_t *itr, int min_shi errno = ENOMEM; return -1; } - int *new_a = realloc(itr->bins.a, new_m * sizeof(*new_a)); + int *new_a = hts_realloc_p(itr->bins.a, sizeof(*new_a), new_m); if (!new_a) return -1; itr->bins.a = new_a; itr->bins.m = new_m; @@ -3227,7 +3229,7 @@ static inline int add_to_interval(hts_itr_t *iter, bins_t *bin, if (!bin->n) return 0; - off = realloc(iter->off, (iter->n_off + bin->n) * sizeof(*off)); + off = hts_realloc_ps(iter->off, sizeof(*off), iter->n_off, bin->n); if (!off) return -2; @@ -3770,7 +3772,7 @@ int hts_itr_multi_cram(const hts_idx_t *idx, hts_itr_t *iter) tid = curr_reg->tid; if (tid >= 0) { - tmp = realloc(off, (n_off + curr_reg->count) * sizeof(*off)); + tmp = hts_realloc_ps(off, sizeof(*off), n_off, curr_reg->count); if (!tmp) goto err; off = tmp; diff --git a/hts_expr.c b/hts_expr.c index dfd15b151..87a5e7bd1 100644 --- a/hts_expr.c +++ b/hts_expr.c @@ -38,6 +38,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include "htslib/hts_expr.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_log.h" #include "textutils_internal.h" @@ -851,12 +852,12 @@ hts_filter_t *hts_filter_init(const char *str) { if (!f) return NULL; // Oversize to permit faster comparisons with memcmp over strcmp - size_t len = strlen(str)+100; - if (!(f->str = malloc(len))) { + size_t len = strlen(str); + if (!(f->str = hts_malloc_ps(sizeof(*f->str), len, 100))) { free(f); return NULL; } - strcpy(f->str, str); + memcpy(f->str, str, len + 1); return f; } diff --git a/htslib/kbitset.h b/htslib/kbitset.h index 0a52958cf..2e0a44e36 100644 --- a/htslib/kbitset.h +++ b/htslib/kbitset.h @@ -55,6 +55,7 @@ #include #include #include +#include "hts_alloc.h" #define KBS_ELTBITS (CHAR_BIT * sizeof (unsigned long)) #define KBS_ELT(i) ((i) / KBS_ELTBITS) @@ -79,7 +80,7 @@ static inline kbitset_t *kbs_init2(size_t ni, int fill) { size_t n = (ni + KBS_ELTBITS-1) / KBS_ELTBITS; kbitset_t *bs = - (kbitset_t *) malloc(sizeof(kbitset_t) + n * sizeof(unsigned long)); + (kbitset_t *) hts_malloc_pse(sizeof(unsigned long), n, 0, sizeof(kbitset_t)); if (bs == NULL) return NULL; bs->n = bs->n_max = n; memset(bs->b, fill? ~0 : 0, n * sizeof (unsigned long)); @@ -104,7 +105,7 @@ static inline int kbs_resize2(kbitset_t **bsp, size_t ni_new, int fill) size_t n_new = (ni_new + KBS_ELTBITS-1) / KBS_ELTBITS; if (bs == NULL || n_new > bs->n_max) { bs = (kbitset_t *) - realloc(*bsp, sizeof(kbitset_t) + n_new * sizeof(unsigned long)); + hts_realloc_pse(*bsp, sizeof(unsigned long), n_new, 0, sizeof(kbitset_t)); if (bs == NULL) return -1; bs->n_max = n_new; diff --git a/htslib/ksort.h b/htslib/ksort.h index 7857d4c77..3a314cbc2 100644 --- a/htslib/ksort.h +++ b/htslib/ksort.h @@ -64,6 +64,7 @@ #include #include +#include "hts_alloc.h" #include "hts_defs.h" #ifndef klib_unused @@ -103,7 +104,7 @@ typedef struct { int curr, shift; \ \ a2[0] = array; \ - a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \ + a2[1] = temp? temp : (type_t*)hts_malloc_p(sizeof(type_t), n); \ for (curr = 0, shift = 0; (1ul< #include #include "htslib/kstring.h" +#include "htslib/hts_alloc.h" int kputd(double d, kstring_t *s) { int len = 0; @@ -233,7 +234,7 @@ int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) if (n == max) { \ int *tmp; \ max = max? max<<1 : 2; \ - if ((tmp = (int*)realloc(offsets, sizeof(int) * max))) { \ + if ((tmp = hts_realloc_p(offsets, sizeof(int), max))) { \ offsets = tmp; \ } else { \ free(offsets); \ @@ -407,7 +408,7 @@ static int *ksBM_prep(const ubyte_t *pat, int m) int i, *suff, *prep, *bmGs, *bmBc; if (m < 1) return NULL; - prep = (int*)calloc((size_t) m + 256, sizeof(int)); + prep = hts_calloc_ps(sizeof(int), m, 256); if (!prep) return NULL; bmGs = prep; bmBc = prep + m; { // preBmBc() diff --git a/probaln.c b/probaln.c index b42f85685..764a44b88 100644 --- a/probaln.c +++ b/probaln.c @@ -35,6 +35,7 @@ #include #include #include "htslib/hts.h" +#include "htslib/hts_alloc.h" /***************************************** * Probabilistic banded glocal alignment * @@ -113,11 +114,11 @@ int probaln_glocal(const uint8_t *ref, int l_ref, const uint8_t *query, } // s[] is the scaling factor to avoid underflow - s = malloc((l_query+2) * sizeof(double)); + s = hts_malloc_ps(sizeof(*s), l_query, 2); if (!s) goto fail; // initialize qual - qual = malloc(l_query * sizeof(float)); + qual = hts_malloc_p(sizeof(float), l_query); if (!qual) goto fail; if (g_qual2prob[0] == 0) for (i = 0; i < 256; ++i) diff --git a/realn.c b/realn.c index d7e8255f8..d1b76e2f5 100644 --- a/realn.c +++ b/realn.c @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include #include "htslib/hts.h" +#include "htslib/hts_alloc.h" #include "htslib/sam.h" int sam_cap_mapq(bam1_t *b, const char *ref, hts_pos_t ref_len, int thres) @@ -219,7 +220,7 @@ int sam_prob_realn(bam1_t *b, const char *ref, hts_pos_t ref_len, int flag) { } assert(bq == NULL); // bq was used above, but should now be NULL - bq = malloc(align_lqseq * 3 + lref); + bq = malloc(hts_add_sat2(hts_prod_sat2(align_lqseq, 3), lref)); if (!bq) goto fail; q = bq + align_lqseq; tseq = q + align_lqseq; @@ -233,7 +234,7 @@ int sam_prob_realn(bam1_t *b, const char *ref, hts_pos_t ref_len, int flag) { tref[i-xb] = seq_nt16_int[seq_nt16_table[(unsigned char)ref[i]]]; } - state = malloc(c->l_qseq * sizeof(int)); + state = hts_malloc_p(sizeof(int), c->l_qseq); if (!state) goto fail; if (probaln_glocal(tref, xe-xb, tseq, c->l_qseq, qual, &conf, state, q) == INT_MIN) { diff --git a/ref_cache/listener.c b/ref_cache/listener.c index 5062bcd9a..6c087abab 100644 --- a/ref_cache/listener.c +++ b/ref_cache/listener.c @@ -42,6 +42,7 @@ DEALINGS IN THE SOFTWARE. */ #include "misc.h" #include "options.h" #include "poll_wrap.h" +#include "../htslib/hts_alloc.h" struct Listeners { size_t nsocks; @@ -129,7 +130,7 @@ Listeners * get_listen_sockets(int port) { return NULL; } - lsocks->sockets = malloc(count * sizeof(*lsocks->sockets)); + lsocks->sockets = hts_malloc_p(sizeof(*lsocks->sockets), count); if (lsocks->sockets == NULL) { perror("Allocating socket list"); freeaddrinfo(addr_list); @@ -209,7 +210,7 @@ Listeners * adopt_listen_sockets(int min_sock_fd, int num_fds) { if (lsocks == NULL) return NULL; - lsocks->sockets = malloc((size_t) num_fds * sizeof(*lsocks->sockets)); + lsocks->sockets = hts_malloc_p(sizeof(*lsocks->sockets), (size_t) num_fds); if (lsocks->sockets == NULL) { perror("Allocating socket list"); free(lsocks); diff --git a/ref_cache/log_files.c b/ref_cache/log_files.c index 160bbfb67..259b7a745 100644 --- a/ref_cache/log_files.c +++ b/ref_cache/log_files.c @@ -43,6 +43,7 @@ DEALINGS IN THE SOFTWARE. */ #include "log_files.h" #include "options.h" +#include "../htslib/hts_alloc.h" #define LOG_NAME_LEN 80 typedef struct { @@ -200,7 +201,7 @@ Logfiles * open_logs(const Options *opts) { && (strcmp(suff, "log") == 0 || strcmp(suff, "log.gz") == 0)) { if (logfiles->nlogs == logfiles->sz) { size_t new_sz = logfiles->sz * 2; - Logfile *new_logs = realloc(logfiles->logs, new_sz * sizeof(Logfile)); + Logfile *new_logs = hts_realloc_p(logfiles->logs, sizeof(Logfile), new_sz); if (new_logs == NULL) { perror(NULL); goto fail; diff --git a/ref_cache/main.c b/ref_cache/main.c index 11a393f4e..27564ff98 100644 --- a/ref_cache/main.c +++ b/ref_cache/main.c @@ -61,6 +61,7 @@ DEALINGS IN THE SOFTWARE. */ #include "poll_wrap.h" #include "server.h" #include "upstream.h" +#include "../htslib/hts_alloc.h" // May not have been defined, depending on compiler options #ifndef NI_MAXHOST @@ -107,10 +108,10 @@ static void change_name(char *name) { static int init_children(Options *opts) { int k; - upstream = malloc((opts->max_kids + 1U) * sizeof(int)); + upstream = hts_malloc_ps(sizeof(*upstream), opts->max_kids, 1); if (upstream == NULL) return -1; - kids = malloc((opts->max_kids + 1U) * sizeof(Child_proc)); + kids = hts_malloc_ps(sizeof(*kids), opts->max_kids, 1); if (kids == NULL) return -1; for (k = 0; k <= opts->max_kids; k++) { @@ -751,8 +752,9 @@ static int add_match_addr(Options *opts, const char *addr_list) { if (opts->match_addrs_size == opts->num_match_addrs) { size_t new_size = (opts->match_addrs_size > 0 ? opts->match_addrs_size * 2 : 16); - MatchAddr *new_addrs = realloc(opts->match_addrs, - new_size * sizeof(*new_addrs)); + MatchAddr *new_addrs = hts_realloc_p(opts->match_addrs, + sizeof(*new_addrs), + new_size); if (!new_addrs) { perror("Allocating address match list"); freeaddrinfo(addrs); diff --git a/ref_cache/poll_wrap_poll.c b/ref_cache/poll_wrap_poll.c index ca28b34d7..5631b339c 100644 --- a/ref_cache/poll_wrap_poll.c +++ b/ref_cache/poll_wrap_poll.c @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include #include "poll_wrap.h" +#include "../htslib/hts_alloc.h" #include "../cram/pooled_alloc.h" #if defined(REF_CACHE_NO_POOLED_ALLOC) @@ -74,11 +75,11 @@ Poll_wrap *pw_init(int debug) { if (pw->pool == NULL) goto fail; pw->polled_sz = INIT_POLLED_SZ; - pw->polled = malloc(pw->polled_sz * sizeof(struct pollfd)); + pw->polled = hts_malloc_p(sizeof(struct pollfd), pw->polled_sz); if (pw->polled == NULL) goto fail; pw->idx_sz = INIT_IDX_SZ; - pw->fd_index = malloc(pw->idx_sz * sizeof(unsigned int)); + pw->fd_index = hts_malloc_p(sizeof(unsigned int), pw->idx_sz); if (pw->fd_index == NULL) goto fail; pw->item_index = calloc(pw->idx_sz, sizeof(Pw_item *)); @@ -113,13 +114,13 @@ Pw_item * pw_register(Poll_wrap *pw, int fd, Pw_fd_type fd_type, if (pw->idx_sz <= (unsigned int) fd) { unsigned int new_sz = (unsigned int) fd + 1; - unsigned int *new_index = realloc(pw->fd_index, - new_sz * sizeof(unsigned int)); + unsigned int *new_index = hts_realloc_p(pw->fd_index, + sizeof(*pw->fd_index), new_sz); Pw_item **new_items; if (new_index == NULL) return NULL; pw->fd_index = new_index; - new_items = realloc(pw->item_index, new_sz * sizeof(Pw_item *)); + new_items = hts_realloc_p(pw->item_index, sizeof(*pw->item_index), new_sz); if (new_items == NULL) return NULL; memset(new_items + pw->idx_sz,0,(new_sz - pw->idx_sz) * sizeof(Pw_item *)); @@ -128,8 +129,8 @@ Pw_item * pw_register(Poll_wrap *pw, int fd, Pw_fd_type fd_type, } if (pw->npolled == pw->polled_sz) { unsigned int new_sz = pw->polled_sz * 2; - struct pollfd *new_polled = realloc(pw->polled, - new_sz * sizeof(*new_polled)); + struct pollfd *new_polled = hts_realloc_p(pw->polled, + sizeof(*pw->polled), new_sz); if (new_polled == NULL) return NULL; pw->polled = new_polled; diff --git a/regidx.c b/regidx.c index 602edebf3..20640f0cc 100644 --- a/regidx.c +++ b/regidx.c @@ -27,6 +27,7 @@ #include #include #include "htslib/hts.h" +#include "htslib/hts_alloc.h" #include "htslib/kstring.h" #include "htslib/kseq.h" #include "htslib/khash_str2int.h" @@ -184,7 +185,7 @@ int regidx_push(regidx_t *idx, char *chr_beg, char *chr_end, hts_pos_t beg, hts_ list->reg[list->nreg].end = end; if ( idx->payload_size ) { if ( mreg != list->mreg ) { - uint8_t *new_dat = realloc(list->dat, idx->payload_size*list->mreg); + uint8_t *new_dat = hts_realloc_p(list->dat, idx->payload_size, list->mreg); if (!new_dat) return -1; list->dat = new_dat; } @@ -339,12 +340,12 @@ static int reglist_build_index_(regidx_t *regidx, reglist_t *list) if ( !regidx->payload_size ) { qsort(list->reg,list->nreg,sizeof(reg_t),cmp_reg_ptrs); } else { - reg_t **ptr = malloc(sizeof(*ptr)*list->nreg); + reg_t **ptr = hts_malloc_p(sizeof(*ptr), list->nreg); if (!ptr) return -1; for (i=0; inreg; i++) ptr[i] = list->reg + i; qsort(ptr,list->nreg,sizeof(*ptr),cmp_reg_ptrs2); - uint8_t *tmp_dat = malloc(regidx->payload_size*list->nreg); + uint8_t *tmp_dat = hts_malloc_p(regidx->payload_size, list->nreg); if (!tmp_dat) { free(ptr); return -1; } for (i=0; inreg; i++) { size_t iori = ptr[i] - list->reg; @@ -355,7 +356,7 @@ static int reglist_build_index_(regidx_t *regidx, reglist_t *list) free(list->dat); list->dat = tmp_dat; - reg_t *tmp_reg = (reg_t*) malloc(sizeof(reg_t)*list->nreg); + reg_t *tmp_reg = (reg_t*) hts_malloc_p(sizeof(reg_t), list->nreg); if (!tmp_reg) { free(ptr); return -1; } for (i=0; inreg; i++) { size_t iori = ptr[i] - list->reg; diff --git a/sam.c b/sam.c index 56deec42e..dc1841910 100644 --- a/sam.c +++ b/sam.c @@ -53,6 +53,7 @@ DEALINGS IN THE SOFTWARE. */ #include "hts_internal.h" #include "sam_internal.h" #include "htslib/hfile.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_endian.h" #include "htslib/hts_expr.h" #include "header.h" @@ -212,7 +213,7 @@ sam_hdr_t *sam_hdr_dup(const sam_hdr_t *h0) goto fail; } else { h->l_text = h0->text ? h0->l_text : 0; - h->text = malloc(h->l_text + 1); + h->text = hts_malloc_ps(sizeof(*h->text), h->l_text, 1); if (!h->text) goto fail; if (h0->text) memcpy(h->text, h0->text, h->l_text); @@ -592,7 +593,7 @@ int bam_set1(bam1_t *bam, // re-allocate the data buffer as needed. size_t data_len = l_qname + qname_nuls + n_cigar * 4 + (l_seq + 1) / 2 + l_seq; - if (realloc_bam_data(bam, data_len + l_aux) < 0) { + if (realloc_bam_data(bam, hts_add_sat2(data_len, l_aux)) < 0) { return -1; } @@ -2909,7 +2910,7 @@ ssize_t sam_parse_cigar(const char *in, char **end, uint32_t **a_cigar, size_t * n_cigar = read_ncigar(in); if (!n_cigar) return 0; if (n_cigar > *a_mem) { - uint32_t *a_tmp = realloc(*a_cigar, n_cigar*sizeof(**a_cigar)); + uint32_t *a_tmp = hts_realloc_p(*a_cigar, sizeof(**a_cigar), n_cigar); if (a_tmp) { *a_cigar = a_tmp; *a_mem = n_cigar; @@ -3257,7 +3258,7 @@ static void *sam_parse_worker(void *arg) { if (i >= gb->abams) { int old_abams = gb->abams; gb->abams *= 2; - b = (bam1_t *)realloc(gb->bams, gb->abams*sizeof(bam1_t)); + b = hts_realloc_p(gb->bams, sizeof(bam1_t), gb->abams); if (!b) { gb->abams /= 2; sam_state_err(fd, ENOMEM); @@ -3364,7 +3365,7 @@ static void *sam_dispatcher_read(void *vp) { if (!l) goto err; l->alloc = SAM_NBYTES; - l->data = malloc(l->alloc+8); // +8 for optimisation in sam_parse1 + l->data = hts_malloc_ps(sizeof(*l->data), l->alloc, 8); // +8 for optimisation in sam_parse1 if (!l->data) { free(l); l = NULL; @@ -3375,7 +3376,8 @@ static void *sam_dispatcher_read(void *vp) { l->next = NULL; if (l->alloc < line_frag+SAM_NBYTES/2) { - char *rp = realloc(l->data, line_frag+SAM_NBYTES/2 +8); + char *rp = hts_realloc_ps(l->data, sizeof(*rp), + line_frag, SAM_NBYTES/2 + 8); if (!rp) goto err; l->alloc = line_frag+SAM_NBYTES/2; @@ -3408,7 +3410,7 @@ static void *sam_dispatcher_read(void *vp) { // entire buffer is part of a single line if (cp == l->data) { line_frag = l->data_size; - char *rp = realloc(l->data, l->alloc * 2 + 8); + char *rp = realloc(l->data, hts_add_sat2(hts_prod_sat2(l->alloc, 2), 8)); if (!rp) goto err; l->alloc *= 2; @@ -5393,7 +5395,7 @@ static inline void mp_free(mempool_t *mp, lbnode_t *p) --mp->cnt; p->next = 0; // clear lbnode_t::next here if (mp->n == mp->max) { mp->max = mp->max? mp->max<<1 : 256; - mp->buf = (lbnode_t**)realloc(mp->buf, sizeof(lbnode_t*) * mp->max); + mp->buf = hts_realloc_p(mp->buf, sizeof(lbnode_t*), mp->max); } mp->buf[mp->n++] = p; } @@ -6031,7 +6033,7 @@ const bam_pileup1_t *bam_plp64_next(bam_plp_t iter, int *_tid, hts_pos_t *_pos, if (p->b.core.tid == iter->tid && p->beg <= iter->pos) { // here: p->end > pos; then add to pileup if (n_plp == iter->max_plp) { // then double the capacity iter->max_plp = iter->max_plp? iter->max_plp<<1 : 256; - iter->plp = (bam_pileup1_t*)realloc(iter->plp, sizeof(bam_pileup1_t) * iter->max_plp); + iter->plp = hts_realloc_p(iter->plp, sizeof(bam_pileup1_t), iter->max_plp); } iter->plp[n_plp].b = &p->b; iter->plp[n_plp].cd = p->cd; diff --git a/synced_bcf_reader.c b/synced_bcf_reader.c index 7769132fa..d7780d6e1 100644 --- a/synced_bcf_reader.c +++ b/synced_bcf_reader.c @@ -39,6 +39,7 @@ DEALINGS IN THE SOFTWARE. */ #include "htslib/kseq.h" #include "htslib/khash_str2int.h" #include "htslib/bgzf.h" +#include "htslib/hts_alloc.h" #include "htslib/thread_pool.h" #include "bcf_sr_sort.h" @@ -156,7 +157,7 @@ static int *init_filters(bcf_hdr_t *hdr, const char *filters, int *nfilters) { if ( *tmp==',' || !*tmp ) { - int *otmp = (int*) realloc(out, (nout+1)*sizeof(int)); + int *otmp = hts_realloc_ps(out, sizeof(*otmp), nout, 1); if (!otmp) goto err; out = otmp; @@ -279,9 +280,11 @@ int bcf_sr_add_hreader(bcf_srs_t *files, htsFile *file_ptr, int autoclose, const return 0; } - files->has_line = (int*) realloc(files->has_line, sizeof(int)*(files->nreaders+1)); + files->has_line = hts_realloc_ps(files->has_line, sizeof(*files->has_line), + files->nreaders, 1); files->has_line[files->nreaders] = 0; - files->readers = (bcf_sr_t*) realloc(files->readers, sizeof(bcf_sr_t)*(files->nreaders+1)); + files->readers = hts_realloc_ps(files->readers, sizeof(*files->readers), + files->nreaders, 1); bcf_sr_t *reader = &files->readers[files->nreaders++]; memset(reader,0,sizeof(bcf_sr_t)); @@ -435,7 +438,7 @@ int bcf_sr_add_hreader(bcf_srs_t *files, htsFile *file_ptr, int autoclose, const if ((auxdata = BCF_SR_AUX(files))) { //store closure status for htsfile - int *tmp = realloc(auxdata->closefile, sizeof(int) * files->nreaders); + int *tmp = hts_realloc_p(auxdata->closefile, sizeof(int), files->nreaders); if (!tmp) { hts_log_error("Failed to allocate memory"); return 0; @@ -666,7 +669,7 @@ static int _reader_fill_buffer(bcf_srs_t *files, bcf_sr_t *reader) { // Increase buffer size reader->mbuffer += 8; - reader->buffer = (bcf1_t**) realloc(reader->buffer, sizeof(bcf1_t*)*reader->mbuffer); + reader->buffer = hts_realloc_p(reader->buffer, sizeof(bcf1_t*), reader->mbuffer); for (i=8; i>0; i--) // initialize { reader->buffer[reader->mbuffer-i] = bcf_init1(); @@ -980,7 +983,8 @@ int bcf_sr_set_samples(bcf_srs_t *files, const char *fname, int is_file) continue; } - files->samples = (char**) realloc(files->samples, (files->n_smpl+1)*sizeof(const char*)); + files->samples = hts_realloc_ps(files->samples, sizeof(const char*), + files->n_smpl, 1); files->samples[files->n_smpl++] = strdup(smpl[i]); } @@ -1000,7 +1004,7 @@ int bcf_sr_set_samples(bcf_srs_t *files, const char *fname, int is_file) for (i=0; inreaders; i++) { bcf_sr_t *reader = &files->readers[i]; - reader->samples = (int*) malloc(sizeof(int)*files->n_smpl); + reader->samples = hts_malloc_p(sizeof(int), files->n_smpl); reader->n_smpl = files->n_smpl; for (j=0; jn_smpl; j++) reader->samples[j] = bcf_hdr_id2int(reader->header, BCF_DT_SAMPLE, files->samples[j]); @@ -1040,8 +1044,8 @@ static int _regions_add(bcf_sr_regions_t *reg, const char *chr, hts_pos_t start, { // the chromosome block does not exist iseq = reg->nseqs++; - reg->seq_names = (char**) realloc(reg->seq_names,sizeof(char*)*reg->nseqs); - reg->regs = (region_t*) realloc(reg->regs,sizeof(region_t)*reg->nseqs); + reg->seq_names = hts_realloc_p(reg->seq_names,sizeof(char*),reg->nseqs); + reg->regs = hts_realloc_p(reg->regs,sizeof(region_t),reg->nseqs); memset(®->regs[reg->nseqs-1],0,sizeof(region_t)); reg->seq_names[iseq] = strdup(chr); reg->regs[iseq].creg = -1; diff --git a/tabix.c b/tabix.c index bd7d100f6..39eacc8f0 100644 --- a/tabix.c +++ b/tabix.c @@ -41,6 +41,7 @@ DEALINGS IN THE SOFTWARE. */ #include "htslib/kseq.h" #include "htslib/bgzf.h" #include "htslib/hts.h" +#include "htslib/hts_alloc.h" #include "htslib/regidx.h" #include "htslib/hts_defs.h" #include "htslib/hts_log.h" @@ -154,7 +155,7 @@ static char **parse_regions(char *regions_fname, char **argv, int argc, int *nre } (*nregs) += regidx_nregs(idx); - regs = (char**) malloc(sizeof(char*)*(*nregs)); + regs = hts_malloc_p(sizeof(char*), *nregs); if (!regs) error_errno(NULL); int nseq; @@ -184,7 +185,7 @@ static char **parse_regions(char *regions_fname, char **argv, int argc, int *nre { if ( argc ) { - regs = (char**) malloc(sizeof(char*)*argc); + regs = hts_malloc_p(sizeof(char*), argc); if (!regs) error_errno(NULL); } else diff --git a/tbx.c b/tbx.c index 61721dc3a..d9d636b43 100644 --- a/tbx.c +++ b/tbx.c @@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include "htslib/tbx.h" #include "htslib/bgzf.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_endian.h" #include "hts_internal.h" @@ -382,7 +383,7 @@ static int tbx_set_meta(tbx_t *tbx) khash_t(s2i) *d = (khash_t(s2i)*)tbx->dict; memcpy(x, &tbx->conf, 24); - name = (char**)malloc(sizeof(char*) * kh_size(d)); + name = hts_malloc_p(sizeof(char*), kh_size(d)); if (!name) return -1; for (k = kh_begin(d), l = 0; k != kh_end(d); ++k) { if (!kh_exist(d, k)) continue; @@ -390,7 +391,7 @@ static int tbx_set_meta(tbx_t *tbx) l += strlen(kh_key(d, k)) + 1; // +1 to include '\0' } l_nm = x[6] = l; - meta = (uint8_t*)malloc(l_nm + 28); + meta = hts_malloc_ps(sizeof(*meta), l_nm, 28); if (!meta) { free(name); return -1; } if (ed_is_big()) for (i = 0; i < 7; ++i) diff --git a/test/test-bcf-sr.c b/test/test-bcf-sr.c index 1cd198fa0..853d6d824 100644 --- a/test/test-bcf-sr.c +++ b/test/test-bcf-sr.c @@ -36,6 +36,7 @@ #include #include +#include "../htslib/hts_alloc.h" #include "../htslib/hts_defs.h" #include "../htslib/synced_bcf_reader.h" #include "../htslib/hts.h" @@ -224,7 +225,7 @@ int main(int argc, char *argv[]) error("Failed to set targets\n"); } - if (usefptr && !(htsfp = malloc(sizeof(htsFile*) * nvcf))) { + if (usefptr && !(htsfp = hts_malloc_p(sizeof(htsFile*), nvcf))) { error("Failed to allocate memory\n"); } diff --git a/test/test-vcf-api.c b/test/test-vcf-api.c index 2de39c72e..8656f792a 100644 --- a/test/test-vcf-api.c +++ b/test/test-vcf-api.c @@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include "../htslib/hts.h" +#include "../htslib/hts_alloc.h" #include "../htslib/vcf.h" #include "../htslib/vcfutils.h" #include "../htslib/kbitset.h" @@ -201,7 +202,7 @@ void write_bcf(char *fname) check0(bcf_update_info_flag(hdr, rec, "DB", NULL, 1)); check0(bcf_update_info_flag(hdr, rec, "H2", NULL, 1)); // .. FORMAT - int32_t *tmpia = (int*)malloc(bcf_hdr_nsamples(hdr)*2*sizeof(int)); + int32_t *tmpia = (int*)hts_malloc_p(2 * sizeof(*tmpia), bcf_hdr_nsamples(hdr)); tmpia[0] = bcf_gt_phased(0); tmpia[1] = bcf_gt_phased(0); tmpia[2] = bcf_gt_phased(1); diff --git a/test/test_khash.c b/test/test_khash.c index 76ff1879c..792cd34ab 100644 --- a/test/test_khash.c +++ b/test/test_khash.c @@ -40,6 +40,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include +#include "../htslib/hts_alloc.h" #include "../htslib/khash.h" #include "../htslib/kroundup.h" @@ -68,7 +69,7 @@ char * make_keys(size_t num, size_t kl) { char *keys; if (num > MAX_ENTRIES) return NULL; - keys = malloc(kl * num); + keys = hts_malloc_p(kl, num); if (!keys) { perror(NULL); return NULL; @@ -285,7 +286,7 @@ static size_t read_keys(const char *keys_file, char **keys_out, if (key < end) nkeys++; } - key_locations = malloc(nkeys * sizeof(*key_locations)); + key_locations = hts_malloc_p(sizeof(*key_locations), nkeys); if (!key_locations) goto fail; diff --git a/thread_pool.c b/thread_pool.c index 2370aa82e..4d70047f2 100644 --- a/thread_pool.c +++ b/thread_pool.c @@ -40,6 +40,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include "thread_pool_internal.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_log.h" // Minimum stack size for threads. Required for some rANS codecs @@ -738,12 +739,12 @@ hts_tpool *hts_tpool_init(int n) { p->t_stack = NULL; p->n_count = 0; p->n_running = 0; - p->t = malloc(n * sizeof(p->t[0])); + p->t = hts_malloc_p(sizeof(p->t[0]), n); if (!p->t) { free(p); return NULL; } - p->t_stack = malloc(n * sizeof(*p->t_stack)); + p->t_stack = hts_malloc_p(sizeof(*p->t_stack), n); if (!p->t_stack) { free(p->t); free(p); diff --git a/vcf.c b/vcf.c index 544fe8c01..3b8970962 100644 --- a/vcf.c +++ b/vcf.c @@ -46,6 +46,7 @@ DEALINGS IN THE SOFTWARE. */ #include "htslib/tbx.h" #include "htslib/hfile.h" #include "hts_internal.h" +#include "htslib/hts_alloc.h" #include "htslib/hts_endian.h" #include "htslib/khash_str2int.h" #include "htslib/kstring.h" @@ -248,7 +249,7 @@ static int bcf_hdr_add_sample_len(bcf_hdr_t *h, const char *s, size_t len) // Ensure space is available in h->samples size_t n = kh_size(d); - char **new_samples = realloc(h->samples, sizeof(char*) * (n + 1)); + char **new_samples = hts_realloc_ps(h->samples, sizeof(*h->samples), n, 1); if (!new_samples) { free(sdup); return -1; @@ -324,7 +325,7 @@ int bcf_hdr_sync(bcf_hdr_t *h) { bcf_idpair_t *new_idpair; // this should be true only for i=2, BCF_DT_SAMPLE - new_idpair = (bcf_idpair_t*) realloc(h->id[i], kh_size(d)*sizeof(bcf_idpair_t)); + new_idpair = hts_realloc_p(h->id[i], sizeof(bcf_idpair_t), kh_size(d)); if (!new_idpair) return -1; h->n[i] = kh_size(d); h->id[i] = new_idpair; @@ -381,9 +382,9 @@ bcf_hrec_t *bcf_hrec_dup(bcf_hrec_t *hrec) if (!out->value) goto fail; } out->nkeys = hrec->nkeys; - out->keys = (char**) malloc(sizeof(char*)*hrec->nkeys); + out->keys = hts_malloc_p(sizeof(char*), hrec->nkeys); if (!out->keys) goto fail; - out->vals = (char**) malloc(sizeof(char*)*hrec->nkeys); + out->vals = hts_malloc_p(sizeof(char*), hrec->nkeys); if (!out->vals) goto fail; int i, j = 0; for (i=0; inkeys; i++) @@ -442,14 +443,14 @@ int bcf_hrec_add_key(bcf_hrec_t *hrec, const char *str, size_t len) char **tmp; size_t n = hrec->nkeys + 1; assert(len > 0 && len < SIZE_MAX); - tmp = realloc(hrec->keys, sizeof(char*)*n); + tmp = hts_realloc_p(hrec->keys, sizeof(char*), n); if (!tmp) return -1; hrec->keys = tmp; - tmp = realloc(hrec->vals, sizeof(char*)*n); + tmp = hts_realloc_p(hrec->vals, sizeof(char*), n); if (!tmp) return -1; hrec->vals = tmp; - hrec->keys[hrec->nkeys] = (char*) malloc((len+1)*sizeof(char)); + hrec->keys[hrec->nkeys] = hts_malloc_ps(sizeof(char), len, 1); if (!hrec->keys[hrec->nkeys]) return -1; memcpy(hrec->keys[hrec->nkeys],str,len); hrec->keys[hrec->nkeys][len] = 0; @@ -471,7 +472,7 @@ int bcf_hrec_set_val(bcf_hrec_t *hrec, int i, const char *str, size_t len, int i errno = ENOMEM; return -1; } - hrec->vals[i] = (char*) malloc((len+3)*sizeof(char)); + hrec->vals[i] = hts_malloc_ps(sizeof(char), len, 3); if (!hrec->vals[i]) return -1; hrec->vals[i][0] = '"'; memcpy(&hrec->vals[i][1],str,len); @@ -484,7 +485,7 @@ int bcf_hrec_set_val(bcf_hrec_t *hrec, int i, const char *str, size_t len, int i errno = ENOMEM; return -1; } - hrec->vals[i] = (char*) malloc((len+1)*sizeof(char)); + hrec->vals[i] = hts_malloc_ps(sizeof(char), len, 1); if (!hrec->vals[i]) return -1; memcpy(hrec->vals[i],str,len); hrec->vals[i][len] = 0; @@ -495,11 +496,11 @@ int bcf_hrec_set_val(bcf_hrec_t *hrec, int i, const char *str, size_t len, int i int hrec_add_idx(bcf_hrec_t *hrec, int idx) { int n = hrec->nkeys + 1; - char **tmp = (char**) realloc(hrec->keys, sizeof(char*)*n); + char **tmp = hts_realloc_p(hrec->keys, sizeof(char*), n); if (!tmp) return -1; hrec->keys = tmp; - tmp = (char**) realloc(hrec->vals, sizeof(char*)*n); + tmp = hts_realloc_p(hrec->vals, sizeof(char*), n); if (!tmp) return -1; hrec->vals = tmp; @@ -666,7 +667,7 @@ bcf_hrec_t *bcf_hdr_parse_line(const bcf_hdr_t *h, const char *line, int *len) hrec = (bcf_hrec_t*) calloc(1,sizeof(bcf_hrec_t)); if (!hrec) { *len = -1; return NULL; } - hrec->key = (char*) malloc(sizeof(char)*(n+1)); + hrec->key = hts_malloc_ps(sizeof(char), n, 1); if (!hrec->key) goto fail; memcpy(hrec->key,p,n); hrec->key[n] = 0; @@ -676,7 +677,7 @@ bcf_hrec_t *bcf_hdr_parse_line(const bcf_hdr_t *h, const char *line, int *len) if ( *p!='<' ) // generic field, e.g. ##samtoolsVersion=0.1.18-r579 { while ( *q && *q!='\n' ) q++; - hrec->value = (char*) malloc((q-p+1)*sizeof(char)); + hrec->value = hts_malloc_p(sizeof(char), (q-p+1)); if (!hrec->value) goto fail; memcpy(hrec->value, p, q-p); hrec->value[q-p] = 0; @@ -1180,7 +1181,7 @@ int bcf_hdr_add_hrec(bcf_hdr_t *hdr, bcf_hrec_t *hrec) // New record, needs to be added int n = hdr->nhrec + 1; - bcf_hrec_t **new_hrec = realloc(hdr->hrec, n*sizeof(bcf_hrec_t*)); + bcf_hrec_t **new_hrec = hts_realloc_p(hdr->hrec, sizeof(bcf_hrec_t*), n); if (!new_hrec) { free(str.s); bcf_hdr_unregister_hrec(hdr, hrec); @@ -3772,7 +3773,7 @@ static int vcf_parse_filter(kstring_t *str, const bcf_hdr_t *h, bcf1_t *v, char for (r = p; *r; ++r) if (*r == ';') ++n_flt; if (n_flt > max_n_flt) { - a_flt = malloc(n_flt * sizeof(*a_flt)); + a_flt = hts_malloc_p(sizeof(*a_flt), n_flt); if (!a_flt) { hts_log_error("Could not allocate memory at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1); v->errcode |= BCF_ERR_LIMITS; // No appropriate code? @@ -3878,7 +3879,7 @@ static int vcf_parse_info(kstring_t *str, const bcf_hdr_t *h, bcf1_t *v, char *p if (*t == ',') ++n_val; // Check both int and float size in one step for simplicity if (n_val > max_n_val) { - int32_t *a_tmp = (int32_t *)realloc(a_val, n_val * sizeof(*a_val)); + int32_t *a_tmp = hts_realloc_p(a_val, sizeof(*a_val), n_val); if (!a_tmp) { hts_log_error("Could not allocate memory at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1); v->errcode |= BCF_ERR_LIMITS; // No appropriate code? @@ -4486,7 +4487,7 @@ int vcf_format(const bcf_hdr_t *h, const bcf1_t *v, kstring_t *s) // No real gain to be had in handling unpacked data here, // but it doesn't cost us much in complexity either and // it gives us flexibility. - fmt = malloc(v->n_fmt * sizeof(*fmt)); + fmt = hts_malloc_p(sizeof(*fmt), v->n_fmt); if (!fmt) return -1; } @@ -5032,7 +5033,7 @@ int bcf_translate(const bcf_hdr_t *dst_hdr, bcf_hdr_t *src_hdr, bcf1_t *line) int dict; for (dict=0; dict<2; dict++) // BCF_DT_ID and BCF_DT_CTG { - src_hdr->transl[dict] = (int*) malloc(src_hdr->n[dict]*sizeof(int)); + src_hdr->transl[dict] = hts_malloc_p(sizeof(int), src_hdr->n[dict]); for (i=0; in[dict]; i++) { if ( !src_hdr->id[dict][i].key ) // gap left after removed BCF header lines @@ -5276,7 +5277,7 @@ int bcf_hdr_set_samples(bcf_hdr_t *hdr, const char *samples, int is_file) else { // Make new list and dictionary with desired samples - char **samples = (char**) malloc(sizeof(char*)*bcf_hdr_nsamples(hdr)); + char **samples = hts_malloc_p(sizeof(char*), bcf_hdr_nsamples(hdr)); vdict_t *new_dict, *d; int k, res; if (!samples) return -1; @@ -5447,7 +5448,8 @@ static int bcf_set_variant_types(bcf1_t *b) bcf_dec_t *d = &b->d; if ( d->n_var < b->n_allele ) { - bcf_variant_t *new_var = realloc(d->var, sizeof(bcf_variant_t)*b->n_allele); + bcf_variant_t *new_var = hts_realloc_p(d->var, sizeof(bcf_variant_t), + b->n_allele); if (!new_var) return -1; d->var = new_var; @@ -5692,7 +5694,7 @@ int bcf_update_format_string(const bcf_hdr_t *hdr, bcf1_t *line, const char *key int len = strlen(values[i]); if ( len > max_len ) max_len = len; } - char *out = (char*) malloc(max_len*n); + char *out = hts_malloc_p(max_len, n); if ( !out ) return -2; for (i=0; ilen ) { *ndst = info->len; - *dst = realloc(*dst, *ndst * size1); + *dst = hts_realloc_p(*dst, *ndst, size1); } #define BRANCH(type_t, convert, is_missing, is_vector_end, set_missing, set_regular, out_type_t) do { \ @@ -6166,7 +6168,7 @@ int bcf_get_format_string(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, c int nsmpl = bcf_hdr_nsamples(hdr); if ( !*dst ) { - *dst = (char**) malloc(sizeof(char*)*nsmpl); + *dst = hts_malloc_p(sizeof(char*), nsmpl); if ( !*dst ) return -4; // could not alloc (*dst)[0] = NULL; } @@ -6226,7 +6228,7 @@ int bcf_get_format_values(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, v if ( *ndst < fmt->n*nsmpl ) { *ndst = fmt->n*nsmpl; - *dst = realloc(*dst, *ndst*size1); + *dst = hts_realloc_p(*dst, *ndst, size1); if ( !*dst ) return -4; // could not alloc } diff --git a/vcfutils.c b/vcfutils.c index 3e6abb6c8..94350c903 100644 --- a/vcfutils.c +++ b/vcfutils.c @@ -27,6 +27,7 @@ DEALINGS IN THE SOFTWARE. */ #include #include "htslib/vcfutils.h" +#include "htslib/hts_alloc.h" #include "htslib/kbitset.h" int bcf_calc_ac(const bcf_hdr_t *header, bcf1_t *line, int *ac, int which) @@ -667,7 +668,7 @@ int bcf_remove_allele_set(const bcf_hdr_t *header, bcf1_t *line, const struct kb const char *cardinalities[] = { "fixed", ".", "A", "G", "R", "P", "LA", "LG", "LR", "M" }; - int *map = malloc(line->n_allele * sizeof(int)); + int *map = hts_malloc_p(sizeof(int), line->n_allele); int *laa = NULL, *laa_map = NULL, *lr_orig = NULL; uint8_t *dat = NULL; int num_laa, laa_size = 0, laa_map_stride = 0; @@ -1002,10 +1003,11 @@ int bcf_remove_allele_set(const bcf_hdr_t *header, bcf1_t *line, const struct kb int num_laa_vals = num_laa / line->n_sample; laa_map_stride = num_laa_vals + 1; int max_k = 0; - laa_map = malloc(sizeof(*laa_map) * laa_map_stride * line->n_sample); + laa_map = hts_malloc_p(sizeof(*laa_map), + hts_prod_sat2(laa_map_stride, line->n_sample)); if (!laa_map) goto err; - lr_orig = malloc(sizeof(*lr_orig) * line->n_sample); + lr_orig = hts_malloc_p(sizeof(*lr_orig), line->n_sample); if (!lr_orig) goto err; int laa_changed = 0;