mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Fix bugs in plpgsql and ecpg caused by assuming that isspace() would only
return true for exactly the characters treated as whitespace by their flex scanners. Per report from Victor Snezhko and subsequent investigation. Also fix a passel of unsafe usages of <ctype.h> functions, that is, ye olde char-vs-unsigned-char issue. I won't miss <ctype.h> when we are finally able to stop using it.
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This is a port of the Double Metaphone algorithm for use in PostgreSQL.
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/fuzzystrmatch/dmetaphone.c,v 1.9 2006/07/16 02:44:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/fuzzystrmatch/dmetaphone.c,v 1.10 2006/09/22 21:39:56 tgl Exp $
|
||||
*
|
||||
* Double Metaphone computes 2 "sounds like" strings - a primary and an
|
||||
* alternate. In most cases they are the same, but for foreign names
|
||||
@ -318,7 +318,7 @@ MakeUpper(metastring * s)
|
||||
char *i;
|
||||
|
||||
for (i = s->str; *i; i++)
|
||||
*i = toupper(*i);
|
||||
*i = toupper((unsigned char) *i);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ get_val( HSParser *state, bool ignoreeq, bool *escaped ) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
} else if ( *(state->ptr) == '\\' ) {
|
||||
st = GV_WAITESCIN;
|
||||
} else if ( !isspace(*(state->ptr)) ) {
|
||||
} else if ( !isspace((unsigned char) *(state->ptr)) ) {
|
||||
*(state->cur) = *(state->ptr);
|
||||
state->cur++;
|
||||
st = GV_INVAL;
|
||||
@ -65,7 +65,7 @@ get_val( HSParser *state, bool ignoreeq, bool *escaped ) {
|
||||
} else if ( *(state->ptr) == ',' && ignoreeq ) {
|
||||
state->ptr--;
|
||||
return true;
|
||||
} else if ( isspace(*(state->ptr)) ) {
|
||||
} else if ( isspace((unsigned char) *(state->ptr)) ) {
|
||||
return true;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
state->ptr--;
|
||||
@ -146,7 +146,7 @@ parse_hstore( HSParser *state ) {
|
||||
st = WGT;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
elog(ERROR,"Unexpectd end of string");
|
||||
} else if (!isspace(*(state->ptr))) {
|
||||
} else if (!isspace((unsigned char) *(state->ptr))) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
}
|
||||
} else if ( st == WGT ) {
|
||||
@ -177,7 +177,7 @@ parse_hstore( HSParser *state ) {
|
||||
st = WKEY;
|
||||
} else if ( *(state->ptr) == '\0' ) {
|
||||
return;
|
||||
} else if (!isspace(*(state->ptr))) {
|
||||
} else if (!isspace((unsigned char) *(state->ptr))) {
|
||||
elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin));
|
||||
}
|
||||
} else
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/isn/isn.c,v 1.2 2006/09/10 20:45:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/isn/isn.c,v 1.3 2006/09/22 21:39:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -72,13 +72,16 @@ bool check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
|
||||
aux2 = TABLE[i][1];
|
||||
|
||||
/* must always start with a digit: */
|
||||
if(!isdigit(*aux1) || !isdigit(*aux2)) goto invalidtable;
|
||||
if (!isdigit((unsigned char) *aux1) || !isdigit((unsigned char) *aux2))
|
||||
goto invalidtable;
|
||||
a = *aux1 - '0';
|
||||
b = *aux2 - '0';
|
||||
|
||||
/* must always have the same format and length: */
|
||||
while(*aux1 && *aux2) {
|
||||
if(!(isdigit(*aux1) && isdigit(*aux2)) && (*aux1!=*aux2 || *aux1 != '-'))
|
||||
if (!(isdigit((unsigned char) *aux1) &&
|
||||
isdigit((unsigned char) *aux2)) &&
|
||||
(*aux1 != *aux2 || *aux1 != '-'))
|
||||
goto invalidtable;
|
||||
aux1++;
|
||||
aux2++;
|
||||
@ -124,7 +127,7 @@ unsigned dehyphenate(char *bufO, char *bufI)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
while(*bufI) {
|
||||
if(isdigit(*bufI)) {
|
||||
if(isdigit((unsigned char) *bufI)) {
|
||||
*bufO++ = *bufI;
|
||||
ret++;
|
||||
}
|
||||
@ -183,7 +186,7 @@ unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsign
|
||||
|
||||
firstdig++, ean_aux1++, ean_aux2++;
|
||||
if(!(*ean_aux1 && *ean_aux2 && *firstdig)) break;
|
||||
if(!isdigit(*ean_aux1)) ean_aux1++, ean_aux2++;
|
||||
if(!isdigit((unsigned char) *ean_aux1)) ean_aux1++, ean_aux2++;
|
||||
} else {
|
||||
/* check in what direction we should go and move the pointer accordingly */
|
||||
if(*firstdig < *ean_aux1 && !ean_in1) upper = search;
|
||||
@ -227,7 +230,7 @@ unsigned weight_checkdig(char *isn, unsigned size)
|
||||
{
|
||||
unsigned weight = 0;
|
||||
while(*isn && size>1) {
|
||||
if(isdigit(*isn)) {
|
||||
if(isdigit((unsigned char) *isn)) {
|
||||
weight += size-- * (*isn - '0');
|
||||
}
|
||||
isn++;
|
||||
@ -254,7 +257,7 @@ unsigned checkdig(char *num, unsigned size)
|
||||
pos = 1;
|
||||
}
|
||||
while(*num && size>1) {
|
||||
if(isdigit(*num)) {
|
||||
if(isdigit((unsigned char) *num)) {
|
||||
if(pos++%2) check3 += *num - '0';
|
||||
else check += *num - '0';
|
||||
size--;
|
||||
@ -366,7 +369,7 @@ void ean2ISBN(char *isn)
|
||||
hyphenate(isn, isn+4, NULL, NULL);
|
||||
check = weight_checkdig(isn, 10);
|
||||
aux = strchr(isn, '\0');
|
||||
while(!isdigit(*--aux));
|
||||
while(!isdigit((unsigned char) *--aux));
|
||||
if(check == 10) *aux = 'X';
|
||||
else *aux = check + '0';
|
||||
}
|
||||
@ -411,7 +414,7 @@ ean13 str2ean(const char *num)
|
||||
{
|
||||
ean13 ean = 0; /* current ean */
|
||||
while(*num) {
|
||||
if(isdigit(*num)) ean = 10 * ean + (*num - '0');
|
||||
if(isdigit((unsigned char) *num)) ean = 10 * ean + (*num - '0');
|
||||
num++;
|
||||
}
|
||||
return (ean<<1); /* also give room to a flag */
|
||||
@ -570,7 +573,7 @@ bool string2ean(const char *str, bool errorOK, ean13 *result,
|
||||
/* recognize and validate the number: */
|
||||
while(*aux2 && length <= 13) {
|
||||
last = (*(aux2+1) == '!' || *(aux2+1) == '\0'); /* is the last character */
|
||||
digit = (isdigit(*aux2)!=0); /* is current character a digit? */
|
||||
digit = (isdigit((unsigned char) *aux2)!=0); /* is current character a digit? */
|
||||
if(*aux2=='?' && last) /* automagically calculate check digit if it's '?' */
|
||||
magic = digit = true;
|
||||
if(length == 0 && (*aux2=='M' || *aux2=='m')) {
|
||||
@ -583,13 +586,13 @@ bool string2ean(const char *str, bool errorOK, ean13 *result,
|
||||
/* only ISSN can be here */
|
||||
if(type != INVALID) goto eaninvalid;
|
||||
type = ISSN;
|
||||
*aux1++ = toupper(*aux2);
|
||||
*aux1++ = toupper((unsigned char) *aux2);
|
||||
length++;
|
||||
} else if(length == 9 && (digit || *aux2=='X' || *aux2=='x') && last) {
|
||||
/* only ISBN and ISMN can be here */
|
||||
if(type != INVALID && type != ISMN) goto eaninvalid;
|
||||
if(type == INVALID) type = ISBN; /* ISMN must start with 'M' */
|
||||
*aux1++ = toupper(*aux2);
|
||||
*aux1++ = toupper((unsigned char) *aux2);
|
||||
length++;
|
||||
} else if(length == 11 && digit && last) {
|
||||
/* only UPC can be here */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Both POSIX and CRC32 checksums */
|
||||
|
||||
/* $PostgreSQL: pgsql/contrib/ltree/crc32.c,v 1.6 2006/03/11 04:38:29 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/ltree/crc32.c,v 1.7 2006/09/22 21:39:57 tgl Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#ifdef LOWER_NODE
|
||||
#include <ctype.h>
|
||||
#define TOLOWER(x) tolower(x)
|
||||
#define TOLOWER(x) tolower((unsigned char) (x))
|
||||
#else
|
||||
#define TOLOWER(x) (x)
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* in/out function for ltree and lquery
|
||||
* Teodor Sigaev <teodor@stack.net>
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.12 2006/03/11 04:38:29 momjian Exp $
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.13 2006/09/22 21:39:57 tgl Exp $
|
||||
*/
|
||||
|
||||
#include "ltree.h"
|
||||
@ -332,7 +332,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*ptr == ',')
|
||||
state = LQPRS_WAITSNUM;
|
||||
else if (isdigit((unsigned int) *ptr))
|
||||
else if (isdigit((unsigned char) *ptr))
|
||||
{
|
||||
curqlevel->low = atoi(ptr);
|
||||
state = LQPRS_WAITND;
|
||||
@ -342,7 +342,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (state == LQPRS_WAITSNUM)
|
||||
{
|
||||
if (isdigit((unsigned int) *ptr))
|
||||
if (isdigit((unsigned char) *ptr))
|
||||
{
|
||||
curqlevel->high = atoi(ptr);
|
||||
state = LQPRS_WAITCLOSE;
|
||||
@ -359,7 +359,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*ptr == '}')
|
||||
state = LQPRS_WAITEND;
|
||||
else if (!isdigit((unsigned int) *ptr))
|
||||
else if (!isdigit((unsigned char) *ptr))
|
||||
UNCHAR;
|
||||
}
|
||||
else if (state == LQPRS_WAITND)
|
||||
@ -371,7 +371,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (*ptr == ',')
|
||||
state = LQPRS_WAITSNUM;
|
||||
else if (!isdigit((unsigned int) *ptr))
|
||||
else if (!isdigit((unsigned char) *ptr))
|
||||
UNCHAR;
|
||||
}
|
||||
else if (state == LQPRS_WAITEND)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* txtquery io
|
||||
* Teodor Sigaev <teodor@stack.net>
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltxtquery_io.c,v 1.11 2006/03/11 04:38:29 momjian Exp $
|
||||
* $PostgreSQL: pgsql/contrib/ltree/ltxtquery_io.c,v 1.12 2006/09/22 21:39:57 tgl Exp $
|
||||
*/
|
||||
|
||||
#include "ltree.h"
|
||||
@ -81,7 +81,7 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, uint1
|
||||
*lenval = 1;
|
||||
*flag = 0;
|
||||
}
|
||||
else if (!isspace((unsigned int) *(state->buf)))
|
||||
else if (!isspace((unsigned char) *(state->buf)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("operand syntax error")));
|
||||
|
@ -27,7 +27,7 @@
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.c,v 1.4 2006/07/19 17:05:50 neilc Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.c,v 1.5 2006/09/22 21:39:57 tgl Exp $ */
|
||||
|
||||
#include "postgres.h"
|
||||
#include "px.h"
|
||||
@ -1799,7 +1799,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
|
||||
return MP_RANGE;
|
||||
|
||||
/* Skip leading whitespace */
|
||||
while(isspace((int)*str))
|
||||
while(isspace((unsigned char) *str))
|
||||
++str;
|
||||
|
||||
/* Handle leading sign tag (+/-, positive default) */
|
||||
@ -3127,10 +3127,10 @@ static int s_ch2val(char c, int r)
|
||||
{
|
||||
int out;
|
||||
|
||||
if(isdigit((int)c))
|
||||
if(isdigit((unsigned char)c))
|
||||
out = c - '0';
|
||||
else if(r > 10 && isalpha((int)c))
|
||||
out = toupper(c) - 'A' + 10;
|
||||
else if(r > 10 && isalpha((unsigned char) c))
|
||||
out = toupper((unsigned char) c) - 'A' + 10;
|
||||
else
|
||||
return -1;
|
||||
|
||||
@ -3151,7 +3151,7 @@ static char s_val2ch(int v, int caps)
|
||||
char out = (v - 10) + 'a';
|
||||
|
||||
if(caps)
|
||||
return toupper(out);
|
||||
return toupper((unsigned char) out);
|
||||
else
|
||||
return out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user