c98ab6c8d2b3a44f447f3f6847129b9840c1749d
galt
  Fri May 13 01:39:42 2022 -0700
Fixing #filter in hgTables/joining.c for improved SQL Injection protections. refs #29274

diff --git src/hg/hgTables/joining.c src/hg/hgTables/joining.c
index 01c7c85..3275d50 100644
--- src/hg/hgTables/joining.c
+++ src/hg/hgTables/joining.c
@@ -47,31 +47,31 @@
     };
 
 static void joinedTablesSepOutFile(struct joinedTables *joined, FILE *f, char outSep)
 /* write outSep separated fields to file handle */
 {
 struct joinedRow *jr;
 struct joinerDtf *field;
 int outCount = 0;
 
 if (f == NULL)
     f = stdout;
 
 /* Print out field names. */
 if (joined->filter)
     {
-    fprintf(f, "#filter: %s\n", joined->filter->string);
+    fprintf(f, "#filter: %s\n", joined->filter->string+NOSQLINJ_SIZE);
     }
 fprintf(f, "#");
 for (field = joined->fieldList; field != NULL; field = field->next)
     {
     if (outSep == ',') fputc('"', f);
     fprintf(f, "%s.%s.%s", field->database, field->table, field->field);
     if (outSep == ',') fputc('"', f);
     if (field->next == NULL)
         fprintf(f, "\n");
     else
         fprintf(f, "%c", outSep);
     }
 for (jr = joined->rowList; jr != NULL; jr = jr->next)
     {
     int i;
@@ -610,32 +610,32 @@
 if (isFirst)
     identifierFilter = identifierWhereClause(idField, idHash);
 
 // ignore returned filter from this call to filterClause:
 filterClause(tj->database, tj->table, regionList->chrom, identifierFilter);
 
 /* Record combined filter. */
 // Show only the SQL filter built from filter page options, not identifierFilter,
 // because identifierFilter can get enormous (like 126kB for 12,500 rsIDs).
 char *filterNoIds = filterClause(tj->database, tj->table, regionList->chrom, NULL);
 if (filterNoIds != NULL)
     {
     if (joined->filter == NULL)
 	joined->filter = dyStringNew(0);
     else
-	dyStringAppend(joined->filter, " AND ");
-    dyStringAppend(joined->filter, filterNoIds);
+	sqlDyStringPrintf(joined->filter, " AND ");
+    sqlDyStringPrintf(joined->filter, "%-s", filterNoIds);
     if (!isFirst)
 	{
         needUpdateFilter = TRUE;
 	for (jr = joined->rowList; jr != NULL; jr = jr->next)
 	    jr->hitThisTable = FALSE;
 	}
     }
 
 /* Create field spec for sql - first fields user will see, and
  * second keys if any. */
 for (dtf = tj->fieldList; dtf != NULL; dtf = dtf->next)
     {
     struct joinerDtf *dupe = joinerDtfClone(dtf);
     slAddTail(&joined->fieldList, dupe);
     dyStringAddList(sqlFields, dtf->field);