080a160c7b9595d516c9c70e83689a09b60839d0
galt
  Mon Jun 3 12:16:53 2013 -0700
fix SQL Injection
diff --git src/hg/lib/hgRelate.c src/hg/lib/hgRelate.c
index 1862415..813cda6 100644
--- src/hg/lib/hgRelate.c
+++ src/hg/lib/hgRelate.c
@@ -15,87 +15,85 @@
 #include "hdb.h"
 
 
 static char extFileCreate[] =
 /* This keeps track of external files and directories. */
 "create table %s ("
   "id int unsigned not null primary key,"  /* Unique ID across all tables. */
   "name varchar(64) not null,"	  /* Symbolic name of file.  */
   "path varchar(255) not null,"   /* Full path. Ends in '/' if a dir. */
   "size bigint unsigned not null,"           /* Size of file (checked) */
                    /* Extra indices. */
   "index (name))";
 
 static char historyCreate[] =	
 /* This contains a row for each update made to database. */
-"create table history ("
+"NOSQLINJ create table history ("
   "ix int not null auto_increment primary key,"  /* Update number. */
   "startId int unsigned not null,"              /* Start this session's ids. */
   "endId int unsigned not null,"                /* First id for next session. */
   "who varchar(255) not null,"         /* User who updated. */
   "what varchar(255) not null,"        /* What they did. */
   "modTime timestamp not null,"        /* Modification time. */
   "errata varchar(255) )";            /* Deleted data */
 
 HGID hgGetMaxId(struct sqlConnection *conn, char *tableName)
 /* get the maximum value of the id column in a table or zero if empry  */
 {
 /* we get a row with NULL if the table is empty */
 char query[128];
 char **row = NULL;
 HGID maxId;
 struct sqlResult *sr;
 
-safef(query, sizeof(query), "SELECT MAX(id) from %s", tableName);
+sqlSafef(query, sizeof(query), "SELECT MAX(id) from %s", tableName);
 
 sr = sqlGetResult(conn, query);
 if (sr != NULL)
     row = sqlNextRow(sr);
 if ((row == NULL) || (row[0] == NULL))
     maxId = 0;  /* empty table */
 else
     maxId = sqlUnsigned(row[0]);
 sqlFreeResult(&sr);
 return maxId;
 }
 
 static void ensureHistoryTableExists(struct sqlConnection *conn)
 /* create history table if it doesn't exist */
 {
 static boolean first = TRUE;
 if (first)
     {
     sqlMaybeMakeTable(conn, "history", historyCreate);
     first = FALSE;
     }
 }
 
 static void hgHistoryEnterVa(struct sqlConnection *conn, int startId, int endId, char *comment, va_list args)
 /* add an entry to the history table */
 {
 // create SQL encoded string for comment
 struct dyString *commentBuf = dyStringNew(256);
 dyStringVaPrintf(commentBuf, comment, args);
-char *commentStr = sqlEscapeString(commentBuf->string);
-dyStringFree(&commentBuf);
 struct dyString *query = dyStringNew(256);
 ensureHistoryTableExists(conn);
-dyStringPrintf(query, "INSERT into history (ix, startId, endId, who, what, modTime, errata) VALUES(NULL,%d,%d,'%s',\"%s\",NOW(), NULL)",
-               startId, endId, getUser(), commentStr);
+sqlDyStringPrintf(query, "INSERT into history (ix, startId, endId, who, what, modTime, errata) VALUES (NULL,%d,%d,'%s','%s',NOW(), NULL)",
+               startId, endId, getUser(), commentBuf->string);
 sqlUpdate(conn,query->string);
 dyStringFree(&query); 
-freeMem(commentStr);
+dyStringFree(&commentBuf);
 }
 
 void hgHistoryComment(struct sqlConnection *conn, char *comment, ...)
 /* Add comment to history table. */
 {
 va_list args;
 va_start(args, comment);
 hgHistoryEnterVa(conn, 0, 0, comment, args);
 va_end(args);
 }
 
 void hgHistoryCommentWithIds(struct sqlConnection *conn, int startId, int endId, char *comment, ...)
 /* Add comment to history table, with id range. */
 {
 va_list args;
@@ -201,67 +199,67 @@
 }
 
 
 int hgAddToExtFileTbl(char *path, struct sqlConnection *conn, char *extFileTbl)
 /* Add entry to the specified extFile table.  Delete it if it already exists.
  * Returns extFile id. */
 {
 char root[128], ext[64], name[256];
 struct dyString *dy = newDyString(1024);
 long long size = fileSize(path);
 
 /* create table if it doesn't exist */
 if (!sqlTableExists(conn, extFileTbl))
     {
     char query[1024];
-    safef(query, sizeof(query), extFileCreate, extFileTbl);
+    sqlSafef(query, sizeof(query), extFileCreate, extFileTbl);
     sqlMaybeMakeTable(conn, extFileTbl, query);
     }
 
 HGID id = hgGetMaxId(conn, extFileTbl) + 1;
 
 /* Construct file name without the directory. */
 splitPath(path, NULL, root, ext);
 safef(name, sizeof(name), "%s%s", root, ext);
 
 /* Delete it from database. */
-dyStringPrintf(dy, "delete from %s where path = '%s'", extFileTbl, path);
+sqlDyStringPrintf(dy, "delete from %s where path = '%s'", extFileTbl, path);
 sqlUpdate(conn, dy->string);
 
 /* Add it to table. */
 dyStringClear(dy);
-dyStringPrintf(dy, "INSERT into %s (id, name, path, size) VALUES(%u,'%s','%s',%lld)",
+sqlDyStringPrintf(dy, "INSERT into %s (id, name, path, size) VALUES(%u,'%s','%s',%lld)",
                extFileTbl, id, name, path, size);
 sqlUpdate(conn, dy->string);
 hgHistoryCommentWithIds(conn, id, id, "extFile table %s: added %s (%lld)", extFileTbl, path, size);
 dyStringFree(&dy);
 return id;
 }
 
 int hgAddToExtFile(char *path, struct sqlConnection *conn)
 /* Add entry to ext file table.  Delete it if it already exists. 
  * Returns extFile id. */
 {
 return hgAddToExtFileTbl(path, conn, "extFile");
 }
 
 void hgPurgeExtFileTbl(int id, struct sqlConnection *conn, char *extFileTbl)
 /* remove an entry from the extFile table.  Called
  * when there is an error loading the referenced file
  */
 {
 struct dyString *dy = newDyString(1024);
 
 /* Delete it from database. */
-dyStringPrintf(dy, "delete from %s where id = '%d'", extFileTbl, id);
+sqlDyStringPrintf(dy, "delete from %s where id = '%d'", extFileTbl, id);
 sqlUpdate(conn, dy->string);
 
 dyStringFree(&dy);
 }
 
 void hgPurgeExtFile(int id,  struct sqlConnection *conn)
 /* remove an entry from the extFile table.  Called
  * when there is an error loading the referenced file
  */
 {
 hgPurgeExtFileTbl(id, conn, "extFile");
 }