50bb9043f4659d06f46ef22b20baa9e0d41d8091
angie
  Tue Oct 9 11:42:24 2012 -0700
HTML-encode VCF alternate alleles in case they're symbolic like "<DEL>" (but don't encode twice :).
diff --git src/hg/hgc/vcfClick.c src/hg/hgc/vcfClick.c
index 753368d..68fb1e5 100644
--- src/hg/hgc/vcfClick.c
+++ src/hg/hgc/vcfClick.c
@@ -10,81 +10,82 @@
 #include "hgc.h"
 #include "htmshell.h"
 #include "jsHelper.h"
 #if (defined USE_TABIX && defined KNETFILE_HOOKS)
 #include "knetUdc.h"
 #include "udc.h"
 #endif//def USE_TABIX && KNETFILE_HOOKS
 #include "pgSnp.h"
 #include "trashDir.h"
 #include "vcf.h"
 #include "vcfUi.h"
 
 #define NA "<em>n/a</em>"
 
 static void printKeysWithDescriptions(struct vcfFile *vcff, int wordCount, char **words,
-				      struct vcfInfoDef *infoDefs)
+				      struct vcfInfoDef *infoDefs, boolean escapeHtml)
 /* Given an array of keys, print out a list of values with
  * descriptions if descriptions are available. */
 {
 int i;
 for (i = 0;  i < wordCount; i++)
     {
     if (i > 0)
 	printf(", ");
     char *key = words[i];
     const struct vcfInfoDef *def = vcfInfoDefForKey(vcff, key);
+    char *htmlKey = escapeHtml ? htmlEncode(key) : key;
     if (def != NULL)
-	printf("%s (%s)", htmlEncode(key), def->description);
+	printf("%s (%s)", htmlKey, def->description);
     else
-	printf("%s", htmlEncode(key));
+	printf("%s", htmlKey);
     }
 printf("<BR>\n");
 }
 
 static void vcfAltAlleleDetails(struct vcfRecord *rec, char **displayAls)
 /* If VCF header specifies any symbolic alternate alleles, pull in descriptions. */
 {
 printf("<B>Alternate allele(s):</B> ");
 if (rec->alleleCount < 2 || sameString(rec->alleles[1], "."))
     {
     printf(NA"<BR>\n");
     return;
     }
 struct vcfFile *vcff = rec->file;
-printKeysWithDescriptions(vcff, rec->alleleCount-1, &(displayAls[1]), vcff->altDefs);
+printKeysWithDescriptions(vcff, rec->alleleCount-1, &(displayAls[1]), vcff->altDefs, FALSE);
 }
 
 static void vcfQualDetails(struct vcfRecord *rec)
 /* If VCF header specifies a quality/confidence score (not "."), print it out. */
 {
 printf("<B>Quality/confidence score:</B> %s<BR>\n", sameString(rec->qual, ".") ? NA : rec->qual);
 }
 
 static void vcfFilterDetails(struct vcfRecord *rec)
 /* If VCF header specifies any filters, pull in descriptions. */
 {
 if (rec->filterCount == 0 || sameString(rec->filters[0], "."))
     printf("<B>Filter:</B> "NA"<BR>\n");
 else if (rec->filterCount == 1 && sameString(rec->filters[0], "PASS"))
     printf("<B>Filter:</B> PASS<BR>\n");
 else
     {
     printf("<B>Filter failures:</B> ");
     printf("<font style='font-weight: bold; color: #FF0000;'>\n");
     struct vcfFile *vcff = rec->file;
-    printKeysWithDescriptions(vcff, rec->filterCount, rec->filters, vcff->filterDefs);
+    printKeysWithDescriptions(vcff, rec->filterCount, rec->filters, vcff->filterDefs, TRUE);
     printf("</font>\n");
     }
 }
 
 static void vcfInfoDetails(struct vcfRecord *rec)
 /* Expand info keys to descriptions, then print out keys and values. */
 {
 if (rec->infoCount == 0)
     return;
 struct vcfFile *vcff = rec->file;
 puts("<B>INFO column annotations:</B><BR>");
 puts("<TABLE border=0 cellspacing=0 cellpadding=0>");
 int i;
 for (i = 0;  i < rec->infoCount;  i++)
     {
@@ -304,38 +305,39 @@
 if (seqInLen > threshold)
     {
     dyStringAppendN(dy, seqIn, endLength);
     int skippedLen = seqInLen-2*endLength;
     dyStringPrintf(dy, "...&lt;%d bases&gt;...%s",
 		   skippedLen, seqIn+seqInLen-endLength);
     }
 else
     dyStringAppend(dy, seqIn);
 }
 
 static void makeDisplayAlleles(struct vcfRecord *rec, boolean showLeftBase, char leftBase,
 			       int endLength, char **displayAls)
 /* If necessary, show the left base that we trimmed and/or abbreviate long sequences. */
 {
+struct dyString *dy = dyStringNew(128);
 int i;
 for (i = 0;  i < rec->alleleCount; i++)
     {
-    struct dyString *dy = dyStringNew(128);
+    dyStringClear(dy);
     if (showLeftBase)
 	dyStringPrintf(dy, "(%c)", leftBase);
     abbreviateLongSeq(rec->alleles[i], endLength, dy);
-    displayAls[i] = dy->string; // leak some mem
+    displayAls[i] = htmlEncode(dy->string); // leak some mem
     }
 }
 
 static void vcfRecordDetails(struct trackDb *tdb, struct vcfRecord *rec)
 /* Display the contents of a single line of VCF, assumed to be from seqName
  * (using seqName instead of rec->chrom because rec->chrom might lack "chr"). */
 {
 printf("<B>Name:</B> %s<BR>\n", rec->name);
 printCustomUrl(tdb, rec->name, TRUE);
 static char *formName = "vcfCfgHapCenter";
 printf("<FORM NAME=\"%s\" ACTION=\"%s\">\n", formName, hgTracksName());
 cartSaveSession(cart);
 vcfCfgHaplotypeCenter(cart, tdb, tdb->track, FALSE, rec->file, rec->name,
 		      seqName, rec->chromStart, formName);
 printf("</FORM>\n");