080a160c7b9595d516c9c70e83689a09b60839d0
galt
  Mon Jun 3 12:16:53 2013 -0700
fix SQL Injection
diff --git src/hg/qaPushQ/qaPushQ.c src/hg/qaPushQ/qaPushQ.c
index 389734c..44edbb2 100644
--- src/hg/qaPushQ/qaPushQ.c
+++ src/hg/qaPushQ/qaPushQ.c
@@ -254,31 +254,31 @@
 if (sscanf(d,"%d",&dd)   != 1) return FALSE;
 if (yyyy < 1900) return FALSE;
 if (yyyy > 2100) return FALSE;
 if (  mm > 12  ) return FALSE;
 if (  mm <  1  ) return FALSE;
 if (  dd > 31  ) return FALSE;
 if (  dd <  1  ) return FALSE;
 return TRUE;
 }
 
 
 void encryptPWD(char *password, char *salt, char *buf, int bufsize)
 /* encrypt a password */
 {
 /* encrypt user's password. */
-safef(buf,bufsize,crypt(password, salt));
+safef(buf,bufsize,"%s",crypt(password, salt));
 }
 
 
 void encryptNewPWD(char *password, char *buf, int bufsize)
 /* encrypt a new password */
 {
 unsigned long seed[2];
 char salt[] = "$1$........";
 const char *const seedchars =
 "./0123456789ABCDEFGHIJKLMNOPQRST"
 "UVWXYZabcdefghijklmnopqrstuvwxyz";
 int i;
 /* Generate a (not very) random seed. */
 seed[0] = time(NULL);
 seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
@@ -313,52 +313,52 @@
 
 bool mySqlGetLock(char *name, int timeout)
 /* Tries to acquire (for 10 seconds) and set an advisory lock.
  *  note: mysql returns 1 if successful,
  *   0 if name already locked or NULL if error occurred
  *   blocks another client from obtaining a lock with the same name
  *   lock is automatically released by mysql when connection is closed or detected broken
  *   may even detect program crash and release lock.
  */
 {
 char query[256];
 struct sqlResult *rs;
 char **row = NULL;
 bool result = FALSE;
 
-safef(query, sizeof(query), "select get_lock('%s', %d)", name, timeout);
+sqlSafef(query, sizeof(query), "select get_lock('%s', %d)", name, timeout);
 rs = sqlGetResult(conn, query);
 row=sqlNextRow(rs);
 if (row[0] == NULL)
     {
     safef(msg, sizeof(msg), "Attempt to GET_LOCK of %s caused an error\n",name);
     htmShell(TITLE, doMsg, NULL);
     exit(0);
     }
 if (sameWord(row[0], "1"))
     result = TRUE;
 else if (sameWord(row[0], "0"))
     result = FALSE;
 sqlFreeResult(&rs);
 return result;
 }
 
 void mySqlReleaseLock(char *name)
 /* Releases an advisory lock created by GET_LOCK in mySqlGetLock */
 {
 char query[256];
-safef(query, sizeof(query), "select release_lock('%s')", name);
+sqlSafef(query, sizeof(query), "select release_lock('%s')", name);
 sqlUpdate(conn, query);
 }
 
 
 
 void setLock()
 /* set a lock to reduce concurrency problems */
 {
 mySqlGetLock("qapushq",10);    /* just an advisory semaphore, really */
 }
 
 void releaseLock()
 /* release the advisory lock */
 {
 mySqlReleaseLock("qapushq");
@@ -966,58 +966,52 @@
 	errAbort("drawDisplayLine: unexpected case enum %d.",col);
 
 
     }
 
 }
 
 
 
 void doDisplay()
 /* handle display request, shows pushQ records, also this is the default action  */
 {
 struct pushQ *ki, *kiList = NULL;
 struct sqlResult *sr;
 char **row;
-char query[256];
+struct dyString *dy = dyStringNew(0);
 char lastP = ' ';
 int c = 0;
-char monthsql[256];
 char comment[256];
 
 /* initialize column display order */
 initColsFromString();
 
-safef(monthsql,sizeof(monthsql),"%s","");
+/* Get a list of all (or in month). */
+sqlDyStringPrintf(dy, "select * from %s", pushQtbl);
 if (!sameString(month,""))
     {
-    safef(monthsql,sizeof(monthsql)," where priority='L' and qadate like '%s%%' ",month);
+    sqlDyStringPrintf(dy," where priority='L' and qadate like '%s%%' ",month);
     }
-
-/* Get a list of all (or in month). */
-safef(query, sizeof(query), "select * from %s%s%s",
-    pushQtbl,
-    monthsql,
-    " order by priority, rank, qadate desc, qid desc limit 200"
-    );
-
-sr = sqlGetResult(conn, query);
+dyStringAppend(dy, " order by priority, rank, qadate desc, qid desc limit 200");
+sr = sqlGetResult(conn, dy->string);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     ki = pushQLoad(row);
     slAddHead(&kiList, ki);
     }
+dyStringFree(&dy);
 sqlFreeResult(&sr);
 slReverse(&kiList);
 
 /* #rows returned
 slCount(kiList)
 */
 
 if (sameString(utsName.nodename,"hgwdev"))
     {
     printf("<p style=\"color:red\">Machine: %s THIS IS NOT THE REAL PUSHQ- GO TO <a href=http://hgwbeta.cse.ucsc.edu/cgi-bin/qaPushQ>HGWBETA</a> </p>\n",utsName.nodename);
     }
 
 if (!sameString(msg,""))
     {
     printf("<p style=\"color:red\">%s</p>\n",msg);
@@ -1134,72 +1128,72 @@
 printf("</table>");
 
 pushQFreeList(&kiList);
 
 }
 
 
 struct pushQ *loadPushQ(char *qid)
 /* Return pushQ struct loading q with existing values.
  * Use pushQFree() when done.*/
 {
 char **row;
 struct sqlResult *sr;
 char query[256];
 struct pushQ *q = NULL;
-safef(query, sizeof(query), "select * from %s where qid = '%s'",pushQtbl,qid);
+sqlSafef(query, sizeof(query), "select * from %s where qid = '%s'",pushQtbl,qid);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 if (row)
     q = pushQLoad(row);
 sqlFreeResult(&sr);
 return q;
 }
 
 struct pushQ *mustLoadPushQ(char *qid)
 /* Load pushQ or die */
 {
 struct pushQ *q = loadPushQ(qid);
 if (!q)
     errAbort("loadPushQ: Queue Id %s not found.",qid);
 return q;
 }
 
 
 
 void doPushDone()
 /* Mark record pushState=D, move priority to L for Log, and set rank=0  */
 {
 
 struct pushQ *q;
 char query[256];
 
 q=mustLoadPushQ(cgiString("qid"));
 if (sameString(q->lockUser,"") && sameString(q->pushState,"Y"))
     { /* not already locked and pushState=Y */
 
-    safef(q->lastdate, sizeof(q->lastdate), q->qadate);
+    safef(q->lastdate, sizeof(q->lastdate), "%s", q->qadate);
     strftime (q->qadate  , sizeof(q->qadate  ), "%Y-%m-%d", loctime); /* today's date */
 
-    safef(query, sizeof(query),
+    sqlSafef(query, sizeof(query),
           "update %s set rank = 0, priority ='L', pushState='D', qadate='%s', lastdate='%s' "
           "where qid = '%s' ", pushQtbl, q->qadate, q->lastdate, q->qid);
     sqlUpdate(conn, query);
 
 
     /* first close the hole where it was */
-    safef(query, sizeof(query),
+    sqlSafef(query, sizeof(query),
           "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
           pushQtbl, q->priority, q->rank);
     sqlUpdate(conn, query);
     }
 else
     {
     if (sameString(q->lockUser,""))
 	{
     	safef(msg, sizeof(msg), "Unable to mark record %s done-> Record is locked by %s->",q->qid,q->lockUser);
 	}
     else
 	{
     	safef(msg, sizeof(msg), "Invalid operation for qid %s, pushState is not Y, = %s->",q->qid,q->pushState);
 	}
     }
@@ -1207,55 +1201,55 @@
 pushQFree(&q);
 
 doDisplay();
 }
 
 
 void XdoPromote(int change)
 /* Promote the ranking of this Q item
  * >0 means promote, <0 means demote */
 {
 
 struct pushQ *q;
 char query[256];
 char newQid[sizeof(q->qid)] = "";
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 q = mustLoadPushQ(newQid);
 
 if ((q->rank > 1) && (change>0))
     {
     /* swap places with rank-1 */
-    safef(query, sizeof(query), "update %s set rank = rank + 1 where priority ='%s' and rank = %d ",
+    sqlSafef(query, sizeof(query), "update %s set rank = rank + 1 where priority ='%s' and rank = %d ",
             pushQtbl, q->priority, q->rank-1);
     sqlUpdate(conn, query);
     q->rank--;
-    safef(query, sizeof(query), "update %s set rank = %d where qid ='%s'",
+    sqlSafef(query, sizeof(query), "update %s set rank = %d where qid ='%s'",
             pushQtbl, q->rank, q->qid);
     sqlUpdate(conn, query);
     }
 
 if (change<0)
     {
     /* swap places with rank+1 */
-    safef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank = %d ",
+    sqlSafef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank = %d ",
             pushQtbl, q->priority, q->rank+1);
     if (sqlUpdateRows(conn, query, NULL)>0)
         {
         q->rank++;
-        safef(query, sizeof(query), "update %s set rank = %d where qid ='%s'",
+        sqlSafef(query, sizeof(query), "update %s set rank = %d where qid ='%s'",
                 pushQtbl, q->rank, q->qid);
         sqlUpdate(conn, query);
         }
     }
 
 pushQFree(&q);
 
 doDisplay();
 }
 
 
 void doPromote()
 {
 XdoPromote(1);
 }
@@ -1263,217 +1257,157 @@
 void doDemote()
 {
 XdoPromote(-1);
 }
 
 
 
 
 int getNextAvailQid()
 /* adding new pushQ rec, get next available qid number */
 {
 struct pushQ q;
 int newqid = 0;
 char query[256];
 char *quickres = NULL;
-safef(query, sizeof(query), "select max(qid) from %s",pushQtbl);
+sqlSafef(query, sizeof(query), "select max(qid) from %s",pushQtbl);
 quickres = sqlQuickString(conn, query);
 if (quickres != NULL)
     {
-    safef(q.qid, sizeof(q.qid), quickres);
+    safef(q.qid, sizeof(q.qid), "%s", quickres);
     sscanf(q.qid,"%d",&newqid);
     freez(&quickres);
     }
 newqid++;
 return newqid;
 }
 
 int getNextAvailRank(char *priority)
 /* get next available rank at end of priority section */
 {
 struct pushQ q;
 char query[256];
 char *quickres = NULL;
-safef(query, sizeof(query),
+sqlSafef(query, sizeof(query),
     "select rank from %s where priority='%s' order by rank desc limit 1",
     pushQtbl, priority);
 quickres = sqlQuickString(conn, query);
 if (quickres == NULL)
     {
     q.rank = 0;
     }
 else
     {
     sscanf(quickres,"%d",&q.rank);
     freez(&quickres);
     }
 q.rank++;
 return q.rank;
 }
 
 
 void doTop()
 {
 
 struct pushQ *q;
 char query[256];
 char newQid[sizeof(q->qid)] = "";
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 q = mustLoadPushQ(newQid);
 
 /* first close the hole where it was */
-safef(query, sizeof(query), "update %s set rank = rank + 1 where priority ='%s' and rank < %d ",
+sqlSafef(query, sizeof(query), "update %s set rank = rank + 1 where priority ='%s' and rank < %d ",
         pushQtbl, q->priority, q->rank);
 sqlUpdate(conn, query);
 
 q->rank = 1;
-safef(query, sizeof(query), "update %s set rank = %d where qid = '%s' ",
+sqlSafef(query, sizeof(query), "update %s set rank = %d where qid = '%s' ",
         pushQtbl, q->rank, q->qid);
 sqlUpdate(conn, query);
 
 pushQFree(&q);
 
 doDisplay();
 }
 
 void doBottom()
 {
 
 struct pushQ *q;
 char query[256];
 char newQid[sizeof(q->qid)] = "";
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 q = mustLoadPushQ(newQid);
 
 /* first close the hole where it was */
-safef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
+sqlSafef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
         pushQtbl, q->priority, q->rank);
 sqlUpdate(conn, query);
 
 q->rank = getNextAvailRank(q->priority);
-safef(query, sizeof(query)," update %s set rank = %d where qid = '%s' ",
+sqlSafef(query, sizeof(query), "update %s set rank = %d where qid = '%s' ",
         pushQtbl, q->rank, q->qid);
 sqlUpdate(conn, query);
 
 pushQFree(&q);
 
 doDisplay();
 }
 
 
 /* too bad this isn't part of autoSql's code generation */
 
-void pushQUpdateEscaped(struct sqlConnection *conn, struct pushQ *el, char *tableName, int updateSize)
+void pushQUpdate(struct sqlConnection *conn, struct pushQ *el, char *tableName, int updateSize)
 /* Update pushQ 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 pushQSaveToDb().
  * For example automatically copies and converts:
  * "autosql's features include" --> "autosql\'s features include"
  * before inserting into database. */
 {
 struct dyString *update = newDyString(updateSize);
-char  *qid, *pqid, *priority, *qadate, *newYN, *track, *dbs, *tbls, *cgis, *files, *currLoc, *makeDocYN, *onlineHelp, *ndxYN, *joinerYN, *stat, *featureBits, *sponsor, *reviewer, *extSource, *openIssues, *notes, *pushState, *initdate, *lastdate, *lockUser, *lockDateTime, *releaseLog, *releaseLogUrl, *importance;
-qid = sqlEscapeString(el->qid);
-pqid = sqlEscapeString(el->pqid);
-priority = sqlEscapeString(el->priority);
-qadate = sqlEscapeString(el->qadate);
-newYN = sqlEscapeString(el->newYN);
-track = sqlEscapeString(el->track);
-dbs = sqlEscapeString(el->dbs);
-tbls = sqlEscapeString(el->tbls);
-cgis = sqlEscapeString(el->cgis);
-files = sqlEscapeString(el->files);
-currLoc = sqlEscapeString(el->currLoc);
-makeDocYN = sqlEscapeString(el->makeDocYN);
-onlineHelp = sqlEscapeString(el->onlineHelp);
-ndxYN = sqlEscapeString(el->ndxYN);
-joinerYN = sqlEscapeString(el->joinerYN);
-stat = sqlEscapeString(el->stat);
-featureBits = sqlEscapeString(el->featureBits);
-sponsor = sqlEscapeString(el->sponsor);
-reviewer = sqlEscapeString(el->reviewer);
-extSource = sqlEscapeString(el->extSource);
-openIssues = sqlEscapeString(el->openIssues);
-notes = sqlEscapeString(el->notes);
-pushState = sqlEscapeString(el->pushState);
-initdate = sqlEscapeString(el->initdate);
-lastdate = sqlEscapeString(el->lastdate);
-lockUser = sqlEscapeString(el->lockUser);
-lockDateTime = sqlEscapeString(el->lockDateTime);
-releaseLog = sqlEscapeString(el->releaseLog);
-releaseLogUrl = sqlEscapeString(el->releaseLogUrl);
-importance = sqlEscapeString(el->importance);
 
 /* had to split this up because dyStringPrintf only up to 4000 chars at one time */
-dyStringPrintf(update,
+sqlDyStringPrintf(update,
     "update %s set "
     "pqid='%s',priority='%s',rank=%u,qadate='%s',newYN='%s',track='%s',",
-    tableName,  pqid,  priority, el->rank,  qadate, newYN, track);
-dyStringPrintf(update, "dbs='%s',",dbs);
-dyStringPrintf(update, "tbls='%s',",tbls);
-dyStringPrintf(update, "cgis='%s',",cgis);
-dyStringPrintf(update, "files='%s',",files);
-dyStringPrintf(update, "sizeMB=%u,currLoc='%s',"
+    tableName,  el->pqid,  el->priority, el->rank,  el->qadate, el->newYN, el->track);
+sqlDyStringPrintf(update, "dbs='%s',",el->dbs);
+sqlDyStringPrintf(update, "tbls='%s',",el->tbls);
+sqlDyStringPrintf(update, "cgis='%s',",el->cgis);
+sqlDyStringPrintf(update, "files='%s',",el->files);
+sqlDyStringPrintf(update, "sizeMB=%u,currLoc='%s',"
     "makeDocYN='%s',onlineHelp='%s',ndxYN='%s',joinerYN='%s',stat='%s',"
     "sponsor='%s',reviewer='%s',extSource='%s',",
-    el->sizeMB ,  currLoc,  makeDocYN,
-    onlineHelp,  ndxYN,  joinerYN,  stat,
-    sponsor,  reviewer,  extSource);
-dyStringPrintf(update, "openIssues='%s',",openIssues);
-dyStringPrintf(update, "notes='%s',",notes);
-dyStringPrintf(update, "pushState='%s', initdate='%s', lastdate='%s', bounces='%u',lockUser='%s',"
+    el->sizeMB ,  el->currLoc,  el->makeDocYN,
+    el->onlineHelp,  el->ndxYN,  el->joinerYN,  el->stat,
+    el->sponsor,  el->reviewer,  el->extSource);
+sqlDyStringPrintf(update, "openIssues='%s',",el->openIssues);
+sqlDyStringPrintf(update, "notes='%s',",el->notes);
+sqlDyStringPrintf(update, "pushState='%s', initdate='%s', lastdate='%s', bounces='%u',lockUser='%s',"
                        "lockDateTime='%s',releaseLog='%s',featureBits='%s',releaseLogUrl='%s',"
                        "importance='%s' where qid='%s'",
-                       pushState, initdate, lastdate, el->bounces, lockUser, lockDateTime,
-                       releaseLog, featureBits, releaseLogUrl, importance, qid	);
+                       el->pushState, el->initdate, el->lastdate, el->bounces, el->lockUser, el->lockDateTime,
+                       el->releaseLog, el->featureBits, el->releaseLogUrl, el->importance, el->qid	);
 
 sqlUpdate(conn, update->string);
 freeDyString(&update);
-freez(&qid);
-freez(&pqid);
-freez(&priority);
-freez(&qadate);
-freez(&newYN);
-freez(&track);
-freez(&dbs);
-freez(&tbls);
-freez(&cgis);
-freez(&files);
-freez(&currLoc);
-freez(&makeDocYN);
-freez(&onlineHelp);
-freez(&ndxYN);
-freez(&joinerYN);
-freez(&stat);
-freez(&sponsor);
-freez(&reviewer);
-freez(&extSource);
-freez(&openIssues);
-freez(&notes);
-freez(&pushState);
-freez(&initdate);
-freez(&lastdate);
-freez(&lockUser);
-freez(&lockDateTime);
-freez(&releaseLog);
-freez(&releaseLogUrl);
-freez(&importance);
 }
 
 void getCgiData(bool *isOK, bool isPtr, void *ptr, int size, char *name)
 /* get data, truncate to fit in field to prevent safef buf overflows */
 {
 int l = 0;
 char **pfld = NULL;
 char *fld = NULL;
 char *cgi = NULL;
 cgi = cgiString(name);
 l = strlen(cgi);
 if (isPtr)
     {
     pfld = (char **) ptr;
     }
@@ -1483,31 +1417,31 @@
     }
 if (size != -1)  /* -1 for blob, has no length */
     {
     if (l>(size-1))
 	{
 	*isOK = FALSE;
 	safef(msg,sizeof(msg),"%s: too large, max. %d chars.",name,size-1);
 	}
     }
 if (isPtr)
     {
     *pfld = cloneString(cgi);  /* set pointer to a copy of the whole thing */
     }
 else
     {
-    safef(fld, size, cloneStringZ(cgi,size-1));  /* for non-ptr strings, copy into existing buffer */
+    safef(fld, size, "%s", cloneStringZ(cgi,size-1));  /* for non-ptr strings, copy into existing buffer */
     }
 }
 
 
 
 void doTransfer();    /* forward reference needed */
 
 void doShowSizes();  /* forward reference needed */
 
 void doEdit();       /* forward reference needed */
 
 void doPost()
 /* handle the  post (really just a get for now) from Add or Edit of a pushQ record */
 {
 
@@ -1524,110 +1458,110 @@
 char *lockbutton   = cgiUsualString("lockbutton"  ,"");
 char *cancelbutton   = cgiUsualString("cancelbutton"  ,"");
 char *showSizes    = cgiUsualString("showSizes"   ,"");
 char *transfer     = cgiUsualString("transfer"   ,"");
 
 struct pushQ *q;
 
 bool isNew  = FALSE;   /* new rec */
 bool isRedo = FALSE;   /* need to return to edit form with error msg */
 bool isOK   = TRUE;    /* is data valid length (not too large) */
 bool lockOK = TRUE;    /* assume for now lock state OK */
 
 char newQid     [sizeof(q->qid)]      = "";
 char newPriority[sizeof(q->priority)] = "";
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 if (sameString(newQid,""))
     {
     isNew = TRUE;
     }
 else
     {
     isNew = FALSE;
     }
 
 if (!isNew)
     {
     /* we need to preload q with existing values
      * because some fields like rank are not carried in form
     */
     q = mustLoadPushQ(newQid);
         /* true means optional, it was asked if we could tolerate this,
          *  e.g. delete, then hit back-button
          * user is trying to use back button to recover deleted rec
-        safef(newQid, sizeof(newQid), "");
+        safef(newQid, sizeof(newQid), "%s", "");
         isNew = TRUE;
         */
 
     /* check lock status */
 
     if (sameString(cancelbutton,"Cancel"))  /* user cancelled */
 	{  /* unlock record */
 	safef(q->lockUser, sizeof(q->lockUser), "%s", "");
 	safef(q->lockDateTime, sizeof(q->lockDateTime), "%s", "");
-	pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+	pushQUpdate(conn, q, pushQtbl, updateSize);
 	lockOK = FALSE;
 	}
     else if (sameString(lockbutton,"Lock"))  /* try to lock the record for editing */
 	{
 	if (sameString(q->lockUser,""))  /* q->lockUser blank if nobody has lock */
 	    {
-	    safef(q->lockUser, sizeof(q->lockUser), qaUser);
+	    safef(q->lockUser, sizeof(q->lockUser), "%s", qaUser);
 	    strftime(q->lockDateTime, sizeof(q->lockDateTime), "%Y-%m-%d %H:%M", loctime);
-	    pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+	    pushQUpdate(conn, q, pushQtbl, updateSize);
 	    lockOK = FALSE;
 	    }
 	else
 	    { /* somebody else has lock-> */
 	    lockOK = FALSE;
 	    }
 	}
     else if (!sameString(q->lockUser,qaUser))  /* User supposed to already have lock, verify. */
 	{ /* if lock was lost, what do we do now? */
 	if (sameString(q->lockUser,""))
 	    {
-	    safef(msg,sizeof(msg),"Lost lock-> Must refresh data->");
+	    safef(msg,sizeof(msg), "%s", "Lost lock-> Must refresh data->");
 	    }
 	else
 	    {
 	    safef(msg,sizeof(msg),"Lost lock-> User %s currently has lock on Queue Id %s since %s->",
 		q->lockUser,q->qid,q->lockDateTime);
 	    }
 	lockOK = FALSE;
 	}
 
     if (!lockOK)
 	{
 	doEdit();
 	pushQFree(&q);
 	return;
 	}
 
     }
 
 if (isNew)
     {
     AllocVar(q);
     newqid = getNextAvailQid();
     safef(q->pqid, sizeof(q->pqid), "%s", "");
     safef(q->pushState,sizeof(q->pushState),"N");  /* default to: push not done yet */
     }
 
 
-safef(newPriority, sizeof(newPriority), cgiString("priority"));
+safef(newPriority, sizeof(newPriority), "%s", cgiString("priority"));
 
 
 /* dates */
 getCgiData(&isOK, FALSE, q->qadate    , sizeof(q->qadate    ), "qadate"    );
 getCgiData(&isOK, FALSE, q->initdate  , sizeof(q->initdate  ), "initdate"  );
 
 /* YN select listboxes */
 getCgiData(&isOK, FALSE, q->newYN     , sizeof(q->newYN     ), "newYN"     );
 getCgiData(&isOK, FALSE, q->makeDocYN , sizeof(q->makeDocYN ), "makeDocYN" );
 getCgiData(&isOK, FALSE, q->ndxYN     , sizeof(q->ndxYN     ), "ndxYN"     );
 getCgiData(&isOK, FALSE, q->joinerYN  , sizeof(q->joinerYN  ), "joinerYN"  );
 getCgiData(&isOK, FALSE, q->importance, sizeof(q->importance), "importance"  );
 
 /* chr(255) strings */
 getCgiData(&isOK, TRUE ,&q->track     , 256                 , "track"     );
@@ -1737,126 +1671,126 @@
     isRedo = TRUE;
     }
 
 
 if (isRedo)
     {
     replacePushQFields(q, isNew);
     pushQFree(&q);
     return;
     }
 
 
 if (sameString(bouncebutton,"bounce"))
     {
     safef(newPriority, sizeof(newPriority), "B");
-    safef(q->lastdate, sizeof(q->lastdate), q->qadate);
+    safef(q->lastdate, sizeof(q->lastdate), "%s", q->qadate);
     strftime (q->qadate, sizeof(q->qadate), "%Y-%m-%d", loctime); /* set to today's date */
     q->bounces++;
     }
 if (sameString(bouncebutton,"unbounce"))
     {
     safef(newPriority, sizeof(newPriority), "A");
-    safef(q->lastdate, sizeof(q->lastdate), q->qadate);
+    safef(q->lastdate, sizeof(q->lastdate), "%s", q->qadate);
     strftime (q->qadate, sizeof(q->qadate), "%Y-%m-%d", loctime); /* set to today's date */
     }
 
 
 /* check if priority class has changed, or deleted, then close ranks */
 if ( (!sameString(newPriority,q->priority)) || (sameString(delbutton,"delete")) )
     {
     /* first close the hole where it was */
-    safef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
+    sqlSafef(query, sizeof(query), "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
             pushQtbl, q->priority, q->rank);
     sqlUpdate(conn, query);
     }
 
 /* if not deleted, then if new or priority class change, then take last rank */
 if (!sameString(delbutton,"delete"))
     {
     if ((!sameString(newPriority,q->priority)) || isNew)
 	{
 	q->rank = getNextAvailRank(newPriority);
-	safef(q->priority, sizeof(q->priority), newPriority);
+	safef(q->priority, sizeof(q->priority), "%s", newPriority);
 	}
     }
 
 if (q->priority[0]=='L')
     {
     q->rank = 0;
     }
 
 
 if (sameString(pushbutton,"push requested"))
     {
     /* reset pushState in case was prev-> a log already */
     safef(q->pushState,sizeof(q->pushState),"Y");
     }
 
 if (sameString(delbutton,"delete"))
     {
     /* delete old record */
-    safef(query, sizeof(query), "delete from %s where qid ='%s'", pushQtbl, q->qid);
+    sqlSafef(query, sizeof(query), "delete from %s where qid ='%s'", pushQtbl, q->qid);
     sqlUpdate(conn, query);
     }
 else
     {
     if (sameString(showSizes,"Show Sizes") || sameString(transfer,"Transfer"))
 	{ /* mark record as locked */
-	safef(q->lockUser, sizeof(q->lockUser), qaUser);
+	safef(q->lockUser, sizeof(q->lockUser), "%s", qaUser);
 	strftime(q->lockDateTime, sizeof(q->lockDateTime), "%Y-%m-%d %H:%M", loctime);
 	}
     else
 	{ /* unlock record */
 	safef(q->lockUser, sizeof(q->lockUser), "%s", "");
 	safef(q->lockDateTime, sizeof(q->lockDateTime), "%s", "");
 	}
     if (isNew)
 	{
 	/* save new record */
 	safef(msg, sizeof(msg), "%%0%dd", (int)sizeof(q->qid)-1);
 	safef(newQid,sizeof(newQid),msg,newqid);
-	safef(q->qid, sizeof(q->qid), newQid);
+	safef(q->qid, sizeof(q->qid), "%s", newQid);
     	safef(msg, sizeof(msg), "%s", "");
-	pushQSaveToDbEscaped(conn, q, pushQtbl, updateSize);
+	pushQSaveToDb(conn, q, pushQtbl, updateSize);
 	}
     else
 	{
 	/* update existing record */
-	pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+	pushQUpdate(conn, q, pushQtbl, updateSize);
 	}
     }
 
 if (sameString(clonebutton,"clone"))
     {
     /* save new clone */
-    safef(q->pqid,sizeof(q->pqid), q->qid);  /* daughter will point to parent */
+    safef(q->pqid,sizeof(q->pqid), "%s", q->qid);  /* daughter will point to parent */
     newqid = getNextAvailQid();
     safef(msg, sizeof(msg), "%%0%dd", (int)sizeof(q->qid)-1);
     safef(newQid,sizeof(newQid),msg,newqid);
-    safef(q->qid, sizeof(q->qid), newQid);
+    safef(q->qid, sizeof(q->qid), "%s", newQid);
     safef(msg, sizeof(msg), "%s", "");
     if (q->priority[0]=='L')
 	{
 	q->rank = 0;
 	}
     else
 	{
 	q->rank = getNextAvailRank(q->priority);
 	}
     safef(q->pushState,sizeof(q->pushState),"N");  /* default to: push not done yet */
-    pushQSaveToDbEscaped(conn, q, pushQtbl, updateSize);
+    pushQSaveToDb(conn, q, pushQtbl, updateSize);
     }
 
 
 if (sameString(showSizes,"Show Sizes"))
     {
     cgiVarSet("qid", q->qid); /* for new rec */
     doShowSizes();
     }
 
 else if (sameString(transfer,"Transfer"))
     {
     cgiVarSet("qid", q->qid); /* for new rec */
     doTransfer();
     }
 
@@ -1891,67 +1825,67 @@
     printf("Queue Id %s not found.", cgiString("qid"));
     return;
     }
 
 if ( sameString(qaUser,"kuhn") ||
      sameString(qaUser,"kuhn2") ||
      sameString(qaUser,"mary") ||
      sameString(qaUser,"ann") ||
      sameString(qaUser,"antonio")
      )  /* for users that want to automatically try to lock record immediately */
     {
     if (sameString(action,"edit") || sameString(action,"setSize"))
 	{
 	if (sameString(q->lockUser,""))  /* q->lockUser blank if nobody has lock */
 	    {
-	    safef(q->lockUser, sizeof(q->lockUser), qaUser);
+	    safef(q->lockUser, sizeof(q->lockUser), "%s", qaUser);
 	    strftime(q->lockDateTime, sizeof(q->lockDateTime), "%Y-%m-%d %H:%M", loctime);
-	    pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+	    pushQUpdate(conn, q, pushQtbl, updateSize);
 	    }
 	}
     else /* we are coming back from a post? so return to display automatically */
 	{
 	doDisplay();
 	return;  /* this is needed? */
 	}
     }
 
 replacePushQFields(q, FALSE);  /* new rec = false */
 pushQFree(&q);
 }
 
 void doSetSize()
 /* save sizeMB */
 {
 struct pushQ *q;
 char tempSizeMB[10];
 int updateSize=2456;
 q = loadPushQ(cgiString("qid"));
 if (!q)
     {
     printf("Queue Id %s not found.", cgiString("qid"));
     return;
     }
-safef(tempSizeMB,sizeof(tempSizeMB), cgiUsualString("sizeMB",""));
+safef(tempSizeMB,sizeof(tempSizeMB), "%s", cgiUsualString("sizeMB",""));
 if (!sameString(tempSizeMB,""))
     {
     if (sscanf(tempSizeMB,"%u",&q->sizeMB) != 1)
 	{
 	q->sizeMB = 0;
 	}
     }
-pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+pushQUpdate(conn, q, pushQtbl, updateSize);
 doEdit();
 pushQFree(&q);
 }
 
 
 void doLogin()
 /* make form for login */
 {
 printf("<h4>Login</h4>\n");
 
 printf("<FORM ACTION=\"/cgi-bin/qaPushQ\" NAME=\"loginForm\" METHOD=\"POST\">\n");
 
 printf("<input TYPE=\"hidden\" NAME=\"action\" VALUE=\"postLogin\"  >\n");
 
 printf("<TABLE cellpadding=6>\n");
@@ -2019,31 +1953,31 @@
 {
 htmlSetCookie("qapushq", "", NULL, NULL, ".cse.ucsc.edu", FALSE);
 htmShell(TITLE, doLogoutMsg, NULL);
 }
 
 
 
 
 bool readAUser(struct users *u, bool optional)
 /* read data for my user */
 {
 char query[256];
 char **row;
 struct sqlResult *sr;
 
-safef(query, sizeof(query), "select * from users where user = '%s'",u->user);
+sqlSafef(query, sizeof(query), "select * from users where user = '%s'",u->user);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 if (row == NULL)
     {
     if (optional)
 	{
 	sqlFreeResult(&sr);
 	return FALSE;
 	}
     else
 	{
 	errAbort("%s not found.",u->user);
 	}
     }
 else
@@ -2055,53 +1989,53 @@
 }
 
 
 void readMyUser()
 /* read data for my user */
 {
 int i = 1;  /* because it should start right off with ? */
 char tempVar[2048];
 char tempVarName[256];
 char tempVal[2048];
 
 if ((qaUser == NULL) || (sameString(qaUser,"")))
     {
     return;
     }
-safef(myUser.user,sizeof(myUser.user),qaUser);
+safef(myUser.user, sizeof(myUser.user), "%s", qaUser);
 readAUser(&myUser, FALSE);
 
 while(parseList(myUser.contents,'?',i,tempVar,sizeof(tempVar)))
     {
 
     parseList(tempVar,'=',0,tempVarName,sizeof(tempVarName));
 
     parseList(tempVar,'=',1,tempVal,sizeof(tempVal));
 
     if (sameString(tempVarName,"showColumns"))
 	{
 	showColumns = cloneString(tempVal);
 	}
 
     if (sameString(tempVarName,"org"))
 	{
-	safef(pushQtbl,sizeof(pushQtbl),tempVal);
+	safef(pushQtbl, sizeof(pushQtbl), "%s", tempVal);
 	}
 
     if (sameString(tempVarName,"month"))
 	{
-	safef(month,sizeof(month),tempVal);
+	safef(month, sizeof(month), "%s", tempVal);
 	}
 
     if (sameString(tempVarName,"oldRandState"))
 	{
 	oldRandState = cloneString(tempVal);
 	}
 
     i++;
     }
 }
 
 void saveMyUser();  /* forward declaration */
 
 void doPostLogin()
 /* process Login post */
@@ -2115,51 +2049,51 @@
 char *userPassword = NULL;
 bool loginOK = FALSE;
 char *meta = ""
 "<head>"
 "<title>"
 "Meta Redirect Code"
 "</title>"
 "<meta http-equiv=\"refresh\" content=\"0;url=/cgi-bin/qaPushQ\">"
 "</head>";
 
 userPassword = cgiString("password");
 
 ZeroVar(&u);
 
 u.next = NULL;
-safef(u.user,  sizeof(u.user), cgiString("user"));
+safef(u.user,  sizeof(u.user), "%s", cgiString("user"));
 
 conn = sqlConnectRemote(host, user, password, database);  /* do db conn here special for login */
 
 if (!readAUser(&u, TRUE))
     {
     /* unknown user not allowed */
     safef(msg,sizeof(msg),"Invalid user or password.");
     }
 else
     {
     if (strlen(u.password)==0)
 	{ /* if pwd in db is blank, use this as their new password and encrypt it and save in db. */
 	if (strlen(userPassword) < 6)
 	    { /* bad pwd */
 	    safef(msg,sizeof(msg),"Invalid password. Password must be at least 6 characters long.");
 	    }
         else
             {
             encryptNewPWD(userPassword, u.password, sizeof(u.password));
-            safef(query, sizeof(query), "update %s set password = '%s' where user = '%s' ",
+            sqlSafef(query, sizeof(query), "update %s set password = '%s' where user = '%s' ",
                     tbl, u.password, u.user);
             sqlUpdate(conn, query);
             loginOK = TRUE;
             }
 	}
     else
 	{ /* verify password matches db */
         if (checkPWD(userPassword, u.password))
 	    { /* good pwd, save user in cookie */
 	    loginOK = TRUE;
 	    }
 	else
 	    { /* bad pwd */
 	    safef(msg,sizeof(msg),"Invalid user or password.");
 	    }
@@ -2189,96 +2123,96 @@
 sqlDisconnect(&conn);
 }
 
 
 
 void saveMyUser()
 /* read data for my user */
 {
 char *tbl = "users";
 struct dyString * query = NULL;
 query = newDyString(2048);
 if ((qaUser == NULL) || (sameString(qaUser,"")))
     {
     return;
     }
-dyStringPrintf(query,
+sqlDyStringPrintf(query,
     "update %s set contents = '?showColumns=%s?org=%s?month=%s?oldRandState=%s' where user = '%s'",
     tbl, showColumns, pushQtbl, month, oldRandState, myUser.user);
 sqlUpdate(conn, query->string);
 freeDyString(&query);
 }
 
 
 
 
 void XdoPromoteColumn(int change)
 /* Promote the column
  * 1 = promote, 0 = hide, -1 = demote */
 {
 char target[256] = "";
 
 int i = 0;
 char tempBefore[256] = "";
 char tempVal   [256] = "";
 char tempAfter [256] = "";
 char tempSwap  [256] = "";
 struct dyString * s = NULL;
 s = newDyString(2048);  /* need room */
 
-safef(target, sizeof(target), cgiString("col"));
+safef(target, sizeof(target), "%s", cgiString("col"));
 
 while(TRUE)
     {
     parseList(showColumns,',',i,tempAfter,sizeof(tempAfter));
     if ((tempBefore[0]==0) && (tempVal[0]==0) && (tempAfter[0]==0))
 	{
 	break;
 	}
     if (sameString(target,tempVal))
 	{
 
 	if (change==1)
 	    {
 	    /*  swap places with Before */
-	    safef(tempSwap  , sizeof(tempSwap  ), tempBefore);
-	    safef(tempBefore, sizeof(tempBefore), tempVal   );
-	    safef(tempVal   , sizeof(tempVal   ), tempSwap  );
+	    safef(tempSwap  , sizeof(tempSwap  ), "%s", tempBefore);
+	    safef(tempBefore, sizeof(tempBefore), "%s", tempVal   );
+	    safef(tempVal   , sizeof(tempVal   ), "%s", tempSwap  );
 	    }
 	if (change==0)
 	    {
 	    /* remove */
 	    tempVal[0]=0;  /* set to empty string, output will be skipped */
 	    }
 	if (change==-1)
 	    {
 	    /* swap places with After */
-	    safef(tempSwap  , sizeof(tempSwap  ), tempAfter );
-	    safef(tempAfter , sizeof(tempAfter ), tempVal   );
-	    safef(tempVal   , sizeof(tempVal   ), tempSwap  );
+	    safef(tempSwap  , sizeof(tempSwap  ), "%s", tempAfter );
+	    safef(tempAfter , sizeof(tempAfter ), "%s", tempVal   );
+	    safef(tempVal   , sizeof(tempVal   ), "%s", tempSwap  );
 	    }
 
 	change = 99;  /* just suppress any more changes */
 
 	}
     if (!sameString(tempBefore,""))
 	{
 	dyStringPrintf(s, "%s,", tempBefore);
 	}
     /* roll 'em! */
-    safef(tempBefore, sizeof(tempBefore), tempVal  );
-    safef(tempVal   , sizeof(tempVal)   , tempAfter);
+    safef(tempBefore, sizeof(tempBefore), "%s", tempVal  );
+    safef(tempVal   , sizeof(tempVal)   , "%s", tempAfter);
     i++;
     }
 
 showColumns = cloneString(s->string);
 freeDyString(&s);
 
 showColumns[strlen(showColumns)-1]=0;  /* chop off trailing comma */
 
 doDisplay();
 
 }
 
 
 void doPromoteColumn()
 {
@@ -2368,56 +2302,56 @@
 
 
 void doShowMonths()
 /* This gives the user a choice of months to filter on */
 {
 
 struct sqlResult *sr;
 char **row;
 char query[256];
 
 printf("<h4>Logs for Month</h4>\n");
 printf("<br>\n");
 printf("<A href=qaPushQ?action=display&month=current&cb=%s>Current</A><br>\n", newRandState);
 printf("<br>\n");
 
-safef(query, sizeof(query), "select distinct substring(qadate,1,7) from %s where priority='L' order by qadate desc",pushQtbl);
+sqlSafef(query, sizeof(query), "select distinct substring(qadate,1,7) from %s where priority='L' order by qadate desc",pushQtbl);
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     printf("<A href=qaPushQ?action=display&month=%s&cb=%s>%s</A><br>\n",row[0],newRandState,row[0]);
     }
 sqlFreeResult(&sr);
 printf("<br>\n");
 printf("<a href=\"/cgi-bin/qaPushQ?cb=%s\">RETURN</a><br>", newRandState);
 }
 
 
 
 void getIndexes(struct sqlConnection *conn, char *tbl, char *s, int ssize)
 /* Get indexes with show index on table command. Return -1 if err.
  * Will match multiple if "%" used in tbl */
 {
 char query[256];
 char **row;
 struct sqlResult *sr;
 char *fld = NULL;
 int f = 0, i = 0, n = 0, c = 0;
 char lastKeyName[256]="";
 
 
-safef(query, sizeof(query), "show index from %s",tbl);
+sqlSafef(query, sizeof(query), "show index from %s",tbl);
 sr = sqlGetResult(conn, query);
 f = 0;
 i = 0;
 n = 0;
 if (ssize > 0) s[0]=0;
 while ((fld = sqlFieldName(sr)) != NULL)
     {
     if (sameString(fld,"Key_name"))
 	{
 	n = f;
 	}
     if (sameString(fld,"Column_name"))
 	{
 	i = f;
 	}
@@ -2426,56 +2360,56 @@
 while ((row = sqlNextRow(sr)) != NULL)
     {
     c++;
     if (sameString(row[n],lastKeyName))
     	{
 	strcat(s,"+");
 	strcat(s,row[i]);
 	}
     else
 	{
 	if (c > 1)
 	    {
 	    strcat(s,", ");
 	    }
 	strcat(s, row[i]);
-	safef(lastKeyName,sizeof(lastKeyName),row[n]);
+	safef(lastKeyName, sizeof(lastKeyName), "%s", row[n]);
 	}
     }
 sqlFreeResult(&sr);
 sqlDisconnect(&conn);
 }
 
 
 
 void mySprintWithCommas(char *s, int slength, long long size)
 /* the one in obscure.c was overflowing, so here's mine  */
 {
 char *temp=NULL;
 char sep[2]="";
 s[0]=0;
 temp = needMem(slength);
 while (size >= 1000)
     {
-    safef(temp,slength,s);
+    safef(temp, slength, "%s", s);
     safef(s,slength,"%03d%s%s",(int)(size%1000),sep,temp);
     size/=1000;
     safef(sep,sizeof(sep),",");
     }
 if (size > 0)
     {
-    safef(temp,slength,s);
+    safef(temp, slength, "%s", s);
     safef(s,slength,"%3d%s%s",(int)size,sep,temp);
     }
 else
     {
     safef(s,slength,"0");  /* special case zero*/
     }
 freez(&temp);
 }
 
 
 
 long long pq_getTableSize(char *rhost, char *db, char *tbl, int *errCount)  /* added extension pq_ to supress name conflict in hdb.c */
 /* Get table size via show table status command. Return -1 if err.
  * Will match multiple if "%" used in tbl */
 {
@@ -2503,31 +2437,31 @@
     {
     host     = "hgwdev";
     user     = cfgOption("db.user"    );
     password = cfgOption("db.password");
     }
 
 if ((sameString(utsName.nodename,"hgwdev")) && (sameString(rhost,"hgwbeta")))
     {  // inaccurate but doesn't matter since we only use it to test qaPushQ cgi on dev.
     host     = cfgOption("central.host"    );
     user     = cfgOption("central.user"    );
     password = cfgOption("central.password");
     }
 
 conn = sqlConnectRemote(host, user, password, db);
 
-safef(query, sizeof(query), "show table status like '%s'",tbl);
+sqlSafef(query, sizeof(query), "show table status like '%s'",tbl);
 sr = sqlGetResult(conn, query);
 f = 0;
 d = 0;
 i = 0;
 n = 0;
 while ((fld = sqlFieldName(sr)) != NULL)
     {
     if (sameString(fld,"Name"))
 	{
 	n = f;
 	}
     if (sameString(fld,"Data_length"))
 	{
 	d = f;
 	}
@@ -2650,31 +2584,31 @@
 char tempVal[BLSIZE];
 char c;
 
 char gComma[BLSIZE];
 char gSpace[BLSIZE];
 char gVal[BLSIZE];
 char gc;
 char cgiPath[1024];
 char pathName[1024];
 char filePath[1024];
 char fileName[1024];
 char *found=NULL;
 struct fileInfo *fi = NULL;
 char *crossUrl = "";
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 printf("<H2>Show File Sizes </H2>\n");
 
 q = mustLoadPushQ(newQid);
 
 if (crossPost)  // support showSizes across machines
     {
     crossUrl = sameString(utsName.nodename, "hgwdev") ? "http://hgwbeta.cse.ucsc.edu" : "http://hgwdev.cse.ucsc.edu";
     }
 
 printf("<a href=\"%s/cgi-bin/qaPushQ?action=showSizesHelp&qid=%s&cb=%s\" target=\"_blank\">HELP</a> \n",
     crossUrl,q->qid,newRandState);
 printf("<a href=\"%s/cgi-bin/qaPushQ?action=edit&qid=%s&cb=%s\">RETURN</a> \n",crossUrl,newQid,newRandState);
 printf(" <br>\n");
 printf("Location: %s <br>\n",q->currLoc);
@@ -3046,31 +2980,31 @@
 
 }
 
 
 void listQueues(char *action, boolean isTransfer);  /* forward decl */
 
 void doTransfer()
 /* Present choice of queues to which the selected and locked record may be transferred */
 {
 struct pushQ *q;
 char newQid[sizeof(q->qid)] = "";
 char tempUrl[256];
 
 ZeroVar(&q);
 
-safef(newQid, sizeof(newQid), cgiString("qid"));
+safef(newQid, sizeof(newQid), "%s", cgiString("qid"));
 
 printf("<H2>Transfer Queue Entry %s:%s to Another Queue </H2>\n", pushQtbl, newQid);
 
 q=mustLoadPushQ(newQid);
 
 printf("<a href=\"/cgi-bin/qaPushQ?action=edit&qid=%s&cb=%s\">RETURN</a> \n",newQid,newRandState);
 printf("<br>\n");
 printf("<br>\n");
 
 safef(tempUrl, sizeof(tempUrl), "action=transferTo&qid=%s&toOrg", newQid);
 listQueues(tempUrl, TRUE);
 
 printf("<a href=\"/cgi-bin/qaPushQ?action=edit&qid=%s&cb=%s\">RETURN</a> <br>\n",newQid,newRandState);
 pushQFree(&q);
 }
@@ -3082,68 +3016,68 @@
 struct pushQ *q;
 int updateSize = 2456; /* almost anything works here */
 char *toOrg = cgiString("toOrg");  /* required cgi var */
 char *origQid = NULL;
 int newqid = 0;
 char newQid     [sizeof(q->qid)]      = "";
 char *savePushQtbl = cloneString(pushQtbl);
 char query[256];
 
 origQid = cloneString(cgiString("qid"));  /* required cgi var */
 
 /* get the data from the record */
 q = mustLoadPushQ(origQid);
 
 /* first close the hole where it was */
-safef(query, sizeof(query),
+sqlSafef(query, sizeof(query),
 "update %s set rank = rank - 1 where priority ='%s' and rank > %d ",
 pushQtbl, q->priority, q->rank);
 sqlUpdate(conn, query);
 
 /* delete old record */
-safef(query, sizeof(query), "delete from %s where qid ='%s'", pushQtbl, origQid);
+sqlSafef(query, sizeof(query), "delete from %s where qid ='%s'", pushQtbl, origQid);
 sqlUpdate(conn, query);
 
 /* temporarily set pushQtbl to target */
 safef(pushQtbl, sizeof(pushQtbl), "%s",toOrg);
 
 /* unlock record - don't want it to keep the lock status after xfer */
 safef(q->lockUser, sizeof(q->lockUser), "%s","");
 safef(q->lockDateTime, sizeof(q->lockDateTime), "%s","");
 
 /* get the maxQid from the target Q tbl */
 newqid = getNextAvailQid();
 safef(msg, sizeof(msg), "%%0%dd", (int)sizeof(q->qid)-1);
 safef(newQid,sizeof(newQid),msg,newqid);
-safef(q->qid, sizeof(q->qid), newQid);
+safef(q->qid, sizeof(q->qid), "%s", newQid);
 safef(msg, sizeof(msg), "%s", "");
 
 /* get the maxrank from the target Q tbl for given priority */
 if (q->priority[0]=='L')
     {
     q->rank = 0;
     }
 else
     {
     q->rank = getNextAvailRank(q->priority);
     }
 
 /* clear parent link since can not be maintained */
 safef(q->pqid, sizeof(q->pqid), "%s", "");
 
 /* save record into new target Q */
-pushQSaveToDbEscaped(conn, q, pushQtbl, updateSize);
+pushQSaveToDb(conn, q, pushQtbl, updateSize);
 
 /* restore pushQtbl */
 safef(pushQtbl, sizeof(pushQtbl), "%s", savePushQtbl);
 
 /* set msg to display the new Qid to the user, visible on return */
 safef(msg,sizeof(msg),"Transferred %s Qid %s to %s Qid %s. <br>\n", pushQtbl, origQid, toOrg, q->qid);
 
 doDisplay();
 
 freez(&origQid);
 freez(&savePushQtbl);
 pushQFree(&q);
 }
 
 
@@ -3175,31 +3109,31 @@
 printf("v - click to lower the priority.<br>\n");
 printf("T - click to raise to top priority.<br>\n");
 printf("B - click to lower to bottom priority.<br>\n");
 printf("<br>\n");
 printf("Queue Id - click to edit or see the details page for the record.<br>\n");
 printf("<br>\n");
 printf("<a href=\"javascript:window.close();\" >CLOSE</a> <br>\n");
 }
 
 
 void doShowEditHelp()
 /* show the sizes of all the track tables, cgis, and general files in separate window target= _blank  */
 {
 struct pushQ q;
 ZeroVar(&q);
-safef(q.qid,sizeof(q.qid),cgiString("qid"));
+safef(q.qid, sizeof(q.qid), "%s", cgiString("qid"));
 printf("<h4>Details/Edit Help</h4>\n");
 printf("<br>\n");
 printf("CANCEL - click to return to main display without saving changes.<br>\n");
 printf("HELP - click to see this help.<br>\n");
 printf("<br>\n");
 printf("Initial submission - displays date automatically generated when push queue record is created.<br>\n");
 printf("Importance - from Redmine.<br>\n");
 printf("Date Opened - date QA (re)opened. (YYYY-MM-DD) Defaults originally to current date to save typing.<br>\n");
 printf("New track? - choose Y if this is a new track (i.e. has never before appeared on beta).<br>\n");
 printf("Track - enter the track name as it will appear in the genome browser (use the shortLabel).<br>\n");
 printf("Release Log- enter the short Label (usually) followed by notes in parentheses if any. This appears in the release log unless empty.<br>\n");
 printf("Databases - enter db name. May be comma-separated list if more than one organism, etc.<br>\n");
 printf("Tables - enter as comma-separated list all tables that apply. They must exist in the database specified. Wildcard * supported. (Put comments in parentheses).<br>\n");
 printf("CGIs - enter names of any new cgis that are applicable. Must be found on hgwbeta.<br>\n");
 printf("Files - enter pathnames of any additional files if needed.<br>\n");
@@ -3222,31 +3156,31 @@
 printf("push requested button - press only if you are QA staff and about to submit the push-request. It will try to verify that required entries are present.<br>\n");
 printf("clone button - press if you wish to split the original push queue record into multiple parts. Saves typing, used rarely.<br>\n");
 printf("bounce button - press to bounce from priority A, the QA queue, to B, the developer queue if it needs developer attention.<br>\n");
 printf("transfer button - press to transfer the pushQ entry to another queue.<br>\n");
 printf("lock - press lock to lock the record and edit it.  When in edit mode, make your changes and submit.  Do not leave the record locked.<br>\n");
 printf("<br>\n");
 printf("<a href=\"javascript:window.close();\">CLOSE</a> <br>\n");
 }
 
 
 void doShowSizesHelp()
 /* show the sizes of all the track tables, cgis, and general files in separate window target= _blank  */
 {
 struct pushQ q;
 ZeroVar(&q);
-safef(q.qid,sizeof(q.qid),cgiString("qid"));
+safef(q.qid, sizeof(q.qid), "%s", cgiString("qid"));
 printf("<h4>Show File Sizes Help</h4>\n");
 printf("<br>\n");
 printf("Tables: Shows sizes of database data and indexes.<br>\n");
 printf("Expands wildcard * in table names list. <br>\n");
 printf("Shows total index size, and the key expression of each index.<br>\n");
 printf("Location of tables is relative to the Current Location setting in the record.<br>\n");
 printf("<br>\n");
 printf("CGIs: shows files specified. Currently limited to checking localhost (hgwbeta in this case).<br>\n");
 printf("<br>\n");
 printf("Total size of all:  total size of all files found in bytes.<br>\n");
 printf("Total: size in megabytes(MB) which is what should be entered into the size(MB) field of the push queue record.<br>\n");
 printf("<br>\n");
 printf("RETURN - click to return to the details/edit page.<br>\n");
 printf("Set Size As - click to set size to that found, and return to the details/edit page. Saves typing. Be sure to press submit to save changes.<br>\n");
 printf("<br>\n");
@@ -3255,52 +3189,52 @@
 }
 
 void checkConn2()
 /* get 2nd conn, if not already done */
 {
 if (!conn2)
     conn2 = sqlConnectRemote(host, user, password, database);
 }
 
 boolean verifyTableIsQueue(char *table)
 /* Return TRUE if table is a push Q */
 {
 boolean result = TRUE;
 char query[256];
 char *field = NULL;
-safef(query, sizeof(query), "desc %s",table);
+sqlSafef(query, sizeof(query), "describe %s",table);
 checkConn2();
 field = sqlQuickString(conn2, query);
 result = sameString(field,"qid");
 freez(&field);
 return result;
 }
 
 void listQueues(char *action, boolean isTransfer)
 /* list the available queues other than self */
 {
 struct sqlResult *sr;
 char **row;
 char query[256];
 char *monthChange = isTransfer ? "" : "&month=current";
 if (!(isTransfer && sameString(pushQtbl,"pushQ")))
     {
     char *extra = (sameString(pushQtbl,"pushQ") ? " (you are here)" : "");
     printf("<A href=qaPushQ?%s=%s%s&cb=%s>Main Push Queue</A>%s<br>\n",action,"pushQ",monthChange,newRandState,extra);
     printf("<br>\n");
     }
-safef(query, sizeof(query), "show tables");
+sqlSafef(query, sizeof(query), "show tables");
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     if (!(isTransfer && sameString(row[0],pushQtbl)) &&
 	!sameString(row[0],"pushQ") &&
 	!sameString(row[0],"users") &&
 	!sameString(row[0],"gbjunk"))
 	{
 	if (verifyTableIsQueue(row[0]))
 	    {
 	    char *displayQ = row[0];
 	    if (sameString(displayQ,"pushQ"))
 		displayQ = "Main Push Queue";
 	    char *extra = (sameString(row[0],pushQtbl) ? " (you are here)" : "");
     	    printf("<A href=qaPushQ?%s=%s%s&cb=%s>%s</A>%s<br>\n",action,row[0],monthChange,newRandState,displayQ,extra);
@@ -3324,31 +3258,31 @@
 }
 
 void doUnlock()
 /* currently a backdoor for logged-in users to unlock a record */
 {
 struct pushQ *q;
 int updateSize = 2456; /* almost anything works here */
 
 q = mustLoadPushQ(cgiString("qid")); /* required cgi var */
 
 /* unlock record */
 safef(q->lockUser, sizeof(q->lockUser), "%s","");
 safef(q->lockDateTime, sizeof(q->lockDateTime), "%s","");
 
 /* update existing record */
-pushQUpdateEscaped(conn, q, pushQtbl, updateSize);
+pushQUpdate(conn, q, pushQtbl, updateSize);
 
 pushQFree(&q);
 
 doDisplay();
 
 }
 
 
 /* ======================================================== */
 
 
 void doDrawReleaseLog(boolean isEncode)
 /* Test - draw the release log using log data in pushQ  */
 {
 
@@ -3382,109 +3316,109 @@
 cpassword = cfgOption("rrcentral.password");
 centraldb = cfgOption("rrcentral.db");
 
 webStart(NULL, NULL, "Track and Table Releases");
 
 
 
 // only allowed one connection at a time?
 sqlDisconnect(&conn);
 
 betaconn = sqlConnectRemote(chost, cuser, cpassword, centraldb);
 
 
 printf(" This page contains track and table release information for the following genome assemblies:<br>\n");
 
-safef(query,sizeof(query),
+sqlSafef(query,sizeof(query),
     "select * from dbDb "
     "where active=1 "
     "order by orderKey, name desc");
 sr = sqlGetResult(betaconn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     ki = dbDbLoad(row);
     slAddHead(&kiList, ki);
     }
 sqlFreeResult(&sr);
 
 slReverse(&kiList);
 sqlDisconnect(&betaconn);
 
 // are we really only allowed one remoteconn at a time?
 conn = sqlConnectRemote(host, user, password, database);
 
 /* filter the db list to make sure we actually have data */
 struct dbDb *newList=NULL, *kiNext;
 for (ki = kiList; ki != NULL; ki = kiNext)
     {
     kiNext = ki->next;
-    safef(query,sizeof(query),
+    sqlSafef(query,sizeof(query),
           "select count(*) from pushQ "
           "where priority='L' and releaseLog != '' and ("
           "dbs like '%s' or "
           "dbs like '%s %%' or "
           "dbs like '%% %s' or "
           "dbs like '%% %s %%'"
           ") %s"
           "order by qadate desc, qid desc",
           ki->name,
           ki->name,
           ki->name,
           ki->name,
           encodeClause );
     if (sqlQuickNum(conn, query) > 0)
 	{
     	slAddHead(&newList, ki);
 	}
     }
 slReverse(&newList);
 kiList = newList;
 
 /* 10 Latest Changes */
 printf("<ul>\n");
 printf("<li><a CLASS=\"toc\" HREF=\"#recent\" ><b>10 Latest Changes (all assemblies)</b></a></li>");
 
 /* regular log index #links */
 for (ki = kiList; ki != NULL; ki = ki->next)
     {
-    safef(tempName,sizeof(tempName),ki->organism);
+    safef(tempName, sizeof(tempName), "%s", ki->organism);
     if (!sameString(ki->organism, ki->genome))
 	{
 	safef(tempName,sizeof(tempName),"<em>%s</em>",ki->genome);
 	}
     printf("<li><a CLASS=\"toc\" HREF=\"#%s\">%s %s (%s)</a></li>\n",
 	ki->name,tempName,ki->description,ki->name);
     }
 
 printf("</ul>\n");
 printf("<p>\n");
 printf(" For more information about the tracks and tables listed on this page, refer to the "
 "<a href=/goldenPath/help/hgTracksHelp.html#IndivTracks>User's Guide</a>.<p>\n");
 
 strftime (now, sizeof(now), "%02d %b %Y", loctime); /* default to today's date */
 printf("<em>Last updated %s. <a HREF=\"/contacts.html\">Inquiries and feedback welcome</a>.</em>\n",now);
 /* 10 LATEST CHANGES */
 webNewSection("<A NAME=recent></A> 10 Latest Changes (all assemblies)");
 
 printf("<TABLE CELLPADDING=4 style='border:1px solid #aaaaaa; width:100%%;'>\n"
     "<TR>\n"
     "<TD nowrap><B style='color:#006666;'>Track/Table Name</B></TD>\n"
     "<TD nowrap><B style='color:#006666;'>Assembly</B></TD>\n"
     "<TD nowrap><B style='color:#006666;'>Release Date</B></TD>\n"
     "</TR>\n"
     );
-safef(query,sizeof(query),
+sqlSafef(query,sizeof(query),
     "select releaseLog, dbs, qadate, releaseLogUrl from pushQ "
     "where priority='L' and releaseLog != '' and dbs != '' %s"
     "order by qadate desc, qid desc ", encodeClause
     );
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     sscanf(cloneStringZ(&row[2][5],2),"%d",&m);
     sscanf(cloneStringZ(&row[2][8],2),"%d",&d);
 	{  /* parse dblist and make sure it's kosher and active=1 good */
 	char* dbs = cloneString(row[1]);
 	char dbsComma[1024];
 	char dbsSpace[1024];
 	struct dyString* dbList = newDyString(1024);
 	int j = 0, jj = 0;
@@ -3534,44 +3468,44 @@
 	freez(&dbs);
 	freeDyString(&dbList);
 
 	if (topCount>=10)
 	    break;
 
         }
     }
 
 sqlFreeResult(&sr);
 printf("</table>\n");
 
 /* REGULAR LOG */
 for (ki = kiList; ki != NULL; ki = ki->next)
     {
-    safef(tempName,sizeof(tempName),ki->organism);
+    safef(tempName, sizeof(tempName), "%s", ki->organism);
     if (!sameString(ki->organism, ki->genome))
 	{
 	safef(tempName,sizeof(tempName),"<em>%s</em>",ki->genome);
 	}
 
     webNewSection("<A NAME=%s></A>%s %s (%s, %s)",
                   ki->name, tempName, ki->description, ki->name, ki->sourceName);
     printf("<TABLE CELLPADDING=4 style='border:1px solid #aaaaaa; width:100%%;'>\n"
            "<TR><TD nowrap><B style='color:#006666;'>Track/Table Name</B></TD>\n"
            "    <TD nowrap><B style='color:#006666;'>Release Date</B>\n"
            "</TD></TR>\n");
 
-    safef(query,sizeof(query),
+    sqlSafef(query,sizeof(query),
           "select releaseLog, qadate, releaseLogUrl from pushQ "
           "where priority='L' and releaseLog != '' and ("
           "dbs like '%s' or "
           "dbs like '%s %%' or "
           "dbs like '%% %s' or "
           "dbs like '%% %s %%'"
           ") %s"
           "order by qadate desc, qid desc",
           ki->name,
           ki->name,
           ki->name,
           ki->name,
           encodeClause );
 
     //printf("query=%s\n",query);
@@ -3678,52 +3612,52 @@
 
 newRandState = randDigits(20);
 
 conn = sqlConnectRemote(host, user, password, database);
 
 setLock();
 
 /* default columns */
 showColumns = cloneString(defaultColumns);
 
 readMyUser();
 
 org = cgiUsualString("org","");  /* get org, defaults to display of main push queue */
 if (!sameString(org,""))
     {
-    safef(pushQtbl,sizeof(pushQtbl),org);
+    safef(pushQtbl, sizeof(pushQtbl), "%s", org);
     }
 if (!sqlTableExists(conn, pushQtbl))  /* if pushQtbl no longer exists, switch to main "pushQ" and set action to "display" */
     {
     safef(pushQtbl,sizeof(pushQtbl),"pushQ");
     action=cloneString("display");    /* do not need to free action because it just points to a cgi-var hash element */
     }
 
 newmonth = cgiUsualString("month","");  /* get month, if =current then resets to normal */
 if (!sameString(newmonth,""))
     {
     if (sameString(newmonth,"current"))
 	{
 	safef(month, sizeof(month), "%s", "");
 	}
     else
 	{
 	temp = needMem(strlen(newmonth)+1+3);
 	safef(temp, strlen(newmonth)+1+3, "%s-01",newmonth);
 	if (isDateValid(temp))
 	    {
-	    safef(month,sizeof(month),newmonth);
+	    safef(month, sizeof(month), "%s", newmonth);
 	    }
 	}
     }
 
 
 
 if (sameString(action,"unlock"))
     {
     /* user probably didnt type in the right cachebuster cb= parm, we will supply it. */
     cgiVarSet("cb",oldRandState);
     }
 
 reqRandState = cgiUsualString("cb","");  /* get cb (cache-buster), ignores request, defaults to main display page */
 if (!sameString(reqRandState,oldRandState))
     {