080a160c7b9595d516c9c70e83689a09b60839d0
galt
  Mon Jun 3 12:16:53 2013 -0700
fix SQL Injection
diff --git src/hg/lib/wikiTrack.c src/hg/lib/wikiTrack.c
index 6852a33..b17f3fb 100644
--- src/hg/lib/wikiTrack.c
+++ src/hg/lib/wikiTrack.c
@@ -110,80 +110,39 @@
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = wikiTrackLoad(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void wikiTrackSaveToDb(struct sqlConnection *conn, struct wikiTrack *el, char *tableName, int updateSize)
 /* Save wikiTrack as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
- * inserted as NULL. Note that strings must be escaped to allow insertion into the database.
- * For example "autosql's features include" --> "autosql\'s features include" 
- * If worried about this use wikiTrackSaveToDbEscaped() */
+ * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
-dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", 
+sqlDyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", 
 	tableName,  el->bin,  el->chrom,  el->chromStart,  el->chromEnd,  el->name,  el->score,  el->strand,  el->db,  el->owner,  el->color,  el->class,  el->creationDate,  el->lastModifiedDate,  el->descriptionKey,  el->id,  el->geneSymbol);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
-void wikiTrackSaveToDbEscaped(struct sqlConnection *conn, struct wikiTrack *el, char *tableName, int updateSize)
-/* Save wikiTrack as a row to the table specified by tableName. 
- * As blob fields may be arbitrary size updateSize specifies the approx size.
- * of a string that would contain the entire query. Automatically 
- * escapes all simple strings (not arrays of string) but may be slower than wikiTrackSaveToDb().
- * For example automatically copies and converts: 
- * "autosql's features include" --> "autosql\'s features include" 
- * before inserting into database. */ 
-{
-struct dyString *update = newDyString(updateSize);
-char  *chrom, *name, *strand, *db, *owner, *color, *class, *creationDate, *lastModifiedDate, *descriptionKey, *geneSymbol;
-chrom = sqlEscapeString(el->chrom);
-name = sqlEscapeString(el->name);
-strand = sqlEscapeString(el->strand);
-db = sqlEscapeString(el->db);
-owner = sqlEscapeString(el->owner);
-color = sqlEscapeString(el->color);
-class = sqlEscapeString(el->class);
-creationDate = sqlEscapeString(el->creationDate);
-lastModifiedDate = sqlEscapeString(el->lastModifiedDate);
-descriptionKey = sqlEscapeString(el->descriptionKey);
-geneSymbol = sqlEscapeString(el->geneSymbol);
-
-dyStringPrintf(update, "insert into %s values ( %u,'%s',%u,%u,'%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,'%s')", 
-	tableName, el->bin ,  chrom, el->chromStart , el->chromEnd ,  name, el->score ,  strand,  db,  owner,  color,  class,  creationDate,  lastModifiedDate,  descriptionKey, el->id ,  geneSymbol);
-sqlUpdate(conn, update->string);
-freeDyString(&update);
-freez(&chrom);
-freez(&name);
-freez(&strand);
-freez(&db);
-freez(&owner);
-freez(&color);
-freez(&class);
-freez(&creationDate);
-freez(&lastModifiedDate);
-freez(&descriptionKey);
-freez(&geneSymbol);
-}
 
 struct wikiTrack *wikiTrackCommaIn(char **pS, struct wikiTrack *ret)
 /* Create a wikiTrack out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new wikiTrack */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->bin = sqlUnsignedComma(&s);
 ret->chrom = sqlStringComma(&s);
 ret->chromStart = sqlUnsignedComma(&s);
 ret->chromEnd = sqlUnsignedComma(&s);
 ret->name = sqlStringComma(&s);
@@ -305,31 +264,31 @@
 #include "cart.h"
 #include "hPrint.h"
 #include "grp.h"
 #include "obscure.h"
 #include "hCommon.h"
 #include "web.h"
 #include "hgColors.h"
 
 #ifdef NOT
 static void savePosInTextBox(char *chrom, int start, int end)
 /* Save basic position/database info in text box and hidden var. 
    Positions becomes chrom:start-end*/
 {
 char position[128];
 char *newPos;
-snprintf(position, 128, "%s:%d-%d", chrom, start, end);
+safef(position, 128, "%s:%d-%d", chrom, start, end);
 newPos = addCommasToPos(position);
 cgiMakeTextVar("getDnaPos", newPos, strlen(newPos) + 2);
 cgiContinueHiddenVar("db");
 }
 #endif
 
 boolean wikiTrackReadOnly()
 /* return TRUE if wiki track is in Read-Only mode, default answer is FALSE */
 {
 return cfgOptionBooleanDefault(CFG_WIKI_TRACK_READ_ONLY, FALSE);
 }
 
 boolean wikiTrackEnabled(char *database, char **wikiUserName)
 /*determine if wikiTrack can be used, and is this user logged into the wiki ?*/
 {
@@ -443,35 +402,35 @@
     "class varchar(255) not null,\n"
     "creationDate varchar(255) not null,\n"
     "lastModifiedDate varchar(255) not null,\n"
     "descriptionKey varchar(255) not null,\n"
     "id int unsigned not null auto_increment,\n"
     "geneSymbol varchar(255) null,\n"
     "PRIMARY KEY(id),\n"
     "INDEX chrom (db,bin,chrom),\n"
     "INDEX name (db,name),\n"
     "INDEX gene (geneSymbol)\n"
 ")\n";
 
 char *wikiTrackGetCreateSql(char *tableName)
 /* return sql create statement for wiki track with tableName */
 {
-struct dyString *createTable = dyStringNew(512);
+struct dyString *dy = dyStringNew(512);
 
-dyStringPrintf(createTable, createString, tableName);
+sqlDyStringPrintf(dy, createString, tableName);
 
-return (dyStringCannibalize(&createTable));
+return (dyStringCannibalize(&dy));
 }
 
 char *wikiDbName()
 /* return name of database where wiki track is located
     currently this is central.db but the future may be configurable */
 {
 static char *dbName = NULL;
 
 if (dbName)
     return dbName;
 
 char setting[64];
 safef(setting, sizeof(setting), "central.db");
 dbName = cfgOption(setting);
 return dbName;
@@ -487,74 +446,74 @@
 }
 
 void wikiDisconnect(struct sqlConnection **pConn)
 /* disconnect from wikiTrack table database */
 {
 hDisconnectCentral(pConn);
 }
 
 struct wikiTrack *findWikiItemId(char *wikiItemId)
 /* given a wikiItemId return the row from the table */
 {
 struct wikiTrack *item;
 char query[256];
 struct sqlConnection *wikiConn = wikiConnect();
 
-safef(query, ArraySize(query), "SELECT * FROM %s WHERE id='%s' limit 1",
+sqlSafef(query, ArraySize(query), "SELECT * FROM %s WHERE id='%s' limit 1",
 	WIKI_TRACK_TABLE, wikiItemId);
 
 item = wikiTrackLoadByQuery(wikiConn, query);
 if (NULL == item)
     errAbort("display wiki item: failed to load item '%s'", wikiItemId);
 wikiDisconnect(&wikiConn);
 
 return item;
 }
 
 struct wikiTrack *findWikiItemByGeneSymbol(char *db, char *geneSymbol)
 /* given a db and UCSC known gene geneSymbol, find the wiki item */
 {
 struct wikiTrack *item = NULL;
 
 /* make sure neither of these arguments is NULL */
 if (db && geneSymbol)
     {
     char query[256];
     struct sqlConnection *wikiConn = wikiConnect();
-    safef(query, ArraySize(query),
+    sqlSafef(query, ArraySize(query),
 	"SELECT * FROM %s WHERE db='%s' AND geneSymbol='%s' limit 1",
 	    WIKI_TRACK_TABLE, db, geneSymbol);
 
     item = wikiTrackLoadByQuery(wikiConn, query);
 
     wikiDisconnect(&wikiConn);
     }
 
 return item;
 }
 
 struct wikiTrack *findWikiItemByName(char *db, char *name)
 /* given a db,name pair return the row from the table, can return NULL */
 {
 struct wikiTrack *item = NULL;
 
 /* make sure neither of these arguments is NULL */
 if (name && db)
     {
     char query[256];
     struct sqlConnection *wikiConn = wikiConnect();
-    safef(query, ArraySize(query),
+    sqlSafef(query, ArraySize(query),
 	"SELECT * FROM %s WHERE db='%s' AND name='%s' limit 1",
 	    WIKI_TRACK_TABLE, db, name);
 
     item = wikiTrackLoadByQuery(wikiConn, query);
 
     wikiDisconnect(&wikiConn);
     }
 
 return item;
 }
 
 static char *stripEditURLs(char *rendered)
 /* test for actual text, remove edit sections and any html comment strings */
 {
 char *stripped = cloneString(rendered);
@@ -802,31 +761,31 @@
     char *userSignature;
     /* In the case where this is a restoration of the header lines,
      *	may be a different creator than this user adding comments.
      *	So, get the header line correct to represent the actual creator.
      */
     if (sameWord(userName, item->owner))
 	userSignature = cloneString("~~~~");
     else
 	{
 	struct dyString *tt = newDyString(1024);
 	dyStringPrintf(tt, "[[User:%s|%s]] ", item->owner, item->owner);
 	dyStringPrintf(tt, "%s", item->creationDate);
 	userSignature = dyStringCannibalize(&tt);
 	recreateHeader = TRUE;
 	}
-    snprintf(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd);
+    safef(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd);
     newPos = addCommasToPos(database, position);
     
     if (extraHeader)
 	{
 	dyStringPrintf(content, "%s\n%s\n",
 	    category, extraHeader);
 	}
     else
 	{
 	dyStringPrintf(content, "%s\n"
 "[http://%s/cgi-bin/hgTracks?db=%s&wikiTrack=pack&position=%s:%d-%d %s %s]"
 	"&nbsp;&nbsp;<B>'%s'</B>&nbsp;&nbsp;",
 	category,
 	    cfgOptionDefault(CFG_WIKI_BROWSER, DEFAULT_BROWSER), database,
 		seqName, winStart+1, winEnd, database, newPos, item->name);
@@ -940,31 +899,31 @@
     char *userSignature;
     /* In the case where this is a restoration of the header lines,
      *	may be a different creator than this user adding comments.
      *	So, get the header line correct to represent the actual creator.
      */
     if (sameWord(userName, item->owner))
 	userSignature = cloneString("~~~~");
     else
 	{
 	struct dyString *tt = newDyString(1024);
 	dyStringPrintf(tt, "[[User:%s|%s]] ", item->owner, item->owner);
 	dyStringPrintf(tt, "%s", item->creationDate);
 	userSignature = dyStringCannibalize(&tt);
 	recreateHeader = TRUE;
 	}
-    snprintf(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd);
+    safef(position, 128, "%s:%d-%d", seqName, winStart+1, winEnd);
     newPos = addCommasToPos(database, position);
     if (extraHeader)
 	{
 	dyStringPrintf(content, "%s\n%s\n",
 	    category, extraHeader);
 	}
     else
 	{
 	dyStringPrintf(content, "%s\n"
 "[http://%s/cgi-bin/hgTracks?db=%s&wikiTrack=pack&position=%s:%d-%d %s %s]"
 	"&nbsp;&nbsp;<B>'%s'</B>&nbsp;&nbsp;",
 	category,
 	    cfgOptionDefault(CFG_WIKI_BROWSER, DEFAULT_BROWSER), database,
 		seqName, winStart+1, winEnd, database, newPos, item->name);
 	}