571441c95ee70d617e139675763b7b499e3ebc29
max
  Tue Jun 11 17:59:15 2013 -0700
fixing an sqlinjection problem as suggested by galt
diff --git src/hg/hgTracks/pubsTracks.c src/hg/hgTracks/pubsTracks.c
index 655d85b..9023b84 100644
--- src/hg/hgTracks/pubsTracks.c
+++ src/hg/hgTracks/pubsTracks.c
@@ -435,42 +435,47 @@
 safef(newName, sizeof(newName), "%d articles", (int) bed->score);
 return cloneString(newName);
 }
 
 static void pubsMarkerMapItem(struct track *tg, struct hvGfx *hvg, void *item,
                               char *itemName, char *mapItemName, int start, int end,
                               int x, int y, int width, int height)
 {
 struct bed *bed = item;
 genericMapItem(tg, hvg, item, bed->name, bed->name, start, end, x, y, width, height);
 }
 
 static struct hash* pubsLookupSequences(struct track *tg, struct sqlConnection* conn, char *articleId, bool getSnippet)
 /* create a hash with a mapping annotId -> snippet or annotId -> shortSeq for an articleId*/
 {
-    char query[LARGEBUF];
+    struct dyString *dy = dyStringNew(LARGEBUF);
     char *sequenceTable = trackDbRequiredSetting(tg->tdb, "pubsSequenceTable");
-    char *selectValSql = NULL;
+
+    // work around sql injection fix problem, suggested by galt
+    sqlDyStringPrintf(dy, "SELECT annotId, ");
+
     if (getSnippet)
-        selectValSql = "replace(replace(snippet, \"<B>\", \"\\n>>> \"), \"</B>\", \" <<<\\n\")";
+        dyStringAppend(dy, "replace(replace(snippet, \"<B>\", \"\\n>>> \"), \"</B>\", \" <<<\\n\")" );
     else
-        selectValSql = "concat(substr(sequence,1,4),\"...\",substr(sequence,-4))";
+        dyStringAppend(dy, "concat(substr(sequence,1,4),\"...\",substr(sequence,-4))" );
+    dyStringPrintf(dy, " FROM %s WHERE articleId='%s' ", sequenceTable, articleId);
+    // end sql injection fix
+
+    struct hash *seqIdHash = sqlQuickHash(conn, dy->string);
 
-    sqlSafef(query, sizeof(query), "SELECT annotId, %s  FROM %s WHERE articleId='%s' ", 
-        selectValSql, sequenceTable, articleId);
-    struct hash *seqIdHash = sqlQuickHash(conn, query);
-    //freeMem(sequenceTable); // XX Why does this crash?? because trackDbRequiredSetting returns a value in a hash. do not free.
+    //freeMem(sequenceTable); // trackDbRequiredSetting returns a value in a hash, so do not free
+    freeDyString(&dy);
     return seqIdHash;
 }
 
 static char *pubsArticleDispId(struct track *tg, struct sqlConnection *conn, char *articleId)
 /* given an articleId, lookup author and year and create <author><year> label for it */
 {
 char *dispLabel = NULL;
 char *articleTable = pubsArticleTable(tg);
 char query[LARGEBUF];
 sqlSafef(query, sizeof(query), "SELECT firstAuthor, year FROM %s WHERE articleId = '%s'", 
     articleTable, articleId);
 struct sqlResult *sr = sqlGetResult(conn, query);
 if (sr!=NULL)
     {
     char **row = NULL;