diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml new file mode 100644 index 000000000..a8cae56fd --- /dev/null +++ b/.github/workflows/linux-build.yml @@ -0,0 +1,126 @@ +name: Linux CI +on: [push, pull_request] + +jobs: + build-linux: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Fully declare each matrix entry here, as otherwise it's possible + # to get unexpected results due to the way the entries get expanded + # (See https://magmanu.github.io/blog/tech/matrices-github-actions/) + include: + # x86-64, clang, configure + - os: ubuntu-latest + use-configure: use-configure + htssrc: hidden-htslib + compiler: clang + sanitize: no-sanitize + + # x86-64, gcc, configure, sanitize + - os: ubuntu-latest + use-configure: use-configure + htssrc: hidden-htslib + compiler: gcc + sanitize: sanitize + + # x86-64, gcc, no configure, run extra checks + - os: ubuntu-latest + use-configure: no-configure + htssrc: htslib + compiler: gcc + sanitize: no-sanitize + + # arm, gcc, configure + - os: ubuntu-24.04-arm + use-configure: use-configure + htssrc: hidden-htslib + compiler: gcc + sanitize: no-sanitize + + defaults: + run: + working-directory: ./bcftools + + steps: + - name: Checkout + # This is actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false + path: bcftools + + - name: Run apt + working-directory: . + run: | + sudo apt-get update + sudo apt-get install -y --no-install-suggests --no-install-recommends autoconf automake make ${{ matrix.compiler }} perl zlib1g-dev libbz2-dev liblzma-dev libcurl4-gnutls-dev libssl-dev libdeflate-dev libperl-dev libgsl0-dev libio-pty-perl + + - name: Clone htslib + working-directory: . + run: | + mkdir -p ${{ matrix.htssrc }} + htslib_pr=`git log -2 --format='%s' | sed -n 's/.*htslib#\([0-9]*\).*/\1/p'` + ./bcftools/.ci_helpers/clone ${GITHUB_REPOSITORY_OWNER} htslib ${{ matrix.htssrc }} ${GITHUB_HEAD_REF:-$GITHUB_REF_NAME} $htslib_pr + + - name: Set build options + run: | + cc='clang' + configure_opts='--enable-werror --enable-perl-filters --enable-libgsl' + cflags='-g -O3' + ldflags='' + + if [ '${{ matrix.sanitize }}' = 'sanitize' ] ; then + cflags="-g -Og -fsanitize=address,undefined -Wno-format-truncation -Wno-format-overflow -DHTS_ALLOW_UNALIGNED=0" + ldflags='-fsanitize=address,undefined' + fi + + echo "cc=${cc}" >> "$GITHUB_ENV" + echo "configure_opts=${configure_opts}" >> "$GITHUB_ENV" + echo "cflags=${cflags}" >> "$GITHUB_ENV" + echo "ldflags=${ldflags}" >> "$GITHUB_ENV" + + - name: Build htslib + working-directory: ${{ matrix.htssrc }} + run: | + htsdir="`realpath ..`/installed-htslib" + echo "htsdir=${htsdir}" >> "$GITHUB_ENV" + + autoreconf -i + { ./configure --prefix="$htsdir" ${configure_opts} ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags"} ${ldflags:+LDFLAGS="$ldflags"} || + { cat config.log ; false ; } ; } && + make -j 5 && + make install + + - name: Configure bcftools + if: ${{ matrix.use-configure == 'use-configure' }} + run: | + autoreconf -i + + with_htslib="--with-htslib=$htsdir" + ldflags="${ldflags:+$ldflags }-Wl,-rpath=${htsdir}/lib" + + printf "\nRunning ./configure ${with_htslib} ${configure_opts}${cc:+ CC='$cc'}${cflags:+ CFLAGS='$cflags'}${ldflags:+ LDFLAGS='$ldflags'} ...\n\n" + + { ./configure $with_htslib ${configure_opts} ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags"} ${ldflags:+LDFLAGS="$ldflags"} && + { grep -qE 'CFLAGS *=.*-Werror' config.mk || + { printf "\nStopping as -Werror was not set.\n" 1>&2 ; false ; } ; + } ; + } || { printf "\n### config.log content follows...\n\n" 1>&2 ; cat config.log ; false ; } + + - name: Compile bcftools + run: | + if [ '${{ matrix.use-configure }}' = 'use-configure' ] ; then + make -j5 + else + make -j5 ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags -Werror"} + fi + + - name: Check + run: | + if [ '${{ matrix.use-configure }}' = 'use-configure' ] ; then + make check BGZIP=$htsdir/bin/bgzip TABIX=$htsdir/bin/tabix + else + make check ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags -Werror"} + fi diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml new file mode 100644 index 000000000..2bef03887 --- /dev/null +++ b/.github/workflows/macos-build.yml @@ -0,0 +1,112 @@ +name: Mac OS CI +on: [push, pull_request] + +jobs: + build-macos: + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + # Fully declare each matrix entry here, as otherwise it's possible + # to get unexpected results due to the way the entries get expanded + # (See https://magmanu.github.io/blog/tech/matrices-github-actions/) + include: + # configure + - use-configure: use-configure + htssrc: hidden-htslib + sanitize: no-sanitize + + # make only + - use-configure: no-configure + htssrc: htslib + sanitize: no-sanitize + + # configure, sanitize + - use-configure: use-configure + htssrc: hidden-htslib + sanitize: sanitize + + defaults: + run: + working-directory: ./bcftools + + steps: + - name: Checkout + # This is actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false + path: bcftools + + - name: Install autotools + working-directory: . + run: | + brew install autoconf automake libtool + + - name: Clone htslib + working-directory: . + run: | + mkdir -p ${{ matrix.htssrc }} + htslib_pr=`git log -2 --format='%s' | sed -n 's/.*htslib#\([0-9]*\).*/\1/p'` + ./bcftools/.ci_helpers/clone ${GITHUB_REPOSITORY_OWNER} htslib ${{ matrix.htssrc }} ${GITHUB_HEAD_REF:-$GITHUB_REF_NAME} $htslib_pr + + - name: Set build options + run: | + cc='clang' + configure_opts='--enable-werror' + cflags='-g -O3 -arch arm64 -arch x86_64' + ldflags='-arch arm64 -arch x86_64' + + if [ '${{ matrix.sanitize }}' = 'sanitize' ] ; then + cflags="-g -Og -fsanitize=address,undefined -Wno-format-truncation -Wno-format-overflow -arch arm64 -arch x86_64 -DHTS_ALLOW_UNALIGNED=0" + ldflags='-fsanitize=address,undefined -arch arm64 -arch x86_64' + fi + + echo "cc=${cc}" >> "$GITHUB_ENV" + echo "configure_opts=${configure_opts}" >> "$GITHUB_ENV" + echo "cflags=${cflags}" >> "$GITHUB_ENV" + echo "ldflags=${ldflags}" >> "$GITHUB_ENV" + + - name: Build htslib + working-directory: ${{ matrix.htssrc }} + run: | + htsdir="`realpath ..`/installed-htslib" + echo "htsdir=${htsdir}" >> "$GITHUB_ENV" + + autoreconf -i + { ./configure --prefix="$htsdir" ${configure_opts} ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags"} ${ldflags:+LDFLAGS="$ldflags"} || + { cat config.log ; false ; } ; } && + make -j 5 && + make install + + - name: Configure bcftools + if: ${{ matrix.use-configure == 'use-configure' }} + run: | + autoreconf -i + + with_htslib="--with-htslib=$htsdir" + ldflags="${ldflags:+$ldflags }-Wl,-rpath,${htsdir}/lib" + + printf "\nRunning ./configure ${with_htslib} ${configure_opts}${cc:+ CC='$cc'}${cflags:+ CFLAGS='$cflags'}${ldflags:+ LDFLAGS='$ldflags'} ...\n\n" + + { ./configure $with_htslib ${configure_opts} ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags"} ${ldflags:+LDFLAGS="$ldflags"} && + { grep -qE 'CFLAGS *=.*-Werror' config.mk || + { printf "\nStopping as -Werror was not set.\n" 1>&2 ; false ; } ; + } ; + } || { printf "\n### config.log content follows...\n\n" 1>&2 ; cat config.log ; false ; } + + - name: Compile bcftools + run: | + if [ '${{ matrix.use-configure }}' = 'use-configure' ] ; then + make -j5 + else + make -j5 ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags -Werror"} + fi + + - name: Check + run: | + if [ '${{ matrix.use-configure }}' = 'use-configure' ] ; then + make check BGZIP=$htsdir/bin/bgzip TABIX=$htsdir/bin/tabix + else + make check ${cc:+CC="$cc"} ${cflags:+CFLAGS="$cflags -Werror"} + fi diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 49a14f37f..a413d620c 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -2,11 +2,12 @@ name: Windows/MinGW-W64 CI on: [push, pull_request] jobs: - build: + build-windows: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@v4 + # This is actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: ref: ${{ github.event.pull_request.head.sha }} - name: Set up MSYS2 MinGW-W64 @@ -23,6 +24,7 @@ jobs: mingw-w64-x86_64-zlib mingw-w64-x86_64-bzip2 mingw-w64-x86_64-xz + mingw-w64-x86_64-gsl - name: Clone htslib shell: msys2 {0} run: | @@ -41,7 +43,7 @@ jobs: export MSYSTEM=MINGW64 autoheader autoconf -Wno-syntax - ./configure --enable-werror + ./configure --enable-werror --enable-libgsl make -j4 - name: Check bcftools shell: msys2 {0} diff --git a/config.mk.in b/config.mk.in index 8b2715e5f..f49dd8bc0 100644 --- a/config.mk.in +++ b/config.mk.in @@ -61,10 +61,10 @@ PLUGIN_EXT = @PLUGIN_EXT@ @Hsource@HTSLIB_LIB = $(HTSLIB) $(HTSLIB_static_LIBS) @Hsource@HTSLIB_DLL = $(HTSDIR)/@HTSLIB_DLL@ @Hsource@HTSLIB_LDFLAGS = $(HTSLIB_static_LDFLAGS) -@Hsource@W32_PLUGIN_LIBS = libbcftools.a $(HTSLIB_DLL) $(ALL_LIBS) +@Hsource@W32_PLUGIN_LIBS = libbcftools.a $(HTSLIB_DLL) $(ALL_LIBS) $(GSL_LIBS) @Hsource@BGZIP = $(HTSDIR)/bgzip @Hsource@TABIX = $(HTSDIR)/tabix HTSLIB_CPPFLAGS = @HTSLIB_CPPFLAGS@ @Hinstall@HTSLIB_LDFLAGS = @HTSLIB_LDFLAGS@ @Hinstall@HTSLIB_LIB = -lhts -@Hinstall@W32_PLUGIN_LIBS = libbcftools.a $(HTSLIB_LDFLAGS) $(HTSLIB_LIB) $(ALL_LIBS) +@Hinstall@W32_PLUGIN_LIBS = libbcftools.a $(HTSLIB_LDFLAGS) $(HTSLIB_LIB) $(ALL_LIBS) $(GSL_LIBS) diff --git a/hex.h b/hex.h index 95210e3cf..bfb26b0f1 100644 --- a/hex.h +++ b/hex.h @@ -53,9 +53,9 @@ * If the buffer size is not sufficient, then the return value is the number of characters required for * buffer string, including the terminating null byte. */ -static inline size_t hex_uint64_t(uint64_t n, char *str) +static inline size_t hex_uint64_t(uint64_t n, char str[static 17]) { - return sprintf(str, "%016" PRIx64, n); + return snprintf(str, 17, "%016" PRIx64, n); } /** @brief Parses a 16 chars hexadecimal string and returns the code. diff --git a/m4/hts_prog_cc_warnings.m4 b/m4/hts_prog_cc_warnings.m4 index b1b365349..08f582c4f 100644 --- a/m4/hts_prog_cc_warnings.m4 +++ b/m4/hts_prog_cc_warnings.m4 @@ -65,75 +65,76 @@ dnl an option that includes a hash sign... # Tests for flags to enable C compiler warnings # GCC compatible AS_IF([test "x$GCC" = "xyes" && - "$CC" -c -Wall conftest.c > /dev/null 2>&1 && + $CC -c -Wall conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-Wall"], [hts_cv_prog_cc_warnings="-Wall -ansi -pedantic"]) ], # Sun Studio or Solaris C compiler - ["$CC" -V 2>&1 | $GREP -i -E "WorkShop|Sun C" > /dev/null 2>&1 && - "$CC" -c -v -Xc conftest.c > /dev/null 2>&1 && + [$CC -V 2>&1 | $GREP -i -E "WorkShop|Sun C" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -v -Xc conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-v"], [hts_cv_prog_cc_warnings="-v -Xc"]) ], # Digital Unix C compiler - ["$CC" -V 2>&1 | $GREP -i "Digital UNIX Compiler" > /dev/null 2>&1 && - "$CC" -c -verbose -w0 -warnprotos -std1 conftest.c > /dev/null 2>&1 && + [$CC -V 2>&1 | $GREP -i "Digital UNIX Compiler" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -verbose -w0 -warnprotos -std1 conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o], [dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-verbose -w0 -warnprotos"], [hts_cv_prog_cc_warnings="-verbose -w0 -warnprotos -std1"]) ], # C for AIX Compiler - ["$CC" 2>&1 | $GREP -i "C for AIX Compiler" > /dev/null 2>&1 && - "$CC" -c -qlanglvl=ansi -qinfo=all conftest.c > /dev/null 2>&1 && + [$CC 2>&1 | $GREP -i "C for AIX Compiler" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -qlanglvl=ansi -qinfo=all conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd"], [hts_cv_prog_cc_warnings="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd -qlanglvl=ansi"]) ], # IRIX C compiler - ["$CC" -version 2>&1 | $GREP -i "MIPSpro Compilers" > /dev/null 2>&1 && - "$CC" -c -fullwarn -ansi -ansiE conftest.c > /dev/null 2>&1 && + [$CC -version 2>&1 | $GREP -i "MIPSpro Compilers" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -fullwarn -ansi -ansiE conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-fullwarn"], [hts_cv_prog_cc_warnings="-fullwarn -ansi -ansiE"]) ], # HP-UX C compiler - [what "$CC" 2>&1 | $GREP -i "HP C Compiler" > /dev/null 2>&1 && - "$CC" -c -Aa +w1 conftest.c > /dev/null 2>&1 && + [what "$CC" 2>&1 | $GREP -i "HP C Compiler" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -Aa +w1 conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="+w1"], [hts_cv_prog_cc_warnings="+w1 -Aa"]) ], # The NEC SX series (Super-UX 10) C compiler - ["$CC" -V 2>&1 | $GREP "/SX" > /dev/null 2>&1 && - "$CC" -c -pvctl[,]fullmsg -Xc conftest.c > /dev/null 2>&1 && + [$CC -V 2>&1 | $GREP "/SX" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -pvctl[,]fullmsg -Xc conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[ AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-pvctl[,]fullmsg"], [hts_cv_prog_cc_warnings="-pvctl[,]fullmsg -Xc"]) ], # The Cray C compiler (Unicos) - ["$CC" -V 2>&1 | $GREP -i "Cray" > /dev/null 2>&1 && - "$CC" -c -h msglevel_2 conftest.c > /dev/null 2>&1 && + [$CC -V 2>&1 | $GREP -i "Cray" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -h msglevel_2 conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl AS_IF([test "x$ansi" = "x"], [hts_cv_prog_cc_warnings="-h#msglevel_2"], [hts_cv_prog_cc_warnings="-h#msglevel_2,conform"]) ], # The Tiny C Compiler - ["$CC" -v 2>&1 | $GREP "tcc version" > /dev/null && - "$CC" -Wall -c conftest.c > /dev/null 2>&1 && + [$CC -v 2>&1 | $GREP "tcc version" >&AS_MESSAGE_LOG_FD && + $CC -Wall -c conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[dnl hts_cv_prog_cc_warnings="-Wall" ]) rm -f conftest.* + rm -rf conftest.dSYM ]) ]) @@ -183,19 +184,20 @@ EOF # Tests for flags to make the C compiler treat warnings as errors # GCC compatible [test "x$GCC" = "xyes" && - "$CC" -c -Werror conftest.c > /dev/null 2>&1 && + $CC -c -Werror conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[hts_cv_prog_cc_werror="-Werror"], # Sun Studio or Solaris C compiler - ["$CC" -V 2>&1 | $GREP -i -E "WorkShop|Sun C" > /dev/null 2>&1 && - "$CC" -c -errwarn=%all conftest.c > /dev/null 2>&1 && + [$CC -V 2>&1 | $GREP -i -E "WorkShop|Sun C" >&AS_MESSAGE_LOG_FD 2>&1 && + $CC -c -errwarn=%all conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[hts_cv_prog_cc_werror="-errwarn=%all"], # The Tiny C Compiler - ["$CC" -v 2>&1 | $GREP "tcc version" > /dev/null && - "$CC" -Wall -c conftest.c > /dev/null 2>&1 && + [$CC -v 2>&1 | $GREP "tcc version" >&AS_MESSAGE_LOG_FD && + $CC -Wall -c conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && test -f conftest.o],[hts_cv_prog_cc_werror="-Werror"] dnl TODO: Add more compilers ) rm -f conftest.* + rm -rf conftest.dSYM ]) ]) AS_IF([test "x$hts_cv_prog_cc_werror" != x],[ diff --git a/plugins/add-variantkey.c b/plugins/add-variantkey.c index af9efd7a8..5bc8add52 100644 --- a/plugins/add-variantkey.c +++ b/plugins/add-variantkey.c @@ -76,7 +76,7 @@ bcf1_t *process(bcf1_t *rec) char rsid[9]; char *ptr = rec->d.id; ptr += 2; // remove 'rs' - sprintf(rsid, "%08" PRIx32, (uint32_t)strtoul(ptr, NULL, 10)); + snprintf(rsid, sizeof(rsid), "%08" PRIx32, (uint32_t)strtoul(ptr, NULL, 10)); bcf_update_info_string(out_hdr, rec, "RSX", rsid); return rec; } diff --git a/plugins/vcf2table.c b/plugins/vcf2table.c index 63ea58bca..85c1447e0 100644 --- a/plugins/vcf2table.c +++ b/plugins/vcf2table.c @@ -611,8 +611,8 @@ static int findContigs(bcf_hdr_t* hdr_in, const char* ctg1a, uint64_t len1, char ctg1b[10]; char ctg2b[10]; // try to add a 'chr' prefix to the chromosome name - sprintf(ctg1b, "chr%s", ctg1a); - sprintf(ctg2b, "chr%s", ctg2a); + snprintf(ctg1b, sizeof(ctg1b), "chr%s", ctg1a); + snprintf(ctg2b, sizeof(ctg2b), "chr%s", ctg2a); int found = 0; int i, n_contigs = hdr_in->n[BCF_DT_CTG]; for (i = 0; i < n_contigs && found < 2; i++) { diff --git a/test/test-regidx.c b/test/test-regidx.c index 8ec261d61..25242aea6 100644 --- a/test/test-regidx.c +++ b/test/test-regidx.c @@ -282,20 +282,20 @@ void test_explicit(char *tgt, char *qry, char *exp) regidx_destroy(idx); } -void create_line_bed(char *line, char *chr, int start, int end) +void create_line_bed(char *line, size_t len, char *chr, int start, int end) { - sprintf(line,"%s\t%d\t%d\n",chr,start-1,end); + snprintf(line,len,"%s\t%d\t%d\n",chr,start-1,end); } -void create_line_tab(char *line, char *chr, int start, int end) +void create_line_tab(char *line, size_t len, char *chr, int start, int end) { - sprintf(line,"%s\t%d\t%d\n",chr,start,end); + snprintf(line,len,"%s\t%d\t%d\n",chr,start,end); } -void create_line_reg(char *line, char *chr, int start, int end) +void create_line_reg(char *line, size_t len, char *chr, int start, int end) { - sprintf(line,"%s:%d-%d\n",chr,start,end); + snprintf(line,len,"%s:%d-%d\n",chr,start,end); } -typedef void (*set_line_f)(char *line, char *chr, int start, int end); +typedef void (*set_line_f)(char *line, size_t len, char *chr, int start, int end); void test(set_line_f set_line, regidx_parse_f parse) { @@ -307,17 +307,17 @@ void test(set_line_f set_line, regidx_parse_f parse) for (i=1; i 25)) { - return sprintf(chrom, "NA"); + return snprintf(chrom, 4, "NA"); } if (code < 23) { - return sprintf(chrom, "%" PRIu8, code); + return snprintf(chrom, 4, "%" PRIu8, code); } static const char *map[] = {"X", "Y", "MT"}; - return sprintf(chrom, "%s", map[(code - 23)]); + return snprintf(chrom, 4, "%s", map[(code - 23)]); } static inline uint32_t encode_base(const uint8_t c) @@ -593,7 +593,7 @@ static inline int8_t compare_variantkey_chrom_pos(uint64_t vka, uint64_t vkb) * If the buffer size is not sufficient, then the return value is the number of characters required for * buffer string, including the terminating null byte. */ -static inline size_t variantkey_hex(uint64_t vk, char *str) +static inline size_t variantkey_hex(uint64_t vk, char str[static 17]) { return hex_uint64_t(vk, str); } diff --git a/vcfmerge.c b/vcfmerge.c index e7af6e5c0..b5f44d083 100644 --- a/vcfmerge.c +++ b/vcfmerge.c @@ -692,7 +692,7 @@ void merge_headers(bcf_hdr_t *hw, const bcf_hdr_t *hr, const char *clash_prefix, int len = strlen(name) + strlen(clash_prefix) + 1; char *tmp = (char*) malloc(sizeof(char)*(len+1)); - sprintf(tmp,"%s:%s",clash_prefix,name); + snprintf(tmp,len + 1,"%s:%s",clash_prefix,name); free(rmme); rmme = name = tmp; } diff --git a/version.c b/version.c index 28b2ec74c..4ebf220f3 100644 --- a/version.c +++ b/version.c @@ -91,7 +91,7 @@ const char *hts_bcf_wmode2(int file_type, const char *fname) return hts_bcf_wmode(file_type); } -void set_wmode(char dst[8], int file_type, const char *fname, int clevel) +void set_wmode(char dst[static 8], int file_type, const char *fname, int clevel) { const char *ret = NULL; const char *end = fname ? strstr(fname, HTS_IDX_DELIM) : NULL; @@ -108,10 +108,10 @@ void set_wmode(char dst[8], int file_type, const char *fname, int clevel) if ( strchr(ret,'v') || strchr(ret,'u') ) error("Error: compression level (%d) cannot be set on uncompressed streams (%s)\n",clevel,fname); len = strlen(ret); if ( len>6 ) error("Fixme: %s\n", ret); - sprintf(dst, "%s%d", ret, clevel); + snprintf(dst, 8, "%s%d", ret, clevel); } else - strcpy(dst, ret); + snprintf(dst, 8, "%s", ret); } int parse_overlap_option(const char *arg) @@ -169,8 +169,9 @@ int init_index2(htsFile *fh, bcf_hdr_t *hdr, const char *fname, size_t l = strlen(*idx_fname); if ( l >= 4 && strcmp(*idx_fname + l - 4, ".tbi")==0 ) min_shift = 0; } else { - if ( !(*idx_fname = malloc(strlen(fname)+6)) ) return -1; - sprintf(*idx_fname, "%s.%s", fname, idx_suffix); + size_t len = strlen(fname)+6; + if ( !(*idx_fname = malloc(len)) ) return -1; + snprintf(*idx_fname, len, "%s.%s", fname, idx_suffix); } if ( bcf_idx_init(fh, hdr, min_shift, *idx_fname) < 0 ) return -1;