cf3880c50c550e4deb61c9664f4f994e13ab6dd8
max
  Mon Aug 17 08:05:58 2026 -0700
hgc/hgTracks: fix three items from the v502 code review, refs #38106

Shared BLAT alignment links (hgc g=htcBlatAlign) drew the page and then
exit(0), which skips main's cartCheckout, so the loaded session was never
written back and the recipient's cart ended up nearly empty. Add
cartCheckout(&cart) before all four exit(0) calls that follow webEndGb(),
including the two early error returns.

squishCodonFont() decided FreeType was active with a looser test than
maybeNewFonts(), missing the requirement that the font name match a row in
freeTypeFonts[]; when they disagreed the bitmap engine got a cell height it
cannot render. Factor the engine decision into freeTypeFontActive() and use
it in both places.

Query name, chrom and a hub's organism string went raw into single-quoted JS
string literals and page titles on the modern alignment page; the shared-link
path reads the query name back out of a bigPsl, so it is not covered by
hgBlat's whitelist. javaScriptLiteralEncode the JS arguments and htmlEncode
the HTML labels.

Also add "u"/"s" (the shared-link session selectors) to hgc excludeVars so
they are not left in the reader's cart.

diff --git src/hg/hgTracks/config.c src/hg/hgTracks/config.c
index 03505c16f85..67ce31d969e 100644
--- src/hg/hgTracks/config.c
+++ src/hg/hgTracks/config.c
@@ -165,30 +165,39 @@
 
 int ii;
 for(ii=0; ii < ArraySize(freeTypeFonts); ii++)
     if (sameString(freeTypeFonts[ii].name, tl.textFont))
         break;
 if (ii == ArraySize(freeTypeFonts))
     return NULL;   // not a font we know about; leave the bitmap engine in place
 
 static char buffer[PATH_LEN];
 char *fontDir = cfgOptionDefault("freeTypeDir", "../htdocs/urw-fonts");
 safef(buffer, sizeof buffer, "%s/%s", fontDir, freeTypeFonts[ii].file);
 *retFontName = freeTypeFonts[ii].name;
 return buffer;
 }
 
+boolean freeTypeFontActive()
+/* TRUE when the FreeType font engine is the one maybeNewFonts() will actually switch to.  Callers
+ * that pick a font to match the live engine (e.g. squishCodonFont) must use this rather than a
+ * looser test, or they can hand the bitmap engine a cell height it cannot render. */
+{
+char *fontName = NULL;
+return chosenFreeTypeFont(&fontName) != NULL;
+}
+
 void initFontEngine()
 /* Load the text engine the user has picked, before anything measures a string.
  * Pack mode reserves room for an item by measuring its label, and
  * mgFontStringWidth answers from whichever engine is loaded at the time.  Doing
  * this up front keeps the packing from depending on whether some earlier image
  * on the page -- the ideogram -- happened to load FreeType first. */
 {
 char *fontName = NULL;
 char *fontFile = chosenFreeTypeFont(&fontName);
 if (fontFile != NULL)
     mgLoadFontEngine(FONT_METHOD_FREETYPE, fontFile);
 }
 
 void maybeNewFonts(struct hvGfx *hvg)
 /* Check to see if we want to use the alternate font engine (FreeType2). */