From d7604b4648e8a3297de5fa66764ffb1150a29f3b Mon Sep 17 00:00:00 2001 From: Zilong-Li Date: Sun, 7 Apr 2024 09:07:03 +0200 Subject: [PATCH] fix asan issues. safe to use writeLine and addLine --- test/Makefile | 10 +++++----- test/bcf-writer.cpp | 11 +---------- vcfpp.h | 23 +++++++++++------------ 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/test/Makefile b/test/Makefile index 1f4fa9d..c09983b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,12 +1,12 @@ -# detect OS architecture and add flags -CXX = g++ -# CXXFLAGS = -std=c++11 -Wall -g -fsanitize=address -CXXFLAGS = -std=c++11 -Wall HTSINC = /usr/local/include HTSLIB = /usr/local/lib +# detect OS architecture and add flags +CXX = g++ +CXXFLAGS = -std=c++11 -Wall -fsanitize=address +# CXXFLAGS = -std=c++11 -Wall LDFLAGS = -L$(HTSLIB) -Wl,-rpath,$(HTSLIB) LIBS = -lhts -lz -lm -lbz2 -llzma -lcurl -lpthread -INC = -I. -I.. +INC = -I. -I.. -I${HTSINC} OBJS = test-main.o bcf-variant.o bcf-reader.o bcf-writer.o example.o diff --git a/test/bcf-writer.cpp b/test/bcf-writer.cpp index 58d9e4a..8f68655 100644 --- a/test/bcf-writer.cpp +++ b/test/bcf-writer.cpp @@ -28,16 +28,7 @@ TEST_CASE("Write BCF with custome header and variants", "[bcf-writer]") bw.header.addContig("chr20"); bw.header.addSample("NA12878"); bw.writeLine("chr20\t2006060\trs146931526\tG\tC\t100\tPASS\tAF=0.000998403\tGT\t1|0"); -} - -TEST_CASE("Write VCF with custome header and variants", "[bcf-writer]") -{ - BcfWriter bw("test.vcf", "VCF4.3"); - bw.header.addFORMAT("GT", "1", "String", "Genotype"); - bw.header.addINFO("AF", "A", "Float", "Estimated allele frequency in the range (0,1)"); - bw.header.addContig("chr20"); - bw.header.addSample("NA12878"); - bw.writeLine("chr20\t2006060\trs146931526\tG\tC\t100\tPASS\tAF=0.000998403\tGT\t1|0"); + bw.close(); } diff --git a/vcfpp.h b/vcfpp.h index 5fbbc26..d865f8a 100644 --- a/vcfpp.h +++ b/vcfpp.h @@ -2,7 +2,7 @@ * @file https://github.com/Zilong-Li/vcfpp/vcfpp.h * @author Zilong Li * @email zilong.dk@gmail.com - * @version v0.3.4 + * @version v0.3.6 * @breif a single C++ file for manipulating VCF * Copyright (C) 2022-2023.The use of this code is governed by the LICENSE file. ******************************************************************************/ @@ -876,10 +876,10 @@ class BcfRecord /** @brief add one variant record from given string*/ void addLineFromString(const std::string & vcfline) { - std::vector str(vcfline.begin(), vcfline.end()); - str.push_back('\0'); // don't forget string has no \0; - kstring_t s = {vcfline.length(), vcfline.length(), &str[0]}; // kstring - ret = vcf_parse(&s, header.hdr, line.get()); + kstring_t s = {0, 0, NULL}; + kputsn(vcfline.c_str(), vcfline.length(), &s); + ret = vcf_parse1(&s, header.hdr, line.get()); + free(s.s); if(ret > 0) throw std::runtime_error("error parsing: " + vcfline + "\n"); if(line->errcode == BCF_ERR_CTG_UNDEF) { @@ -892,7 +892,6 @@ class BcfRecord if(ret < 0) throw std::runtime_error("error adding contig " + contig + " to header.\n"); ret = bcf_hdr_sync(header.hdr); } - free(s.s); } /** @brief if all samples have non missing values for the tag in FORMAT */ @@ -1434,7 +1433,7 @@ class BcfReader int slen = tbx_itr_next(fp.get(), tidx, itr, &s); if(slen > 0) { - ret = vcf_parse(&s, r.header.hdr, r.line.get()); // ret > 0, error + ret = vcf_parse1(&s, r.header.hdr, r.line.get()); // ret > 0, error bcf_unpack(r.line.get(), BCF_UN_ALL); } return (ret <= 0) && (slen > 0); @@ -1574,14 +1573,14 @@ class BcfWriter if(header.hdr == NULL) throw std::runtime_error("couldn't copy the header from another vcf.\n"); } - /// write a string to a vcf line + /// copy a string to a vcf line void writeLine(const std::string & vcfline) { if(!isHeaderWritten && !writeHeader()) throw std::runtime_error("could not write header\n"); - std::vector str(vcfline.begin(), vcfline.end()); - str.push_back('\0'); // don't forget string has no \0; - kstring_t s = {vcfline.length(), vcfline.length(), &str[0]}; // kstring - ret = vcf_parse(&s, header.hdr, b.get()); + kstring_t s = {0, 0, NULL}; + kputsn(vcfline.c_str(), vcfline.length(), &s); + ret = vcf_parse1(&s, header.hdr, b.get()); + free(s.s); if(ret > 0) throw std::runtime_error("error parsing: " + vcfline + "\n"); if(b->errcode == BCF_ERR_CTG_UNDEF) {