44ccfacbe3a3d4b300f80d48651c77837a4b571e
galt
  Tue Apr 26 11:12:02 2022 -0700
SQL INJECTION Prevention Version 2 - this improves our methods by making subclauses of SQL that get passed around be both easy and correct to use. The way that was achieved was by getting rid of the obscure and not well used functions sqlSafefFrag and sqlDyStringPrintfFrag and replacing them with the plain versions of those functions, since these are not needed anymore. The new version checks for NOSQLINJ in unquoted %-s which is used to include SQL clauses, and will give an error the NOSQLINJ clause is not present, and this will automatically require the correct behavior by developers. sqlDyStringPrint is a very useful function, however because it was not enforced, users could use various other dyString functions and they operated without any awareness or checking for SQL correct use. Now those dyString functions are prohibited and it will produce an error if you try to use a dyString function on a SQL string, which is simply detected by the presence of the NOSQLINJ prefix.

diff --git src/lib/sqlList.c src/lib/sqlList.c
index 4aa2362..9a0460a 100644
--- src/lib/sqlList.c
+++ src/lib/sqlList.c
@@ -1,1293 +1,1293 @@
 /* Stuff for processing comma separated lists - a little long so
  * in a separate module from jksql.c though interface is still
  * in jksql.c. 
  *
  * This file is copyright 2002 Jim Kent, but license is hereby
  * granted for all use - public, private or commercial. */
 
 /* The various static routines sql<Type>StaticArray are NOT thread-safe. */
 
 #include "common.h"
 #include "sqlNum.h"
 #include "sqlList.h"
 #include "dystring.h"
 #include "hash.h"
 
 
 int sqlByteArray(char *s, signed char *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array an max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlSigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlByteStaticArray(char *s, signed char **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static signed char *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlSigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlByteDynamicArray(char *s, signed char **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 signed char *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlSignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlUbyteArray(char *s, unsigned char *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array an max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlUbyteStaticArray(char *s, unsigned char **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static unsigned char *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlUbyteDynamicArray(char *s, unsigned char **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 unsigned char *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlUnsignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlCharArray(char *s, char *array, int arraySize)
 /* Convert comma separated list of chars to an array.  Pass in 
  * array and max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = s[0];
     s = e;
     }
 return count;
 }
 
 void sqlCharStaticArray(char *s, char **retArray, int *retSize)
 /* Convert comma separated list of chars to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static char *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = s[0];
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlCharDynamicArray(char *s, char **retArray, int *retSize)
 /* Convert comma separated list of chars to a dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 char *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    if (*s == ',')
 		errAbort("Empty element in list. Each element should contain one character.");
 	    array[count++] = *s++;
 	    if (!(*s == 0 || *s == ','))
 		{
 		--s;
 		char *e = strchr(s, ',');
 		if (e)
 		    *e = 0;
 		errAbort("Invalid character: %s", s);
 		}
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlShortArray(char *s, short *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array an max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlSigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlShortStaticArray(char *s, short **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static short *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlSigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlShortDynamicArray(char *s, short **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 short *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlSignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlUshortArray(char *s, unsigned short *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array an max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlUshortStaticArray(char *s, unsigned short **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static unsigned short *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlUshortDynamicArray(char *s, unsigned short **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 unsigned short *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlUnsignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 int sqlDoubleArray(char *s, double *array, int maxArraySize)
 /* Convert comma separated list of floating point numbers to an array.  
  * Pass in array and max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == maxArraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = atof(s);
     s = e;
     }
 return count;
 }
 
 double sqlSumDoublesCommaSep(char *s)
 /* Return sum of double values in a comma-separated list */
 {
 int count = 0;
 char *p = s;
 while (*p)
     if (*p++ == ',')
         count++;
 double *array = NULL;
 int arraySize = count + 1;
 AllocArray(array, arraySize);
 char *t = cloneString(s);
 count = sqlDoubleArray(cloneString(s), array, arraySize);
 freez(&t);
 int i;
 double sum = 0.0;
 for (i = 0; i < count; i++)
     sum += array[i];
 return sum;
 }
 
 int sqlFloatArray(char *s, float *array, int maxArraySize)
 /* Convert comma separated list of floating point numbers to an array.  
  * Pass in array and max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == maxArraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = atof(s);
     s = e;
     }
 return count;
 }
 
 void sqlDoubleStaticArray(char *s, double **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static double *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = atof(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlFloatStaticArray(char *s, float **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static float *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 128;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = atof(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlDoubleDynamicArray(char *s, double **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe.*/
 {
 double *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlDoubleInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 void sqlFloatDynamicArray(char *s, float **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 float *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlFloatInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlUnsignedArray(char *s, unsigned *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array and max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlUnsignedStaticArray(char *s, unsigned **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static unsigned *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlUnsigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlUnsignedDynamicArray(char *s, unsigned **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 unsigned *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlUnsignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 int sqlSignedArray(char *s, int *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array an max size of array. */
 {
 int count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlSigned(s);
     s = e;
     }
 return count;
 }
 
 void sqlSignedStaticArray(char *s, int **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static int *array = NULL;
 static int alloc = 0;
 int count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlSigned(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlSignedDynamicArray(char *s, int **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 int *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlSignedInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 
 /*-------------------------*/
 
 int sqlLongLongArray(char *s, long long *array, int arraySize)
 /* Convert comma separated list of numbers to an array.  Pass in 
  * array and max size of array. */
 {
 unsigned count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == arraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = sqlLongLong(s);
     s = e;
     }
 return count;
 }
 
 void sqlLongLongStaticArray(char *s, long long **retArray, int *retSize)
 /* Convert comma separated list of numbers to an array which will be
  * overwritten next call to this function, but need not be freed. */
 {
 static long long *array = NULL;
 static unsigned alloc = 0;
 unsigned count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = sqlLongLong(s);
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlLongLongDynamicArray(char *s, long long **retArray, int *retSize)
 /* Convert comma separated list of numbers to an dynamically allocated
  * array, which should be freeMem()'d when done. Thread-safe. */
 {
 long long *array = NULL;
 int count = 0;
 
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	for (;;)
 	    {
 	    array[count++] = sqlLongLongInList(&s);
 	    if (*s++ == 0)
 		break;
 	    if (*s == 0)
 		break;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 /*-------------------------*/
 
 
 int sqlStringArray(char *s, char **array, int maxArraySize)
 /* Convert comma separated list of strings to an array.  Pass in 
  * array and max size of array.  Returns actual size*/
 {
 int count = 0;
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0 || count == maxArraySize)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     array[count++] = s;
     s = e;
     }
 return count;
 }
 
 void sqlStringStaticArray(char *s, char  ***retArray, int *retSize)
 /* Convert comma separated list of strings to an array which will be
  * overwritten next call to this function,  but need not be freed. */
 {
 static char **array = NULL;
 static int alloc = 0;
 int count = 0;
 
 for (;;)
     {
     char *e;
     if (s == NULL || s[0] == 0)
 	break;
     e = strchr(s, ',');
     if (e != NULL)
 	*e++ = 0;
     if (count >= alloc)
 	{
 	if (alloc == 0)
 	    alloc = 64;
 	else
 	    alloc <<= 1;
 	ExpandArray(array, count, alloc);
 	}
     array[count++] = s;
     s = e;
     }
 *retSize = count;
 *retArray = array;
 }
 
 void sqlStringDynamicArray(char *s, char ***retArray, int *retSize)
 /* Convert comma separated list of strings to an dynamically allocated
  * array, which should be freeMem()'d when done. As a speed option all
  * of the elements in the array are needMem()'d at the same time. This 
  * means that all the entries are free()'d by calling freeMem() on the
  * first element. For example:
  * sqlStringDynamicArray(s, &retArray, &retSize);
  * DoSomeFunction(retArray, retSize);
  * freeMem(retArray[0]);
  * freeMem(retArray);
  * Thread-safe. */
 {
 char **array = NULL;
 int count = 0;
 if (s)
     {
     count = countSeparatedItems(s, ',');
     if (count > 0)
 	{
 	AllocArray(array, count);
 	count = 0;
 	s = cloneString(s);
 	for (;;)
 	    {
 	    char *e;
 	    if (s == NULL || s[0] == 0)
 		break;
 	    e = strchr(s, ',');
 	    if (e != NULL)
 		*e++ = 0;
 	    array[count++] = s;
 	    s = e;
 	    }
 	}
     }
 *retArray = array;
 *retSize = count;
 }
 
 char *sqlDoubleArrayToString( double *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%f,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlFloatArrayToString( float *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%f,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlUnsignedArrayToString( unsigned *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%u,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlSignedArrayToString( int *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%d,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlShortArrayToString( short *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%d,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlUshortArrayToString( unsigned short *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%u,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlByteArrayToString( signed char *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%d,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlUbyteArrayToString( unsigned char *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%u,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlCharArrayToString( char *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%c,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlLongLongArrayToString( long long *array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%lld,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 char *sqlStringArrayToString( char **array, int arraySize)
 {
 int i;
-struct dyString *string = newDyString(256);
+struct dyString *string = dyStringNew(256);
 for( i = 0 ; i < arraySize; i++ )
     {
     dyStringPrintf(string, "%s,", array[i]);
     }
 return dyStringCannibalize(&string);
 }
 
 
 /* -------------- */
 
 
 
 void sqlStringFreeDynamicArray(char ***pArray)
 /* Free up a dynamic array (ends up freeing array and first string on it.) */
 {
 char **array;
 if ((array = *pArray) != NULL)
     {
     freeMem(array[0]);
     freez(pArray);
     }
 }
 
 int sqlUnsignedComma(char **pS)
 /* Return signed number at *pS.  Advance *pS past comma at end */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 unsigned ret;
 
 *e++ = 0;
 *pS = e;
 ret = sqlUnsigned(s);
 return ret;
 }
 
 
 int sqlSignedComma(char **pS)
 /* Return signed number at *pS.  Advance *pS past comma at end */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 int ret;
 
 *e++ = 0;
 *pS = e;
 ret = sqlSigned(s);
 return ret;
 }
 
 char sqlCharComma(char **pS)
 /* Return char at *pS.  Advance *pS past comma after char */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 int ret;
 
 *e++ = 0;
 *pS = e;
 ret = s[0];
 return ret;
 }
 
 long long sqlLongLongComma(char **pS)
 /* Return offset (often 64 bits) at *pS.  Advance *pS past comma at 
  * end */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 long long ret;
 
 *e++ = 0;
 *pS = e;
 ret = sqlLongLong(s);
 return ret;
 }
 
 float sqlFloatComma(char **pS)
 /* Return signed number at *pS.  Advance *pS past comma at end */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 float ret;
 
 *e++ = 0;
 *pS = e;
 ret = atof(s);
 return ret;
 }
 
 double sqlDoubleComma(char **pS)
 /* Return signed number at *pS.  Advance *pS past comma at end */
 {
 char *s = *pS;
 char *e = strchr(s, ',');
 double ret;
 
 *e++ = 0;
 *pS = e;
 ret = atof(s);
 return ret;
 }
 
 
 static char *findStringEnd(char *start, char endC)
 /* Return end of string. */
 {
 char c;
 char *s = start;
 
 for (;;)
     {
     c = *s;
     if (c == endC)
 	return s;
     else if (c == 0)
 	errAbort("Unterminated string");
     ++s;
     }
 }
 
 static char *sqlGetOptQuoteString(char **pS)
 /* Return string at *pS.  (Either quoted or not.)  Advance *pS. */
 {
 char *s = *pS;
 char *e;
 char c = *s;
 
 if (c  == '"' || c == '\'')
     {
     s += 1;
     e = findStringEnd(s, c);
     *e++ = 0;
     if (*e++ != ',')
 	errAbort("Expecting comma after string");
     }
 else
     {
     e = strchr(s, ',');
     *e++ = 0;
     }
 *pS = e;
 return s;
 }
 
 char *sqlStringComma(char **pS)
 /* Return string at *pS.  (Either quoted or not.)  Advance *pS. */
 {
 return cloneString(sqlGetOptQuoteString(pS));
 }
 
 void sqlFixedStringComma(char **pS, char *buf, int bufSize)
 /* Copy string at *pS to buf.  Advance *pS. */
 {
 strncpy(buf, sqlGetOptQuoteString(pS), bufSize);
 }
 
 char *sqlEatChar(char *s, char c)
 /* Make sure next character is 'c'.  Return past next char */
 {
 if (*s++ != c)
     errAbort("Expecting %c got %c (%d) in database", c, s[-1], s[-1]);
 return s;
 }
 
 static struct hash *buildSymHash(char **values, boolean isEnum)
 /* build a hash of values for either enum or set symbolic column */
 {
 struct hash *valHash = hashNew(0);
 unsigned setVal = 1; /* not used for enum */
 int iVal;
 for (iVal = 0; values[iVal] != NULL; iVal++)
     {
     if (isEnum)
         hashAddInt(valHash, values[iVal], iVal);
     else
         {
         hashAddInt(valHash, values[iVal], setVal);
         setVal = setVal << 1;
         }
     }
 return valHash;
 }
 
 unsigned sqlEnumParse(char *valStr, char **values, struct hash **valHashPtr)
 /* parse an enumerated column value */
 {
 if (*valHashPtr == NULL)
     *valHashPtr = buildSymHash(values, TRUE);
 return hashIntVal(*valHashPtr, valStr);
 }
 
 unsigned sqlEnumComma(char **pS, char **values, struct hash **valHashPtr)
 /* Return enum at *pS.  (Either quoted or not.)  Advance *pS. */
 {
 return sqlEnumParse(sqlGetOptQuoteString(pS), values, valHashPtr);
 }
 
 void sqlEnumPrint(FILE *f, unsigned value, char **values)
 /* print an enumerated column value */
 {
 fputs(values[value], f);
 }
 
 unsigned sqlSetParse(char *valStr, char **values, struct hash **valHashPtr)
 /* parse a set column value */
 {
 if (*valHashPtr == NULL)
     *valHashPtr = buildSymHash(values, FALSE);
 /* parse comma separated string */
 unsigned value = 0;
 char *val = strtok(valStr, ",");
 while (val != NULL)
     {
     value |= hashIntVal(*valHashPtr, val);
     val = strtok(NULL, ",");
     }
 
 return value;
 }
 
 unsigned sqlSetComma(char **pS, char **values, struct hash **valHashPtr)
 /* Return set at *pS.  (Either quoted or not.)  Advance *pS. */
 {
 return sqlSetParse(sqlGetOptQuoteString(pS), values, valHashPtr);
 }
 
 void sqlSetPrint(FILE *f, unsigned value, char **values)
 /* print a set column value */
 {
 int iVal;
 unsigned curVal = 1;
 int cnt = 0;
 for (iVal = 0; values[iVal] != NULL; iVal++, curVal = curVal << 1)
     {
     if (curVal & value)
         {
         if (cnt > 0)
             fputc(',', f);
         fputs(values[iVal], f);
         cnt++;
         }
     }
 }