95807c7178fd38d52564f06df9fd5b90ceca1d24
braney
  Wed Sep 2 11:20:44 2026 -0700
hgTracks, hgc, hgPhyloPlace: small fixes from the v503 Preview II review, refs #38172

hgTracks.c: skipBeyondDelimit returns NULL when the delimiter is absent, and
the caller decremented and printed it without checking.  The noYearDbs list
keeps every assembly that reaches it carrying a '(' today, so nothing shows,
but printf used to print "(null)" where htmlEncode now walks off the end.
Fall back to the whole freeze name.

gtexTracks.c: the guard before the in place truncation was two bytes stricter
than the buffer needs, so a description just over the budget printed in full.
Say what the buffer requirement actually is.  vcfTrack.c has the same shape a
byte the other way and is already right.

hgPhyloPlace.c: initialize size, as the two sibling call sites do.
cgiMemBlobFind always sets it when it returns a block, so this is for
consistency.

bigBedClick.c: hubEncode was called twice on the same string in one
statement.

diff --git src/hg/hgTracks/gtexTracks.c src/hg/hgTracks/gtexTracks.c
index a0dd2a0c30e..953e392fbeb 100644
--- src/hg/hgTracks/gtexTracks.c
+++ src/hg/hgTracks/gtexTracks.c
@@ -494,32 +494,34 @@
     geneInfo->geneModel = hashFindVal(modelHash, geneBed->geneId); // sometimes this is missing, hash returns NULL. do we check?
     // NOTE: Consider loading all gene descriptions to save queries
     char query[256];
     sqlSafef(query, sizeof(query),
             "select kgXref.description from kgXref where geneSymbol='%s'", geneBed->name);
     char *knownDatabase = hdbDefaultKnownDb(database);
     struct sqlConnection *conn = hAllocConn(knownDatabase);
     char *desc = sqlQuickString(conn, query);
     hFreeConn(&conn);
     if (desc)
         {
         // hg38 known genes has extra detail about source; strip it
         char *fromDetail = strstrNoCase(desc, "(from");
         if (fromDetail)
             *fromDetail = 0;
-        // the "..." plus its terminating null needs MAX_DESC+4 bytes of buffer
-        if (strlen(desc) > MAX_DESC + 4)
+        // The "..." plus its terminating null is written at desc+MAX_DESC, so the buffer
+        // needs MAX_DESC+4 bytes.  sqlQuickString sized it at strlen+1 before the "(from"
+        // strip above shortened the string, so a length of MAX_DESC+3 here is enough.
+        if (strlen(desc) >= MAX_DESC + 3)
             strcpy(desc+MAX_DESC, "...");
         // also strip 'homo sapiens' prefix
         #define SPECIES_PREFIX  "Homo sapiens "
         if (startsWith(SPECIES_PREFIX, desc))
             desc += strlen(SPECIES_PREFIX);
         geneInfo->description = desc;
         }
     else
         geneInfo->description = geneInfo->geneBed->name;
 
     slAddHead(&list, geneInfo);
     geneBed = geneBed->next;
     geneInfo->geneBed->next = NULL;
 
     if (extras->isComparison && (tg->visibility == tvFull || tg->visibility == tvPack))