c118b41f4a28f79fa50b48c47ddd753016d5e1fc
galt
  Tue Jan 30 00:28:53 2018 -0800
fixing field lists. rqlQuery is not real db query. added a couple of new sqlSafef family helper functions in jksql

diff --git src/hg/lib/jksql.c src/hg/lib/jksql.c
index 8d6524c..cd59c53 100644
--- src/hg/lib/jksql.c
+++ src/hg/lib/jksql.c
@@ -3637,30 +3637,32 @@
 static char allowed[256];
 if (!init)
     {
     sqlCheckDisallowAllChars(allowed);
     sqlCheckAllowAlphaNumChars(allowed);
     sqlCheckAllowChar('.', allowed);
     sqlCheckAllowChar('_', allowed);
     // sqlTableExists looks like a single table check, but apparently it has become abused
     // to support multiple tables e.g. sqlTableExists 
     sqlCheckAllowChar(' ', allowed);
     sqlCheckAllowChar(',', allowed);
     sqlCheckAllowChar('\'', allowed); // single quote allowed for special case fieldname is '.'
     // NOTE it is important for security that no other characters be allowed here
     init = TRUE;
     }
+if (sameString(identifiers, "*"))  // exception allowed
+    return identifiers;
 if (!sqlCheckAllowedChars(identifiers, allowed))
     {
     sqlCheckError("Illegal character found in identifier list %s", identifiers);
     return identifiers;
     }
 // Unfortunately, just checking that the characters are legal is far from enough to ensure safety.
 // the comma is required. Currently aliases and tick quotes are not supported.
 int len = strlen(identifiers);
 char c = 0;
 int i = 0;
 boolean needText = TRUE;
 boolean spaceOk = FALSE;
 boolean textDone = FALSE;
 // Currently identifiers list must start with an identifier, no leading spaces or comma allowed.
 // Currently the comma must immediately follow the identifier
@@ -4172,30 +4174,48 @@
 
 
 struct dyString *sqlDyStringCreate(char *format, ...)
 /* Create a dyString with a printf style initial content 
  * Adds the NOSQLINJ prefix. */
 {
 int len = strlen(format) * 3;
 struct dyString *ds = newDyString(len);
 va_list args;
 va_start(args, format);
 vaSqlDyStringPrintf(ds, format, args);
 va_end(args);
 return ds;
 }
 
+void sqlDyStringPrintIdList(struct dyString *ds, char *fields)
+/* Append a comma-separated list of fields identifiers. Aborts if invalid characters in list. */
+{
+sqlDyStringPrintf(ds, "%-s", sqlCkIl(fields));
+}
+
+
+void sqlDyStringPrintValuesList(struct dyString *ds, struct slName *list)
+/* Append a comma-separated, quoted and escaped list of values. */
+{
+struct slName *el;
+for (el = list; el != NULL; el = el->next)
+    {
+    if (el != list)
+	sqlDyStringPrintf(ds, ",");
+    sqlDyStringPrintf(ds, "'%s'", el->name);
+    }
+}
 
 void sqlCheckError(char *format, ...)
 /* A sql injection error has occurred. Check for settings and respond
  * as appropriate with error, warning, logOnly, ignore, dumpstack.
  * Then abort if needed. NOTE: unless it aborts, this function will return! */
 {
 va_list args;
 va_start(args, format);
 
 char *noSqlInjLevel = cfgOption("noSqlInj.level");
 char *noSqlInjDumpStack = cfgOption("noSqlInj.dumpStack");
 // I tried to incorporate this setting so as to avoid duplicate dumpStacks
 // but it is not working that well, and I would rather have two than zero dumps.
 //char *browserDumpStack = cfgOption("browser.dumpStack");
 //char *scriptName = cgiScriptName();