d17212c4b414a78dc5e95554953f3aa9a977ae63
jcasper
  Thu Feb 19 14:52:00 2026 -0800
ps/pdf output wasn't displaying some highlights if too many were present in the cart.  The highlight array is now dynamically allocated instead of a static limit of 4096, refs #36895

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 08d3bf79059..9f82195148d 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -2309,32 +2309,34 @@
 };
 
 struct highlightVar *parseHighlightInfo()
 // Parse highlight info from cart var to a linked list of highlightVar structs
 // Accepts four input formats for the highlight variable:
 // 0) chrom:start-end (format in very old carts)
 // 1) db.chrom:start-end (format in very old carts)
 // 2) db.chrom:start-end#hexColor|db.chrom:start-end#hexColor|... (old format)
 // 3) db#chrom#start#end#hexColor|db#chrom#start#end#hexColor|... (current format, to allow . in seq names)
 //
 {
 struct highlightVar *hlList = NULL;
 char *highlightDef = cartOptionalString(cart, "highlight");
 if(highlightDef)
     {
-    char *hlArr[4096];
-    int hlCount = chopByChar(cloneString(highlightDef), '|', hlArr, ArraySize(hlArr));
+    int hlCount = chopByChar(highlightDef, '|', NULL, 0);
+    char **hlArr = AllocN(char *, hlCount);
+    char *hlStringCopy = cloneString(highlightDef);
+    chopByChar(hlStringCopy, '|', hlArr, hlCount);
     int i;
     for (i=0; i<hlCount; i++)
         {
         char *oneHl = hlArr[i];
         struct highlightVar *h;
         char *chromStart, *chromEnd;
         AllocVar(h);
         if (countSeparatedItems(oneHl, '#')==5)
             // the new format: db#chrom#start#end#color
             {
             h->db     = cloneNextWordByDelimiter(&oneHl,'#');
             h->chrom  = cloneNextWordByDelimiter(&oneHl,'#');
             chromStart = cloneNextWordByDelimiter(&oneHl,'#');
             chromEnd = cloneNextWordByDelimiter(&oneHl,'#');
             h->hexColor = cloneString(oneHl);
@@ -2361,30 +2363,32 @@
             {
             // long to handle virt chrom coordinates
             h->chromStart = atol(chromStart);
             h->chromEnd   = atol(chromEnd);
             // Typically not zero based, unless we have previously saved the highlight
             // as a result of the multi-region code
             if (h->chromStart > 0)
                 {
                 h->chromStart--;
                 }
             slAddHead(&hlList, h);
             }
         }
 
     slReverse(&hlList);
+    freeMem(hlStringCopy);
+    freeMem(hlArr);
     }
 
 return hlList;
 }
 
 static void drawHighlights(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight)
 // Draw the highlight regions in the image.  Only done if theImgBox is not defined.
 // Thus it is done for ps/pdf and view image but for html output the highlights are drawn 
 // on the javascript client by hgTracks.js > imageV2 > drawHighlights()
 {
 struct highlightVar *hlList = parseHighlightInfo();
 
 if(hlList && theImgBox == NULL) // Only highlight region when imgBox is not used. (pdf and show-image)
     {
     struct highlightVar *h;