cec5ead054791f2a6601f308a56d280c08bd8ef7 braney Fri Sep 4 13:32:36 2026 -0700 quickLift: do not take the lift path on half a pair of settings A hub can set quickLiftDb without setting quickLiftUrl, and nothing filters hub trackDb settings. The alignment loaders gated on quickLiftDb alone, so such a stanza took the lift path with no chain file and hgTracks died in endsWith(NULL, ".bb") from bigChainGetLinkFile, by way of quickLiftLoadChains. Verified: SIGSEGV in strlen from common.c:1653, page truncated mid-HTML. This is reachable on a production browser now that bigChain and bigMaf are liftable, because those carry their own bigDataUrl and so need no trustTrackDb. quickLiftIsLifted requires both halves, and every gate now uses it, which also settles the two different predicates that were in use for the same question. quickLiftLoadChains returns an empty list for a NULL file as well, so the older bed and genePred callers are covered whatever their gate does. quickLiftSql now checks that a row has at least as many columns as the loader is going to read. The native psl loader has always checked this, and the quickLift path replacing it did not, so a table of the wrong type walked off the end of the row; the psl caller now states the 21 columns it needs. quickLiftMafs held a maf component name in a fixed buffer through safecpy, which aborts rather than truncates, so a long name from a hub took hgTracks down. It clones instead. htcBigPslAliInWindow used a trackDb pointer its lookup can leave NULL, which its sibling htcBigPslAli already checked for. And aliTrackParam formats a URL parameter into a fixed buffer with safef, which aborts on a long one. refs #38249 diff --git src/hg/inc/quickLift.h src/hg/inc/quickLift.h index 073fa33a682..53a2b2382b5 100644 --- src/hg/inc/quickLift.h +++ src/hg/inc/quickLift.h @@ -98,30 +98,35 @@ // thing that collected the chains. struct psl *quickLiftPsl(struct hash *chainHash, struct hash **pMapPsls, struct psl *psl); // Map the target side of an alignment from the other assembly onto our current reference. // The query side (the mRNA, EST or protein the alignment is to) is left alone. Returns // NULL if the alignment doesn't map. pMapPsls points at a hash of mapping alignments the // caller keeps across a run of items; point it at a NULL hash to start. struct mafAli *quickLiftMafs(struct hash *chainHash, struct mafAli *mafList, char *sourceDb, char *refSrc, int refSrcSize); // Map MAF blocks from the other assembly onto our current reference. A block is cut at // every chain block boundary, since a MAF block has to be one contiguous run on its first // row and the lift does not keep the reference contiguous. refSrc is the name the browser // expects on the reference row, ".", with no hub prefix. +boolean quickLiftIsLifted(struct trackDb *tdb); +// TRUE when this track's data comes from another assembly and there is enough to lift it. +// Both halves have to be there: the chain file that does the lifting and the assembly the +// data came from. A hub can set either one on its own, and half the pair is no use. + boolean quickLiftIsOwnChainTrack(struct trackDb *tdb); // TRUE when this is the chain track quickLift builds to show the lift itself. That stanza // carries quickLiftUrl and quickLiftDb like any lifted track, but its data is already in // reference coordinates and must not be lifted a second time. struct chain *quickLiftChain(struct hash *chainHash, struct hash **pMapPsls, struct chain *chain); // Map a chain's target side from the other assembly onto our current reference. A chain is // an alignment between that assembly and some other species, so this composes the two and // leaves a chain between the reference and that species. The query side is left alone. // Returns NULL if the chain doesn't map. The chain handed in is not modified. struct psl *quickLiftPsls(struct hash *chainHash, struct psl *pslList); // Map a list of alignments in the other assembly's coordinates onto our current reference. // Alignments that don't map are dropped.