731eb75a1a1b0eeacfdaf5a1f48f74dbcee11302
braney
  Mon Dec 4 15:17:07 2017 -0800
fix #20575 and #20616

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index d101b60..d2504a4 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -371,32 +371,30 @@
 for (el = elList; el != NULL; el = el->next)
     {
     if (startsWith(CUSTOM_COMPOSITE_SETTING, el->name))
         copyCustomComposites(cart, el);
     }
 }
 
 void cartCopyCustomTracks(struct cart *cart)
 /* If cart contains any live custom tracks, save off a new copy of them,
  * to prevent clashes by multiple uses of the same session.  */
 {
 struct hashEl *el, *elList = hashElListHash(cart->hash);
 
 for (el = elList; el != NULL; el = el->next)
     {
-    if (startsWith(CUSTOM_COMPOSITE_SETTING, el->name))
-        copyCustomComposites(cart, el);
     if (startsWith(CT_FILE_VAR_PREFIX, el->name))
 	{
 	char *db = &el->name[strlen(CT_FILE_VAR_PREFIX)];
 	struct slName *browserLines = NULL;
 	struct customTrack *ctList = NULL;
 	char *ctFileName = (char *)(el->val);
 	if (fileExists(ctFileName))
 	    ctList = customFactoryParseAnyDb(db, ctFileName, TRUE, &browserLines);
         /* Save off only if the custom tracks are live -- if none are live,
          * leave cart variables in place so hgSession can detect and inform
          * the user. */
 	if (ctList)
 	    {
 	    struct customTrack *ct;
 	    static struct tempName tn;
@@ -1441,91 +1439,108 @@
 /* Make a radio button that is selected if cart variable exists and matches
  * value (or value matches default val if cart var doesn't exist). */
 {
 boolean matches = sameString(val, cartUsualString(cart, var, defaultVal));
 cgiMakeRadioButton(var, val, matches);
 }
 
 void cartSaveSession(struct cart *cart)
 /* Save session in a hidden variable. This needs to be called
  * somewhere inside of form or bad things will happen when user
  * has multiple windows open. */
 {
 cgiMakeHiddenVar(sessionVar, cartSessionId(cart));
 }
 
-static void cartDumpItem(struct hashEl *hel,boolean asTable)
+static void cartDumpItem(struct hashEl *hel,boolean asTable, boolean doHtmlEncode)
 /* Dump one item in cart hash */
 {
-char *var = htmlEncode(hel->name);
-char *val = htmlEncode((char *)(hel->val));
+char *var = hel->name;
+char *val = (char *)(hel->val);
+
+if (doHtmlEncode)
+    {
+    var = htmlEncode(hel->name);
+    val = htmlEncode((char *)(hel->val));
+    }
+
 if (asTable)
     {
     printf("<TR><TD>%s</TD><TD>", var);
     int width=(strlen(val)+1)*8;
     if (width<100)
         width = 100;
     cgiMakeTextVarWithJs(hel->name, val, width,
                                 "change", "setCartVar(this.name,this.value);");
     printf("</TD></TR>\n");
     }
 else
     printf("%s %s\n", var, val);
 
+if (doHtmlEncode)
+    {
     freeMem(var);
     freeMem(val);
     }
+}
 
-void cartDumpList(struct hashEl *elList,boolean asTable)
+void cartDumpList(struct hashEl *elList,boolean asTable, boolean doHtmlEncode)
 /* Dump list of cart variables optionally as a table with ajax update support. */
 {
 struct hashEl *el;
 
 if (elList == NULL)
     return;
 slSort(&elList, hashElCmp);
 if (asTable)
     printf("<table>\n");
 for (el = elList; el != NULL; el = el->next)
-    cartDumpItem(el,asTable);
+    cartDumpItem(el, asTable, doHtmlEncode);
 if (asTable)
     {
     printf("<tr><td colspan=2>&nbsp;&nbsp;<em>count: %d</em></td></tr>\n",slCount(elList));
     printf("</table>\n");
     }
 hashElFreeList(&elList);
 }
 
+void cartDumpNoEncode(struct cart *cart)
+/* Dump contents of cart without HTML encoding. */
+{
+struct hashEl *elList = hashElListHash(cart->hash);
+cartDumpList(elList,FALSE, FALSE);
+}
+
 void cartDump(struct cart *cart)
 /* Dump contents of cart. */
 {
 struct hashEl *elList = hashElListHash(cart->hash);
-cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE));
+cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE), TRUE);
 }
 
 void cartDumpPrefix(struct cart *cart, char *prefix)
 /* Dump all cart variables with prefix */
 {
 struct hashEl *elList = cartFindPrefix(cart, prefix);
-cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE));
+cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE), TRUE);
 }
 
 void cartDumpLike(struct cart *cart, char *wildcard)
 /* Dump all cart variables matching wildcard */
 {
 struct hashEl *elList = cartFindLike(cart, wildcard);
-cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE));
+cartDumpList(elList,cartVarExists(cart,CART_DUMP_AS_TABLE), TRUE);
 }
 
 char *cartFindFirstLike(struct cart *cart, char *wildCard)
 /* Find name of first variable that matches wildCard in cart.
  * Return NULL if none. */
 {
 struct hashEl *el, *elList = hashElListHash(cart->hash);
 char *name = NULL;
 
 for (el = elList; el != NULL; el = el->next)
     {
     if (wildMatch(wildCard, el->name))
 	{
 	name = el->name;
 	break;