080a160c7b9595d516c9c70e83689a09b60839d0
galt
  Mon Jun 3 12:16:53 2013 -0700
fix SQL Injection
diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index b8401a1..7ddaf66 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -49,34 +49,34 @@
 
 void cartTrace(struct cart *cart, char *when, struct sqlConnection *conn)
 /* Write some properties of the cart to stderr for debugging. */
 {
 if (cfgOption("cart.trace") == NULL)
     return;
 struct cartDb *u = cart->userInfo, *s = cart->sessionInfo;
 char *pix = hashFindVal(cart->hash, "pix");
 char *textSize = hashFindVal(cart->hash, "textSize");
 char *trackControls = hashFindVal(cart->hash, "trackControlsOnMain");
 int uLen, sLen;
 if (conn != NULL)
     {
     /* Since the content string is chopped, query for the actual length. */
     char query[1024];
-    safef(query, sizeof(query), "select length(contents) from userDb "
+    sqlSafef(query, sizeof(query), "select length(contents) from userDb "
 	  "where id = %d", u->id);
     uLen = sqlQuickNum(conn, query);
-    safef(query, sizeof(query), "select length(contents) from sessionDb "
+    sqlSafef(query, sizeof(query), "select length(contents) from sessionDb "
 	  "where id = %d", s->id);
     sLen = sqlQuickNum(conn, query);
     }
 else
     {
     uLen = strlen(u->contents);
     sLen = strlen(s->contents);
     }
 if (pix == NULL)
     pix = "-";
 if (textSize == NULL)
     textSize = "-";
 if (trackControls == NULL)
     trackControls = "-";
 fprintf(stderr, "ASH: %22s: "
@@ -164,87 +164,87 @@
 	}
     freez(&fu);
     return isCorr;
     }
 }
 
 struct cartDb *cartDbLoadFromId(struct sqlConnection *conn, char *table, int id)
 /* Load up cartDb entry for particular ID.  Returns NULL if no such id. */
 {
 if (id == 0)
    return NULL;
 else
    {
    struct cartDb *cdb = NULL;
    char where[64];
-   safef(where, sizeof(where), "id = %u", id);
+   sqlSafefFrag(where, sizeof(where), "id = %u", id);
    cdb = cartDbLoadWhere(conn, table, where);
    if (looksCorrupted(cdb))
        {
        /* Can't use warn here -- it interrupts the HTML header, causing an
 	* err500 (and nothing useful in error_log) instead of a warning. */
        fprintf(stderr,
 	       "%s id=%d looks corrupted -- starting over with new %s id.\n",
 	       table, id, table);
        cdb = NULL;
        }
    return cdb;
    }
 }
 
 struct cartDb *loadDb(struct sqlConnection *conn, char *table, int id, boolean *found)
 /* Load bits from database and save in hash. */
 {
 struct cartDb *cdb;
 char query[256];
 boolean result = TRUE;
 
 cdb = cartDbLoadFromId(conn, table, id);
 if (!cdb)
     {
     result = FALSE;
-    safef(query, sizeof(query), "INSERT %s VALUES(0,\"\",0,now(),now(),0)",
+    sqlSafef(query, sizeof(query), "INSERT %s VALUES(0,\"\",0,now(),now(),0)",
 	  table);
     sqlUpdate(conn, query);
     id = sqlLastAutoId(conn);
     if ((cdb = cartDbLoadFromId(conn,table,id)) == NULL)
         errAbort("Couldn't get cartDb for id=%d right after loading.  "
 		 "MySQL problem??", id);
     }
 *found = result;
 return cdb;
 }
 
 void cartExclude(struct cart *cart, char *var)
 /* Exclude var from persistent storage. */
 {
 hashAdd(cart->exclude, var, NULL);
 }
 
 
 void sessionTouchLastUse(struct sqlConnection *conn, char *encUserName,
 			 char *encSessionName)
 /* Increment namedSessionDb.useCount and update lastUse for this session. */
 {
 struct dyString *dy = dyStringNew(1024);
 int useCount;
-dyStringPrintf(dy, "SELECT useCount FROM %s "
+sqlDyStringPrintf(dy, "SELECT useCount FROM %s "
 	       "WHERE userName = '%s' AND sessionName = '%s';",
 	       namedSessionTable, encUserName, encSessionName);
 useCount = sqlQuickNum(conn, dy->string) + 1;
 dyStringClear(dy);
-dyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() "
+sqlDyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() "
 	       "WHERE userName = '%s' AND sessionName = '%s';",
 	       namedSessionTable, useCount, encUserName, encSessionName);
 sqlUpdate(conn, dy->string);
 dyStringFree(&dy);
 }
 
 #ifndef GBROWSE
 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)
     {
@@ -426,31 +426,31 @@
  * If non-NULL, actionVar is a cartRemove wildcard string specifying the
  * CGI action variable that sent us here. */
 {
 struct sqlResult *sr = NULL;
 char **row = NULL;
 char *userName = wikiLinkUserName();
 char *encSessionName = cgiEncodeFull(sessionName);
 char *encSessionOwner = cgiEncodeFull(sessionOwner);
 char query[512];
 
 if (isEmpty(sessionOwner))
     errAbort("Please go back and enter a wiki user name for this session.");
 if (isEmpty(sessionName))
     errAbort("Please go back and enter a session name to load.");
 
-safef(query, sizeof(query), "SELECT shared, contents FROM %s "
+sqlSafef(query, sizeof(query), "SELECT shared, contents FROM %s "
       "WHERE userName = '%s' AND sessionName = '%s';",
       namedSessionTable, encSessionOwner, encSessionName);
 sr = sqlGetResult(conn, query);
 if ((row = sqlNextRow(sr)) != NULL)
     {
     boolean shared = atoi(row[0]);
     if (shared ||
 	(userName && sameString(sessionOwner, userName)))
 	{
 	char *sessionVar = cartSessionVarName();
 	unsigned hgsid = cartSessionId(cart);
 	struct sqlConnection *conn2 = hConnectCentral();
 	sessionTouchLastUse(conn2, encSessionOwner, encSessionName);
 	cartRemoveLike(cart, "*");
 	cartParseOverHash(cart, row[1]);
@@ -654,34 +654,34 @@
     while ((ex = *exclude++))
 	cartExclude(cart, ex);
     }
 
 cartDefaultDisconnector(&conn);
 return cart;
 }
 
 
 
 static void updateOne(struct sqlConnection *conn,
 	char *table, struct cartDb *cdb, char *contents, int contentSize)
 /* Update cdb in database. */
 {
 struct dyString *dy = newDyString(4096);
-dyStringPrintf(dy, "UPDATE %s SET contents='", table);
-dyStringAppendN(dy, contents, contentSize);
-dyStringPrintf(dy, "',lastUse=now(),useCount=%d ", cdb->useCount+1);
-dyStringPrintf(dy, " where id=%u", cdb->id);
+sqlDyStringPrintf(dy, "UPDATE %s SET contents='", table);
+sqlDyAppendEscaped(dy, contents);
+sqlDyStringPrintf(dy, "',lastUse=now(),useCount=%d ", cdb->useCount+1);
+sqlDyStringPrintf(dy, " where id=%u", cdb->id);
 sqlUpdate(conn, dy->string);
 dyStringFree(&dy);
 }
 
 
 void cartEncodeState(struct cart *cart, struct dyString *dy)
 /* Add a CGI-encoded var=val&... string of all cart variables to dy. */
 {
 struct hashEl *el, *elList = hashElListHash(cart->hash);
 boolean firstTime = TRUE;
 char *s = NULL;
 for (el = elList; el != NULL; el = el->next)
     {
     if (!hashLookup(cart->exclude, el->name))
 	{
@@ -1330,31 +1330,31 @@
 return (hguidString == NULL ? 0 : atoi(hguidString));
 }
 
 static int getSessionId()
 /* Get session id if any from CGI. */
 {
 return cgiUsualInt("hgsid", 0);
 }
 
 static void clearDbContents(struct sqlConnection *conn, char *table, unsigned id)
 /* Clear out contents field of row in table that matches id. */
 {
 char query[256];
 if (id == 0)
    return;
-safef(query, sizeof(query), "update %s set contents='' where id=%u",
+sqlSafef(query, sizeof(query), "update %s set contents='' where id=%u",
       table, id);
 sqlUpdate(conn, query);
 }
 
 void cartResetInDb(char *cookieName)
 /* Clear cart in database. */
 {
 int hguid = getCookieId(cookieName);
 int hgsid = getSessionId();
 struct sqlConnection *conn = cartDefaultConnector();
 clearDbContents(conn, "userDb", hguid);
 clearDbContents(conn, "sessionDb", hgsid);
 cartDefaultDisconnector(&conn);
 }
 
@@ -1674,37 +1674,37 @@
 char *chp;
 struct sqlConnection *conn, *conn2;
 
 conn= hAllocConn(genomeDb);
 conn2= hAllocConn(genomeDb);
 
 trashDirFile(&tn, "ct", "gsidSubj", ".list");
 outName = tn.forCgi;
 
 trashDirFile(&tn2, "ct", "gsidSeq", ".list");
 outName2 = tn2.forCgi;
 
 outF = mustOpen(outName,"w");
 outF2= mustOpen(outName2,"w");
 
-safef(query, sizeof(query), "select distinct subjId from hgFixed.gsIdXref order by subjId");
+sqlSafef(query, sizeof(query), "select distinct subjId from hgFixed.gsIdXref order by subjId");
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     fprintf(outF, "%s\n", row[0]);
 
-    safef(query2, sizeof(query2),
+    sqlSafef(query2, sizeof(query2),
           "select dnaSeqId from hgFixed.gsIdXref where subjId='%s' order by dnaSeqId", row[0]);
 
     sr2 = sqlGetResult(conn2, query2);
     while ((row2 = sqlNextRow(sr2)) != NULL)
         {
         /* Remove "ss." from the front of the DNA sequence ID,
            so that they could be used both for DNA and protein MSA maf display */
         chp = strstr(row2[0], "ss.");
         if (chp != NULL)
             {
             fprintf(outF2, "%s\t%s\n", chp+3L, row[0]);
             }
         else
             {
             fprintf(outF2, "%s\t%s\n", row2[0], row[0]);
@@ -1784,32 +1784,32 @@
 	{
         errAbort("can't find species list file var '%s' in cart\n",speciesUseFile);
 	}
     }
 
 struct lineFile *lf = lineFileOpen(val, TRUE);
 
 if (lf == NULL)
     errAbort("can't open species list file %s",val);
 
 if (hIsGsidServer())
     {
     conn= hAllocConn(genomeDb);
     while( ( lineFileChopNext(lf, words, sizeof(words)/sizeof(char *)) ))
         {
-        safef(query, sizeof(query),
-	      "select id from %s where id like '%s%s'", msaTable, "%",  words[0]);
+        sqlSafef(query, sizeof(query),
+	      "select id from %s where id like '%%%s'", msaTable, sqlCheckAlphaNum(words[0]));
 	sr = sqlGetResult(conn, query);
 	if (sqlNextRow(sr) != NULL)
             {
             dyStringPrintf(orderDY, "%s ",words[0]);
             sqlFreeResult(&sr);
             }
         }
     hFreeConn(&conn);
     }
 else
     {
     while( ( lineFileChopNext(lf, words, sizeof(words)/sizeof(char *)) ))
         {
         dyStringPrintf(orderDY, "%s ",words[0]);
         }