83c50d3af3614ea3832bbea7c95488296d0b392e jcasper Mon Nov 4 07:17:51 2024 -0800 When parsing a BED, the space allocated for expScores should be at least expCount entries, even if that's greater than the number of exons. #12101 diff --git src/lib/basicBed.c src/lib/basicBed.c index 3251f15..b39de3f 100644 --- src/lib/basicBed.c +++ src/lib/basicBed.c @@ -1553,30 +1553,41 @@ else { lineFileAllInts(lf, row, 8, &bed->itemRgb, FALSE, 4, "integer", FALSE); } } int tempArraySize = 1; // How big arrays are below if (bedFieldCount > 9) { lineFileAllInts(lf, row, 9, &bed->blockCount, FALSE, 4, "integer", FALSE); if (!(bed->blockCount >= 1)) lineFileAbort(lf, "Expecting blockCount (%d) to be 1 or more.", bed->blockCount); tempArraySize = bed->blockCount; } +if (bedFieldCount > 12) + // get the microarray/colored-exon field count; we might need to increase tempArraySize + // if expCount > blockCount, since the allocated array is used for both exons and expScores + { + lineFileAllInts(lf, row, 12, &bed->expCount, TRUE, 4, "integer", TRUE); + if (!(bed->expCount >= 1)) + lineFileAbort(lf, "Expecting expCount (%d) to be 1 or more.", bed->expCount); + if (!isCt && bed->expCount > tempArraySize) + tempArraySize = bed->expCount; + } + // this memory never gets freed, but tempArraySize can be huge so // we can't allocate it off the stack and we don't want to be // allocating and freeing it millions of times on huge beds. char *allocatedMem = getScratchMem(3 * tempArraySize * sizeof(int) + tempArraySize * sizeof(float)); int *tempBlockSizes = (int *)allocatedMem; int *tempChromStarts = (int *)&allocatedMem[tempArraySize * sizeof(int)]; int *tempExpIds = (int *)&allocatedMem[2*tempArraySize * sizeof(int)]; float *tempExpScores = (float *)&allocatedMem[3*tempArraySize * sizeof(int)]; if (bedFieldCount > 10) { if (isCt) { AllocArray(bed->blockSizes,bed->blockCount+1); // having +1 allows us to detect incorrect size count = lineFileAllIntsArray(lf, row, 10, bed->blockSizes, bed->blockCount+1, TRUE, 4, "integer", TRUE); @@ -1643,33 +1654,30 @@ if (allow1bpOverlap) fudge = -1; if (!(chromStarts[i] >= chromStarts[i-1] + blockSizes[i-1] + fudge)) lineFileAbort(lf, "BED blocks must be in ascending order without overlap. Blocks %d and %d overlap.", i-1, i); } // last block-end must match chromEnd i = bed->blockCount-1; if ((bed->chromStart + chromStarts[i] + blockSizes[i]) != bed->chromEnd) lineFileAbort(lf, BAD_BLOCKS); } if (bedFieldCount > 12) // get the microarray/colored-exon fields { - lineFileAllInts(lf, row, 12, &bed->expCount, TRUE, 4, "integer", TRUE); - if (!(bed->expCount >= 1)) - lineFileAbort(lf, "Expecting expCount (%d) to be 1 or more.", bed->expCount); if (isCt) { AllocArray(bed->expIds,bed->expCount+1); // having +1 allows us to detect incorrect size count = lineFileAllIntsArray(lf, row, 13, bed->expIds, bed->expCount+1, TRUE, 4, "integer", TRUE); } else { count = lineFileAllIntsArray(lf, row, 13, tempExpIds, tempArraySize, TRUE, 4, "integer", TRUE); } if (count != bed->expCount) lineFileAbort(lf, "expecting %d elements in expIds list (bed field 14)", bed->expCount); if (bedFieldCount == 15) { if (isCt) {