e6b0dc7877ae4b24f56682885e03263fd2da3582 braney Tue Aug 18 11:37:04 2026 -0700 lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123 diff --git src/hg/hgc/bamClick.c src/hg/hgc/bamClick.c index 76e73c81998..7d18f661886 100644 --- src/hg/hgc/bamClick.c +++ src/hg/hgc/bamClick.c @@ -1,27 +1,28 @@ /* bamClick - handler for alignments in BAM format (produced by MAQ, * BWA and some other short-read alignment tools). */ /* Copyright (C) 2014 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "hash.h" #include "hdb.h" #include "hgBam.h" #include "hgc.h" #include "hui.h" +#include "htmshell.h" #include "knetUdc.h" #include "udc.h" #include "chromAlias.h" #include "hgBam.h" #include "hgConfig.h" struct bamTrackData { int itemStart; char *itemName; struct hash *pairHash; boolean foundIt; }; @@ -120,31 +121,32 @@ puts("<BR>"); if (bamIsRc(bam)) printf("<em>Note: although the read was mapped to the reverse strand of the genome, " "the sequence and CIGAR in BAM are relative to the forward strand.</em><BR>\n"); puts("<BR>"); struct dnaSeq *genoSeq = hChromSeq(database, seqName, tStart, tEnd); char *qSeq = bamGetQuerySequence(bam, FALSE); if (core->l_qseq > 5000) printf("<B>Alignment not shown, query sequence is %d bp long > 5000bp</B><BR>\n", core->l_qseq); else { if (isNotEmpty(qSeq) && !sameString(qSeq, "*")) { char *qSeq = NULL; struct ffAli *ffa = bamToFfAli(bam, genoSeq, tStart, useStrand, &qSeq); - printf("<B>Alignment of %s to %s:%d-%d%s:</B><BR>\n", itemName, + // the read name comes straight out of the BAM file, so encode it before output + printf("<B>Alignment of %s to %s:%d-%d%s:</B><BR>\n", htmlEncode(itemName), seqName, tStart+1, tEnd, (isRc ? " (reverse complemented)" : "")); ffShowSideBySide(stdout, ffa, qSeq, 0, genoSeq->dna, tStart, tLength, 0, tLength, 8, isRc, FALSE); } } if (!skipQualityScore && core->l_qseq > 0) { if (core->l_qseq > 5000) { printf("<B>Sequence quality not shown, query sequence %d bp long > 5000bp</B><BR>\n", core->l_qseq); } else { printf("<B>Sequence quality scores:</B><BR>\n<TT><TABLE><TR>\n"); @@ -192,57 +194,57 @@ puts(rightSeq); puts("</TT></PRE>"); } } static void bamPairDetails(const bam1_t *leftBam, const bam1_t *rightBam) /* Print out details for paired-end reads. */ { if (leftBam && rightBam) { const bam1_core_t *leftCore = &leftBam->core, *rightCore = &rightBam->core; int leftLength = bamGetTargetLength(leftBam), rightLength = bamGetTargetLength(rightBam); int start = min(leftCore->pos, rightCore->pos); int end = max(leftCore->pos+leftLength, rightCore->pos+rightLength); char *itemName = bam1_qname(leftBam); - printf("<B>Paired read name:</B> %s<BR>\n", itemName); + printf("<B>Paired read name:</B> %s<BR>\n", htmlEncode(itemName)); printPosOnChrom(seqName, start, end, NULL, FALSE, itemName); puts("<P>"); } showOverlap(leftBam, rightBam); printf("<TABLE><TR><TD valign=top><H4>Left end read</H4>\n"); singleBamDetails(leftBam); printf("</TD><TD valign=top><H4>Right end read</H4>\n"); singleBamDetails(rightBam); printf("</TD></TR></TABLE>\n"); } static int oneBam(const bam1_t *bam, void *data, bam_hdr_t *header) /* This is called on each record retrieved from a .bam file. */ { const bam1_core_t *core = &bam->core; if (core->flag & BAM_FUNMAP) return 0; struct bamTrackData *btd = (struct bamTrackData *)data; if (sameString(bam1_qname(bam), btd->itemName)) { btd->foundIt = TRUE; if (btd->pairHash == NULL || (core->flag & BAM_FPAIRED) == 0) { if (core->pos == btd->itemStart) { - printf("<B>Read name:</B> %s<BR>\n", btd->itemName); + printf("<B>Read name:</B> %s<BR>\n", htmlEncode(btd->itemName)); singleBamDetails(bam); } } else { bam1_t *firstBam = (bam1_t *)hashFindVal(btd->pairHash, btd->itemName); if (firstBam == NULL) hashAdd(btd->pairHash, btd->itemName, bamClone(bam)); else { bamPairDetails(firstBam, bam); hashRemove(btd->pairHash, btd->itemName); } } }