90dc829b2d87b15c4fc4bbc1d814f83d1274ef52 braney Fri Sep 4 14:00:05 2026 -0700 Pass element counts, not byte sizes, to the chop routines chopByWhite, chopString and chopByChar take their last argument as a count of elements in the output array. Fifteen call sites passed sizeof(array) instead. For an array of pointers that is eight times the real capacity on a 64-bit build, so the chop could write well past the end of the array. Switched each to ArraySize(). Behaviour is unchanged for any input that already fitted in the array. Built clean: lib, hg/lib, hg/hgTracks, hg/hgc, hg/utils/hubCheck, utils/bedScore, parasol/lib, parasol/parasol. Three directories do not build, but they fail the same way without this change: checkExp is missing htslib link flags, and cgapSageFind and affySplice have stale prototypes in files this does not touch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> diff --git src/hg/makeDb/outside/cgapSage/cgapSageFind/uninteresting.c src/hg/makeDb/outside/cgapSage/cgapSageFind/uninteresting.c index cb00743c8c3..f0acf410875 100644 --- src/hg/makeDb/outside/cgapSage/cgapSageFind/uninteresting.c +++ src/hg/makeDb/outside/cgapSage/cgapSageFind/uninteresting.c @@ -1,116 +1,116 @@ /* Copyright (C) 2007 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "obscure.h" #include "dystring.h" #include "portable.h" #include "linefile.h" #include "hash.h" #include "dnaLoad.h" #include "bed.h" #include "snp.h" #include "cgapSage/cgapSage.h" #include "cgapSage/cgapSageLib.h" #include "cgapSageFind.h" int slPairValCmpReverse(const void *va, const void *vb) /* Compare two slPairs for sorting in reverse order on */ /* the assumption that the stuff in the ->vals are ints. */ { const struct slPair *a = *((struct slPair **)va); const struct slPair *b = *((struct slPair **)vb); int aVal = ptToInt(a->val); int bVal = ptToInt(b->val); return bVal - aVal; } void sortSlPairList(struct hashEl *listEl) /* To be called by hashTraverseEls() so sort each list in */ /* the hash. */ { struct slPair **pPairList = (struct slPair **)&listEl->val; slSort(pPairList, slPairValCmpReverse); } void addFreqToHash(struct hash *freqHash, char *tag, char *id, int val) /* Add the frequency to the end of the list in the hash. */ /* This is done at each line in the frequencies file. */ { struct hashEl *el = hashStore(freqHash, tag); struct slPair *newOne; struct slPair **pList = (struct slPair **)&el->val; AllocVar(newOne); newOne->name = cloneString(id); newOne->val = intToPt(val); slAddHead(pList, newOne); } struct hash *getFreqHash(char *freqFile) /* Read the frequency file in, and store it in a hash and return that. */ { struct hash *freqHash = newHash(23); struct lineFile *lf = lineFileOpen(freqFile, TRUE); char *words[3]; /* Assume there's a header and skip it. */ lineFileSkip(lf, 1); while (lineFileRowTab(lf, words)) { int val; lineFileNeedFullNum(lf, words, 1); lineFileNeedFullNum(lf, words, 2); val = (int)sqlUnsigned(words[2]); addFreqToHash(freqHash, words[0], words[1], val); } lineFileClose(&lf); hashTraverseEls(freqHash, sortSlPairList); return freqHash; } struct hash *getTotTagsHash(char *libsFile) /* Read in the library file and hash up the total tags. */ { struct hash *totTagsHash = newHash(9); struct cgapSageLib *libs = cgapSageLibLoadAllByTab(libsFile); struct cgapSageLib *lib; for (lib = libs; lib != NULL; lib = lib->next) { char buf[16]; safef(buf, sizeof(buf), "%d", lib->libId); hashAddInt(totTagsHash, buf, (int)lib->totalTags); } cgapSageLibFreeList(&libs); return totTagsHash; } void hashElSlPairListFree(struct hashEl **pEl) /* Free up the list in one of the hashEls. */ { struct slPair **pList = (struct slPair **)pEl; slPairFreeList(pList); } int pickApartSeqName(char **pName) /* Change /path/chr:start-end into chr and return start. */ { char *name; char *words[3]; int numWords = 0; char *chrom, *range; int skip = 0; int start = 0; if (!pName || ((name = *pName) == NULL)) return 0; -numWords = chopByChar(name, ':', words, sizeof(words)); +numWords = chopByChar(name, ':', words, ArraySize(words)); if (numWords == 3) skip = 1; chrom = words[0 + skip]; *pName = chrom; range = words[1 + skip]; if (numWords > 1) { chopPrefixAt(range, '-'); start = sqlUnsigned(range); } return start; }