f2fabc0349747429dc2fc206093ec1eae9a16584 galt Tue May 8 11:07:15 2012 -0700 with Jims blessing adding check to not return empty input as 0 but to errabort like the other data types do diff --git src/lib/sqlNum.c src/lib/sqlNum.c index bc9eb25..081f857 100644 --- src/lib/sqlNum.c +++ src/lib/sqlNum.c @@ -12,107 +12,112 @@ unsigned sqlUnsigned(char *s) /* Convert series of digits to unsigned integer about * twice as fast as atoi (by not having to skip white * space or stop except at the null byte.) */ { unsigned res = 0; char *p = s; char c; while (((c = *(p++)) >= '0') && (c <= '9')) { res *= 10; res += c - '0'; } -if (c != '\0') +--p; +/* test for invalid character or empty */ +if ((c != '\0') || (p == s)) errAbort("invalid unsigned integer: \"%s\"", s); return res; } unsigned sqlUnsignedInList(char **pS) /* Convert series of digits to unsigned integer about * twice as fast as atoi (by not having to skip white * space or stop except at the null byte.) * All of string is number. Number may be delimited by a comma. * Returns the position of the delimiter or the terminating 0. */ { char *s = *pS; unsigned res = 0; char *p = s; char c; while (((c = *(p++)) >= '0') && (c <= '9')) { res *= 10; res += c - '0'; } -if (!(c == '\0' || c == ',')) +--p; +if (!(c == '\0' || c == ',') || (p == s)) { char *e = strchr(s, ','); if (e) *e = 0; errAbort("invalid unsigned integer: \"%s\"", s); } -*pS = --p; +*pS = p; return res; } unsigned long sqlUnsignedLong(char *s) /* Convert series of digits to unsigned long about * twice as fast as atol (by not having to skip white * space or stop except at the null byte.) */ { unsigned long res = 0; char *p = s; char c; while (((c = *(p++)) >= '0') && (c <= '9')) { res *= 10; res += c - '0'; } -if (c != '\0') +--p; +if ((c != '\0') || (p == s)) errAbort("invalid unsigned long: \"%s\"", s); return res; } unsigned long sqlUnsignedLongInList(char **pS) /* Convert series of digits to unsigned long about * twice as fast as atol (by not having to skip white * space or stop except at the null byte.) * All of string is number. Number may be delimited by a comma. * Returns the position of the delimiter or the terminating 0. */ { char *s = *pS; unsigned long res = 0; char *p = s; char c; while (((c = *(p++)) >= '0') && (c <= '9')) { res *= 10; res += c - '0'; } -if (!(c == '\0' || c == ',')) +--p; +if (!(c == '\0' || c == ',') || (p == s)) { char *e = strchr(s, ','); if (e) *e = 0; errAbort("invalid unsigned long: \"%s\"", s); } -*pS = --p; +*pS = p; return res; } int sqlSigned(char *s) /* Convert string to signed integer. Unlike atol assumes * all of string is number. */ { int res = 0; char *p, *p0 = s; if (*p0 == '-') p0++; p = p0; while ((*p >= '0') && (*p <= '9')) {