080a160c7b9595d516c9c70e83689a09b60839d0
galt
  Mon Jun 3 12:16:53 2013 -0700
fix SQL Injection
diff --git src/hg/hgc/peakClusters.c src/hg/hgc/peakClusters.c
index 0ed1775..960acaa 100644
--- src/hg/hgc/peakClusters.c
+++ src/hg/hgc/peakClusters.c
@@ -109,34 +109,34 @@
 webPrintLinkCellStart();
 struct trackDb *tdb = hashFindVal(trackHash, table);
 if (tdb == NULL)
     printf("%s info n/a", table);
 else
     compositeMetadataToggle(database, tdb, "metadata", TRUE, FALSE);
 webPrintLinkCellEnd();
 }
 
 static void queryInputTrackTable(struct dyString *query, char *inputTrackTable,
                                 struct slName *fieldList)
 /* Construct query in dyString to return contents of inputTrackTable ordered appropriately */
 {
 struct dyString *fields = dyStringNew(0);
 struct slName *field;
-dyStringPrintf(query, "select tableName ");
+sqlDyStringPrintf(query, "select tableName ");
 for (field = fieldList; field != NULL; field = field->next)
-    dyStringPrintf(fields, ",%s", field->name);
-dyStringPrintf(query, "%s from %s", fields->string, inputTrackTable);
+    sqlDyStringPrintfFrag(fields, ",%s", field->name);
+sqlDyStringPrintf(query, "%-s from %s", fields->string, inputTrackTable);
 if (fieldList != NULL)
     // skip leading comma
     dyStringPrintf(query, " order by %s", fields->string+1);
 dyStringFree(&fields);
 }
 
 static void printPeakClusterTableHits(struct bed *cluster, struct sqlConnection *conn,
 	char *inputTrackTable, struct slName *fieldList, char *vocab)
 /* Put out a lines in an html table that shows assayed sources that have hits in this
  * cluster, or if invert is set, that have misses. */
 {
 char *vocabFile = NULL;
 struct hash *vocabHash = NULL;
 if (vocab)
     {
@@ -208,38 +208,38 @@
 
 static void printFactorSourceTableHits(struct bed *cluster, struct sqlConnection *conn,
 	char *sourceTable, char *inputTrackTable, 
 	struct slName *fieldList, boolean invert, char *vocab)
 /* Put out a lines in an html table that shows assayed sources that have hits in this
  * cluster, or if invert is set, that have misses. */
 {
 char *vocabFile = NULL;
 if (vocab)
     {
     vocabFile = cloneFirstWord(vocab);
     }
 
 /* Make the monster SQL query to get all assays*/
 struct dyString *query = dyStringNew(0);
-dyStringPrintf(query, "select %s.id,%s.name,%s.tableName", sourceTable, sourceTable, 
+sqlDyStringPrintf(query, "select %s.id,%s.name,%s.tableName", sourceTable, sourceTable, 
 	inputTrackTable);
 struct slName *field;
 for (field = fieldList; field != NULL; field = field->next)
-    dyStringPrintf(query, ",%s.%s", inputTrackTable, field->name);
-dyStringPrintf(query, " from %s,%s ", inputTrackTable, sourceTable);
-dyStringPrintf(query, " where %s.source = %s.description", inputTrackTable, sourceTable);
-dyStringPrintf(query, " and factor='%s' order by %s.source", cluster->name, inputTrackTable);
+    sqlDyStringPrintf(query, ",%s.%s", inputTrackTable, field->name);
+sqlDyStringPrintf(query, " from %s,%s ", inputTrackTable, sourceTable);
+sqlDyStringPrintf(query, " where %s.source = %s.description", inputTrackTable, sourceTable);
+sqlDyStringPrintf(query, " and factor='%s' order by %s.source", cluster->name, inputTrackTable);
 
 int displayNo = 0;
 int fieldCount = slCount(fieldList);
 struct sqlResult *sr = sqlGetResult(conn, query->string);
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
     {
     int sourceId = sqlUnsigned(row[0]);
     double signal = cluster->expScores[sourceId];
     boolean hit = (signal > 0);
     if (hit ^ invert)
         {
 	printf("</TR><TR>\n");
 	webPrintIntCell(++displayNo);
 	if (!invert)
@@ -292,52 +292,52 @@
 }
 
 void doPeakClusters(struct trackDb *tdb, char *item)
 /* Display detailed info about a cluster of peaks from other tracks. */
 {
 int start = cartInt(cart, "o");
 char *table = tdb->table;
 int rowOffset = hOffsetPastBin(database, seqName, table);
 char query[256];
 struct sqlResult *sr;
 char **row;
 struct bed *cluster = NULL;
 struct sqlConnection *conn = hAllocConn(database);
 
 cartWebStart(cart, database, "%s item details", tdb->shortLabel);
-safef(query, sizeof(query),
+sqlSafef(query, sizeof(query),
 	"select * from %s where  name = '%s' and chrom = '%s' and chromStart = %d",
 	table, item, seqName, start);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 if (row != NULL)
     cluster = bedLoadN(row + rowOffset, 5);
 sqlFreeResult(&sr);
 
 if (cluster != NULL)
     {
     /* Get list of subgroups to display */
     char *inputTableFieldDisplay = trackDbSetting(tdb, "inputTableFieldDisplay");
     if (inputTableFieldDisplay != NULL)
         {
 	struct slName *fieldList = stringToSlNames(inputTableFieldDisplay);
 	char *vocab = trackDbSetting(tdb, "controlledVocabulary");
 	char *inputTrackTable = trackDbRequiredSetting(tdb, "inputTrackTable");
 
 	/* Print out some information about the cluster overall. */
 	printf("<B>Items in Cluster:</B> %s of %d<BR>\n", cluster->name, 
-	    sqlRowCount(conn, inputTrackTable));
+	    sqlRowCount(conn, sqlCheckTableName(inputTrackTable)));
 	printf("<B>Cluster Score (out of 1000):</B> %d<BR>\n", cluster->score);
 	printPos(cluster->chrom, cluster->chromStart, cluster->chromEnd, NULL, TRUE, NULL);
 
 	/* In a new section put up list of hits. */
 	webNewSection("List of Items in Cluster");
 	webPrintLinkTableStart();
 	printClusterTableHeader(fieldList, FALSE, FALSE, TRUE);
 	printPeakClusterTableHits(cluster, conn, inputTrackTable, fieldList, vocab);
 	}
     else
 	errAbort("Missing required trackDb setting %s for track %s",
 	    "inputTableFieldDisplay", tdb->track);
     webPrintLinkTableEnd();
     }
 printf("<A HREF=\"%s&g=htcListItemsAssayed&table=%s\" TARGET_blank>", hgcPathAndSettings(),
@@ -350,55 +350,55 @@
 hFreeConn(&conn);
 }
 
 void doFactorSource(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start)
 /* Display detailed info about a cluster of peaks from other tracks. */
 {
 int rowOffset = hOffsetPastBin(database, seqName, tdb->table);
 char **row;
 struct sqlResult *sr;
 char query[256];
 char *motifTable = NULL;
 #ifdef TXCLUSTER_MOTIFS_TABLE
 motifTable = TXCLUSTER_MOTIFS_TABLE;
 #endif
 
-safef(query, sizeof(query),
+sqlSafef(query, sizeof(query),
 	"select * from %s where  name = '%s' and chrom = '%s' and chromStart = %d",
 	tdb->table, item, seqName, start);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 struct bed *cluster = NULL;
 if (row != NULL)
     cluster = bedLoadN(row + rowOffset, 15);
 sqlFreeResult(&sr);
 
 if (cluster != NULL)
     {
     char *sourceTable = trackDbRequiredSetting(tdb, "sourceTable");
     struct dnaMotif *motif = NULL;
     struct dnaSeq **seqs = NULL;
     struct bed6FloatScore *hits = NULL;
 
     if(motifTable != NULL && sqlTableExists(conn, motifTable))
         {
         struct sqlResult *sr;
         int rowOffset;
         char where[256];
 
         motif = loadDnaMotif(item, "transRegCodeMotif");
-        safef(where, sizeof(where), "name = '%s'", item);
+        sqlSafefFrag(where, sizeof(where), "name = '%s'", item);
         sr = hRangeQuery(conn, "wgEncodeRegTfbsClusteredMotifs", cluster->chrom, cluster->chromStart,
                          cluster->chromEnd, where, &rowOffset);
         while ((row = sqlNextRow(sr)) != NULL)
             {
             struct bed6FloatScore *hit = NULL;
             AllocVar(hit);
             hit->chromStart = sqlUnsigned(row[rowOffset + 1]);
             hit->chromEnd = sqlUnsigned(row[rowOffset + 2]);
             hit->score = sqlFloat(row[rowOffset + 4]);
             hit->strand[0] = row[rowOffset + 5][0];
             slAddHead(&hits, hit);
             }
         sqlFreeResult(&sr);
         }
     
@@ -409,61 +409,61 @@
 	char *file = cloneFirstWord(vocab);
 	factorLink = controlledVocabLink(file, "term", factorLink, factorLink, factorLink, "");
 	}
     printf("<B>Factor:</B> %s<BR>\n", factorLink);
     printf("<B>Cluster Score (out of 1000):</B> %d<BR>\n", cluster->score);
     if(motif != NULL && hits != NULL)
         {
         struct bed6FloatScore *hit = NULL;
         int i;
         seqs = needMem(sizeof(struct dnaSeq *) * slCount(hits));
         for (hit = hits, i = 0; hit != NULL; hit = hit->next, i++)
             {
             char query[256];
             float maxScore = -1;
 
-            safef(query, sizeof(query), 
+            sqlSafef(query, sizeof(query), 
 	    	"select max(score) from %s where name = '%s'", 
 		"wgEncodeRegTfbsClusteredMotifs", item);
             sr = sqlGetResult(conn, query);
             if ((row = sqlNextRow(sr)) != NULL)
                 {
                 if(!isEmpty(row[0]))
                     {
                     maxScore = sqlFloat(row[0]);
                     }
                 }
             sqlFreeResult(&sr);
 
             struct dnaSeq *seq = hDnaFromSeq(database, 
 	    	seqName, hit->chromStart, hit->chromEnd, dnaLower);
             if(hit->strand[0] == '-')
                 reverseComplement(seq->dna, seq->size);
             seqs[i] = seq;
             printf("<B>Motif Score #%d:</B>  %.2f (max: %.2f)<BR>\n", i + 1, hit->score, maxScore);
             }
         }
     printPos(cluster->chrom, cluster->chromStart, cluster->chromEnd, NULL, TRUE, NULL);
 
     if(seqs != NULL)
         {
         motifMultipleHitsSection(seqs, slCount(hits), motif);
         }
 
     /* Get list of tracks we'll look through for input. */
     char *inputTrackTable = trackDbRequiredSetting(tdb, "inputTrackTable");
-    safef(query, sizeof(query), 
+    sqlSafef(query, sizeof(query), 
     	"select tableName from %s where factor='%s' order by source", inputTrackTable, 
 	cluster->name);
 
     /* Next do the lists of hits and misses.  We have the hits from the non-zero signals in
      * cluster->expScores.  We need to figure out the sources actually assayed though
      * some other way.  We'll do this by one of two techniques. */
     char *inputTableFieldDisplay = trackDbSetting(tdb, "inputTableFieldDisplay");
     if (inputTableFieldDisplay != NULL)
         {
 	struct slName *fieldList = stringToSlNames(inputTableFieldDisplay);
 	char *vocab = trackDbSetting(tdb, "controlledVocabulary");
 
 	/* In a new section put up list of hits. */
 	webNewSection("List of %s Items in Cluster", cluster->name);
 	webPrintLinkTableStart();