206b0af134d75c2397b56a7ee65800a1eb5456a0
galt
  Mon Jan 29 21:15:07 2018 -0800
Use sqlSafef family of functions for safety and consistency.

diff --git src/hg/lib/tablesTables.c src/hg/lib/tablesTables.c
index 830ef6f..e4db6c8 100644
--- src/hg/lib/tablesTables.c
+++ src/hg/lib/tablesTables.c
@@ -407,142 +407,147 @@
     FALSE, NULL, 
     slCount(table->rowList), NULL, NULL, NULL);
 }
 
 
 void webTableBuildQuery(struct cart *cart, char *from, char *initialWhere, 
     char *varPrefix, char *fields, boolean withFilters, 
     struct dyString **retQuery, struct dyString **retWhere)
 /* Construct select, from and where clauses in query, keeping an additional copy of where 
  * Returns the SQL query and the SQL where expression as two dyStrings (need to be freed)  */
 {
 struct dyString *query = dyStringNew(0);
 struct dyString *where = dyStringNew(0);
 struct slName *field, *fieldList = commaSepToSlNames(fields);
 boolean gotWhere = FALSE;
-sqlDyStringPrintf(query, "%s", ""); // TODO check with Galt on how to get reasonable checking back.
-dyStringPrintf(query, "select %s from %s", fields, from);
+sqlDyStringPrintf(query, "select %s from %s", fields, from);
 if (!isEmpty(initialWhere))
     {
-    dyStringPrintf(where, " where ");
+    sqlDyStringPrintfFrag(where, " where ");
     sqlSanityCheckWhere(initialWhere, where);
     gotWhere = TRUE;
     }
 
 /* If we're doing filters, have to loop through the row of filter controls */
 if (withFilters)
     {
     for (field = fieldList; field != NULL; field = field->next)
         {
 	char varName[128];
 	safef(varName, sizeof(varName), "%s_f_%s", varPrefix, field->name);
 	char *val = trimSpaces(cartUsualString(cart, varName, ""));
 	if (!isEmpty(val))
 	    {
 	    if (gotWhere)
-		dyStringPrintf(where, " and ");
+		sqlDyStringPrintf(where, " and ");
 	    else
 		{
-	        dyStringPrintf(where, " where ");
+	        sqlDyStringPrintf(where, " where ");
 		gotWhere = TRUE;
 		}
 	    if (anyWild(val))
 		{
 		char *converted = sqlLikeFromWild(val);
-		 char *escaped = makeEscapedString(converted, '"');
-		 dyStringPrintf(where, "%s like \"%s\"", field->name, escaped);
-		 freez(&escaped);
+		sqlDyStringPrintf(where, "%s like '%s'", field->name, converted);
 		freez(&converted);
 		}
 	    else if (val[0] == '>' || val[0] == '<')
 		{
 		char *remaining = val+1;
 		if (remaining[0] == '=')
+		    {
 		    remaining += 1;
+		    }
 		remaining = skipLeadingSpaces(remaining);
 		if (isNumericString(remaining))
-		     dyStringPrintf(where, "%s %s", field->name, val);
+		    {
+		    sqlDyStringPrintf(where, "%s ", field->name);
+		    if (val[0] == '>')
+			sqlDyStringPrintf(where, ">");
+		    if (val[0] == '<')
+			sqlDyStringPrintf(where, "<");
+		    if (val[1] == '=')
+			sqlDyStringPrintf(where, "=");
+		    sqlDyStringPrintf(where, "%s", remaining);
+		    }
 		else
 		    {
 		    warn("Filter for %s doesn't parse:  %s", field->name, val);
-		     dyStringPrintf(where, "%s is not null", field->name); // Let query continue
+		    sqlDyStringPrintf(where, "%s is not null", field->name); // Let query continue
 		    }
 		}
 	    else
 		{
-		 char *escaped = makeEscapedString(val, '"');
-		 dyStringPrintf(where, "%s = \"%s\"", field->name, escaped);
-		 freez(&escaped);
+		sqlDyStringPrintf(where, "%s = '%s'", field->name, val);
 		}
 	    }
 	}
     }
-dyStringAppend(query, where->string);
+sqlDyStringPrintf(query, "%-s", where->string);  // trust
 
 /* We do order here so as to keep order when working with tables bigger than a page. */
 char orderVar[256];
 safef(orderVar, sizeof(orderVar), "%s_order", varPrefix);
 char *orderFields = cartUsualString(cart, orderVar, "");
 if (!isEmpty(orderFields))
     {
     if (orderFields[0] == '-')
-	dyStringPrintf(query, " order by %s desc", orderFields+1);
+	sqlDyStringPrintf(query, " order by %s desc", orderFields+1);
     else
-	dyStringPrintf(query, " order by %s", orderFields);
+	sqlDyStringPrintf(query, " order by %s", orderFields);
     }
 
 // return query and where expression
 *retQuery = query;
 *retWhere = where;
 }
 
 void webFilteredSqlTable(struct cart *cart, struct sqlConnection *conn, 
     char *fields, char *from, char *initialWhere,  
     char *returnUrl, char *varPrefix, int maxFieldWidth, 
     struct hash *tagOutWrappers, void *wrapperContext,
     boolean withFilters, char *itemPlural, int pageSize, struct hash *suggestHash, void (*addFunc)(void) )
 /* Given a query to the database in conn that is basically a select query broken into
  * separate clauses, construct and display an HTML table around results. This HTML table has
  * column names that will sort the table, and optionally (if withFilters is set)
  * it will also allow field-by-field wildcard queries on a set of controls it draws above
  * the labels. 
  *    Much of the functionality rests on the call to webFilteredFieldedTable.  This function
  * does the work needed to bring in sections of potentially huge results sets into
  * the fieldedTable. */
 {
 struct dyString *query;
 struct dyString *where;
 webTableBuildQuery(cart, from, initialWhere, varPrefix, fields, withFilters, &query, &where);
 
 /* Figure out size of query result */
 struct dyString *countQuery = dyStringNew(0);
-sqlDyStringPrintf(countQuery, "%s", ""); // TODO check with Galt on how to get reasonable checking back.
-dyStringPrintf(countQuery, "select count(*) from %s", from);
-dyStringAppend(countQuery, where->string);
+sqlDyStringPrintf(countQuery, "select count(*) from %s", from);
+sqlDyStringPrintf(countQuery, "%-s", where->string);   // trust
 int resultsSize = sqlQuickNum(conn, countQuery->string);
 dyStringFree(&countQuery);
 
 char pageVar[64];
 safef(pageVar, sizeof(pageVar), "%s_page", varPrefix);
 int page = 0;
 struct fieldedTableSegment context = { .tableSize=resultsSize};
 if (resultsSize > pageSize)
     {
     page = cartUsualInt(cart, pageVar, 0) - 1;
     if (page < 0)
         page = 0;
     int lastPage = (resultsSize-1)/pageSize;
     if (page > lastPage)
         page = lastPage;
     context.tableOffset = page * pageSize;
-    dyStringPrintf(query, " limit %d offset %d", pageSize, context.tableOffset);
+    sqlDyStringPrintf(query, " limit %d offset %d", pageSize, context.tableOffset);
     }
 
 struct fieldedTable *table = fieldedTableFromDbQuery(conn, query->string);
 webFilteredFieldedTable(cart, table, returnUrl, varPrefix, maxFieldWidth, 
     tagOutWrappers, wrapperContext, withFilters, itemPlural, pageSize, &context, suggestHash, addFunc);
 fieldedTableFree(&table);
 
 dyStringFree(&query);
 dyStringFree(&where);
 }