From ade0e24dbb960aa79b0276557cd36c50efca14ae Mon Sep 17 00:00:00 2001 From: Sandra Bohn Date: Wed, 31 Dec 2025 23:12:14 -0500 Subject: [PATCH] fix: munmap_chunk(): invalid pointer --- pbwt/Makefile | 5 +++- pbwt/pbwtCore.c | 2 +- pbwt/pbwtHtslib.c | 6 ++++ pbwt/pbwtMatchTargets.c | 65 ++++++++++++++++++++++++++--------------- pbwt/utils.c | 2 ++ 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/pbwt/Makefile b/pbwt/Makefile index a9a8a7b..da3ec2c 100644 --- a/pbwt/Makefile +++ b/pbwt/Makefile @@ -1,4 +1,7 @@ -CFLAGS= -g -O3 --signed-char +CFLAGS= -O3 --signed-char +ifeq ($(DEBUG), 1) +CFLAGS += -g -fsanitize=address +endif CPPFLAGS=-I$(HTSDIR) HTSLIB=$(HTSDIR)/libhts.a LDLIBS=-pthread $(HTSLIB) -lz -lm -lbz2 -llzma -lcurl -lzip diff --git a/pbwt/pbwtCore.c b/pbwt/pbwtCore.c index 2c3d2ed..8adee1b 100644 --- a/pbwt/pbwtCore.c +++ b/pbwt/pbwtCore.c @@ -354,7 +354,7 @@ void pbwtCursorToAFend(PbwtCursor * u, PBWT * p) { PBWT * pbwtFilterSites(PBWT * pOld, Array filter) { /* Provide array of 0s and 1s to filter sites from pbwt*/ if (arrayMax(filter) != pOld->N) die("Filter is not the same size as pbwt"); - int i, j, newN; + int i, j, newN = 0; for (j = 0; j < pOld->N; ++j) newN += * arrp(filter, j, int); if (newN == pOld->N) return pOld; diff --git a/pbwt/pbwtHtslib.c b/pbwt/pbwtHtslib.c index e8d79b6..260da1f 100644 --- a/pbwt/pbwtHtslib.c +++ b/pbwt/pbwtHtslib.c @@ -147,8 +147,14 @@ PBWT *pbwtReadVcfGT (char *filename) { Site *s = arrayp(p->sites, p->N++, Site); s->x = pos; s->varD = variation(p, REF, ALT); + + /* free ALT string if it was allocated */ + if (!no_alt && ALT) { free(ALT); ALT = NULL; } } + /* free REF string after processing all alleles for this line */ + if (REF) { free(REF); REF = NULL; } + if (nCheckPoint && !(p->N % nCheckPoint)) pbwtCheckPoint (u, p) ; } pbwtCursorToAFend (u, p) ; diff --git a/pbwt/pbwtMatchTargets.c b/pbwt/pbwtMatchTargets.c index eed58e9..e3aa2d7 100644 --- a/pbwt/pbwtMatchTargets.c +++ b/pbwt/pbwtMatchTargets.c @@ -21,8 +21,8 @@ typedef struct TargetMatchArrayStruct { TargetMatchArray; static void clearMatchArray(MatchArray * ma) { - if (ma -> haplotypes) free(ma -> haplotypes); - if (ma -> lengths) free(ma -> lengths); + if (ma -> haplotypes) free(ma -> haplotypes); ma -> haplotypes = NULL; + if (ma -> lengths) free(ma -> lengths); ma -> lengths = NULL; } static void TargetMatchArrayInit(TargetMatchArray * tma, int N, int M, int fl) { @@ -37,6 +37,8 @@ static void TargetMatchArrayInit(TargetMatchArray * tma, int N, int M, int fl) { ma = arrayp(tma -> matchArrays, i, MatchArray); ma -> fl = fl; ma -> N = 0; + ma -> haplotypes = NULL; + ma -> lengths = NULL; } } @@ -53,7 +55,7 @@ typedef struct SparseCscStruct { // store data for csc matrix format // int M; /* number of rows*/ int N; /* number of columns*/ - int nnz; /* number of values */ + int nnz; /* number of non-zero values */ int * data; /* array of int, length nnz */ int * indices; /* array of int, length nnz */ int * indptr; /* array of int, length N + 1 */ @@ -64,11 +66,19 @@ static SparseCsc * SparseCscCreate(int M, int N, int nnz) { SparseCsc * csc = myalloc(1, SparseCsc); csc -> M = M; csc -> N = N; - csc -> nnz = nnz; + csc -> nnz = nnz; /* number of non-zero elements */ if (nnz > 0) { csc -> data = myalloc(nnz, int); csc -> indices = myalloc(nnz, int); + for (int i = 0; i < nnz; i++) { + csc -> data[i] = 0; + csc -> indices[i] = 0; + } + } else { + csc -> data = NULL; + csc -> indices = NULL; } + csc -> indptr = NULL; return csc; } @@ -87,36 +97,41 @@ static void addMatch(int haplotype, int length, int var, TargetMatchArray * tma) MatchArray * ma = arrayp(tma -> matchArrays, var, MatchArray); int j = ma -> N - 1; + int oldN = ma -> N; if (ma -> N < ma -> fl) ma -> N++; int * haplotypes = myalloc(ma -> N, int); int * lengths = myalloc(ma -> N, int); - while (j >= 0 && ma -> lengths[j] < length) { - if (j + 1 < ma -> N) { - lengths[j + 1] = ma -> lengths[j]; - haplotypes[j + 1] = ma -> haplotypes[j]; + if (oldN > 0) { + while (j >= 0 && ma -> lengths[j] < length) { /* shift shorter matches to the right */ + if (j + 1 < ma -> N) { + lengths[j + 1] = ma -> lengths[j]; + haplotypes[j + 1] = ma -> haplotypes[j]; + } + j--; } - j--; - } - while (j >= 0 && ma -> lengths[j] == length && tma -> hap_totals[ma -> haplotypes[j]] <= total) { - if (j + 1 < ma -> N) { - lengths[j + 1] = ma -> lengths[j]; - haplotypes[j + 1] = ma -> haplotypes[j]; + while (j >= 0 && ma -> lengths[j] == length && tma -> hap_totals[ma -> haplotypes[j]] <= total) { + if (j + 1 < ma -> N) { + lengths[j + 1] = ma -> lengths[j]; + haplotypes[j + 1] = ma -> haplotypes[j]; + } + j--; } - j--; } - if (j + 1 < ma -> N) { + if (j + 1 < ma -> N) { /* if there is space in the array, add the new match */ lengths[j + 1] = length; haplotypes[j + 1] = haplotype; } - while (j >= 0) { - lengths[j] = ma -> lengths[j]; - haplotypes[j] = ma -> haplotypes[j]; - j--; + if (oldN > 0) { + while (j >= 0) { /* copy remaining matches to the new array */ + lengths[j] = ma -> lengths[j]; + haplotypes[j] = ma -> haplotypes[j]; + j--; + } + clearMatchArray(ma); } - clearMatchArray(ma); - ma -> lengths = lengths; - ma -> haplotypes = haplotypes; + ma -> lengths = lengths; /* update the match array */ + ma -> haplotypes = haplotypes; /* update the match array */ } static SparseCsc * targetMatchesToCsc(TargetMatchArray * tma, int N, int M) { @@ -229,6 +244,8 @@ static void write_npz(char * prefix, TargetMatchArray * tma, int N, int M) { snprintf(tmp_name, 84, "parallel_haploid_mat_%s.npz", prefix); writeSparseCsc(tmp_name, csc); SparseCscDestroy(csc); + /* prefix is allocated by get_prefix and should be freed here */ + if (prefix) free(prefix); } static void pbwtMatchTargets(PBWT * p, int minL, int nRefHaps) { @@ -290,7 +307,7 @@ static void pbwtMatchTargets(PBWT * p, int minL, int nRefHaps) { free(refHaps); free(targetHaps); pbwtCursorForwardsReadAD(u, var); - if (var % 100 == 0) printProgress((double) var / nVar); + if (var % 1000 == 0) printProgress((double) var / nVar); } printProgress(1.0); printf("\n [pbwt]: Writing output\n"); diff --git a/pbwt/utils.c b/pbwt/utils.c index b4b9d1a..24cd5cc 100644 --- a/pbwt/utils.c +++ b/pbwt/utils.c @@ -117,8 +117,10 @@ char *fgetword (FILE *f) // pass NULL to free alloced memory { ++cp ; ++n ; if (n >= bufSize) { bufSize *= 2 ; + long offset = cp - buf ; /* save offset before realloc */ if (!(buf = (char*) realloc (buf, bufSize))) die ("fgetword realloc failure requesting %d bytes", bufSize) ; + cp = buf + offset ; /* restore pointer after realloc */ } } else