1258d7f65e7058408390246f0b592ae00e1b4d26
braney
  Mon Aug 31 13:48:21 2026 -0700
trackHub: keep a description a track inherited from its parent, refs #38126

trackHubAddOneDescription used to return early when a track had no html setting
of its own, which left tdb->html alone.  Sanitizing where the text comes in made
it assign every time, so it cleared a description that trackHubAddDescription
had copied down from an ancestor.  No caller loses a page over this today,
because each one re-fetches afterward, but the function should not be
destructive.

diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index bf24b125c45..c9506e77a42 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -1328,30 +1328,32 @@
 char *fixedUrl = url;
 if (!endsWith(url, ".html"))
     {
     safef(buffer, sizeof buffer, "%s.html", url);
     fixedUrl = buffer;
     }
 char *html = udcFileReadAllIfExists(fixedUrl, NULL, 0, NULL);
 freez(&url);
 return html;
 }
 
 void trackHubAddOneDescription(char *trackDbFile, struct trackDb *tdb)
 /* Fetch tdb->track's html description and store in tdb->html. */
 {
 char *html = trackHubDescriptionText(trackDbFile, tdb);
+if (html == NULL)
+    return;                     /* no page of its own, so leave any it inherited alone */
 tdb->html = htmlSanitize(html);
 freeMem(html);
 }
 
 struct slName *trackHubDescriptionRemovals(char *trackDbFile, struct trackDb *tdb)
 /* Return a list of messages naming the parts of tdb's description page that we do not
  * print, or NULL if we print all of it. */
 {
 char *html = trackHubDescriptionText(trackDbFile, tdb);
 struct slName *removed = NULL;
 char *clean = htmlSanitizeReport(html, &removed);
 freeMem(html);
 freeMem(clean);
 return removed;
 }