Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbeca984

Browse files
committed
Fix bugs in plpgsql and ecpg caused by assuming that isspace() would only
return true for exactly the characters treated as whitespace by their flexscanners. Per report from Victor Snezhko and subsequent investigation.Also fix a passel of unsafe usages of <ctype.h> functions, that is, ye oldechar-vs-unsigned-char issue. I won't miss <ctype.h> when we are finallyable to stop using it.
1 parent6d0efd3 commitbeca984

File tree

19 files changed

+112
-61
lines changed

19 files changed

+112
-61
lines changed

‎contrib/fuzzystrmatch/dmetaphone.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* This is a port of the Double Metaphone algorithm for use in PostgreSQL.
33
*
4-
* $PostgreSQL: pgsql/contrib/fuzzystrmatch/dmetaphone.c,v 1.9 2006/07/16 02:44:00 tgl Exp $
4+
* $PostgreSQL: pgsql/contrib/fuzzystrmatch/dmetaphone.c,v 1.10 2006/09/22 21:39:56 tgl Exp $
55
*
66
* Double Metaphone computes 2 "sounds like" strings - a primary and an
77
* alternate. In most cases they are the same, but for foreign names
@@ -318,7 +318,7 @@ MakeUpper(metastring * s)
318318
char*i;
319319

320320
for (i=s->str;*i;i++)
321-
*i=toupper(*i);
321+
*i=toupper((unsignedchar)*i);
322322
}
323323

324324

‎contrib/hstore/hstore_io.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ get_val( HSParser *state, bool ignoreeq, bool *escaped ) {
5151
elog(ERROR,"Syntax error near '%c' at postion %d",*(state->ptr), (int4)(state->ptr-state->begin));
5252
}elseif (*(state->ptr)=='\\' ) {
5353
st=GV_WAITESCIN;
54-
}elseif ( !isspace(*(state->ptr)) ) {
54+
}elseif ( !isspace((unsignedchar)*(state->ptr)) ) {
5555
*(state->cur)=*(state->ptr);
5656
state->cur++;
5757
st=GV_INVAL;
@@ -65,7 +65,7 @@ get_val( HSParser *state, bool ignoreeq, bool *escaped ) {
6565
}elseif (*(state->ptr)==','&&ignoreeq ) {
6666
state->ptr--;
6767
return true;
68-
}elseif (isspace(*(state->ptr)) ) {
68+
}elseif (isspace((unsignedchar)*(state->ptr)) ) {
6969
return true;
7070
}elseif (*(state->ptr)=='\0' ) {
7171
state->ptr--;
@@ -146,7 +146,7 @@ parse_hstore( HSParser *state ) {
146146
st=WGT;
147147
}elseif (*(state->ptr)=='\0' ) {
148148
elog(ERROR,"Unexpectd end of string");
149-
}elseif (!isspace(*(state->ptr))) {
149+
}elseif (!isspace((unsignedchar)*(state->ptr))) {
150150
elog(ERROR,"Syntax error near '%c' at postion %d",*(state->ptr), (int4)(state->ptr-state->begin));
151151
}
152152
}elseif (st==WGT ) {
@@ -177,7 +177,7 @@ parse_hstore( HSParser *state ) {
177177
st=WKEY;
178178
}elseif (*(state->ptr)=='\0' ) {
179179
return;
180-
}elseif (!isspace(*(state->ptr))) {
180+
}elseif (!isspace((unsignedchar)*(state->ptr))) {
181181
elog(ERROR,"Syntax error near '%c' at postion %d",*(state->ptr), (int4)(state->ptr-state->begin));
182182
}
183183
}else

‎contrib/isn/isn.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/contrib/isn/isn.c,v 1.2 2006/09/10 20:45:17 tgl Exp $
10+
* $PostgreSQL: pgsql/contrib/isn/isn.c,v 1.3 2006/09/22 21:39:57 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -72,13 +72,16 @@ bool check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
7272
aux2=TABLE[i][1];
7373

7474
/* must always start with a digit: */
75-
if(!isdigit(*aux1)|| !isdigit(*aux2)) gotoinvalidtable;
75+
if (!isdigit((unsignedchar)*aux1)|| !isdigit((unsignedchar)*aux2))
76+
gotoinvalidtable;
7677
a=*aux1-'0';
7778
b=*aux2-'0';
7879

7980
/* must always have the same format and length: */
8081
while(*aux1&&*aux2) {
81-
if(!(isdigit(*aux1)&&isdigit(*aux2))&& (*aux1!=*aux2||*aux1!='-'))
82+
if (!(isdigit((unsignedchar)*aux1)&&
83+
isdigit((unsignedchar)*aux2))&&
84+
(*aux1!=*aux2||*aux1!='-'))
8285
gotoinvalidtable;
8386
aux1++;
8487
aux2++;
@@ -124,7 +127,7 @@ unsigned dehyphenate(char *bufO, char *bufI)
124127
{
125128
unsignedret=0;
126129
while(*bufI) {
127-
if(isdigit(*bufI)) {
130+
if(isdigit((unsignedchar)*bufI)) {
128131
*bufO++=*bufI;
129132
ret++;
130133
}
@@ -183,7 +186,7 @@ unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsign
183186

184187
firstdig++,ean_aux1++,ean_aux2++;
185188
if(!(*ean_aux1&&*ean_aux2&&*firstdig))break;
186-
if(!isdigit(*ean_aux1))ean_aux1++,ean_aux2++;
189+
if(!isdigit((unsignedchar)*ean_aux1))ean_aux1++,ean_aux2++;
187190
}else {
188191
/* check in what direction we should go and move the pointer accordingly */
189192
if(*firstdig<*ean_aux1&& !ean_in1)upper=search;
@@ -227,7 +230,7 @@ unsigned weight_checkdig(char *isn, unsigned size)
227230
{
228231
unsignedweight=0;
229232
while(*isn&&size>1) {
230-
if(isdigit(*isn)) {
233+
if(isdigit((unsignedchar)*isn)) {
231234
weight+=size--* (*isn-'0');
232235
}
233236
isn++;
@@ -254,7 +257,7 @@ unsigned checkdig(char *num, unsigned size)
254257
pos=1;
255258
}
256259
while(*num&&size>1) {
257-
if(isdigit(*num)) {
260+
if(isdigit((unsignedchar)*num)) {
258261
if(pos++%2)check3+=*num-'0';
259262
elsecheck+=*num-'0';
260263
size--;
@@ -366,7 +369,7 @@ void ean2ISBN(char *isn)
366369
hyphenate(isn,isn+4,NULL,NULL);
367370
check=weight_checkdig(isn,10);
368371
aux=strchr(isn,'\0');
369-
while(!isdigit(*--aux));
372+
while(!isdigit((unsignedchar)*--aux));
370373
if(check==10)*aux='X';
371374
else*aux=check+'0';
372375
}
@@ -411,7 +414,7 @@ ean13 str2ean(const char *num)
411414
{
412415
ean13ean=0;/* current ean */
413416
while(*num) {
414-
if(isdigit(*num))ean=10*ean+ (*num-'0');
417+
if(isdigit((unsignedchar)*num))ean=10*ean+ (*num-'0');
415418
num++;
416419
}
417420
return (ean<<1);/* also give room to a flag */
@@ -570,7 +573,7 @@ bool string2ean(const char *str, bool errorOK, ean13 *result,
570573
/* recognize and validate the number: */
571574
while(*aux2&&length <=13) {
572575
last= (*(aux2+1)=='!'||*(aux2+1)=='\0');/* is the last character */
573-
digit= (isdigit(*aux2)!=0);/* is current character a digit? */
576+
digit= (isdigit((unsignedchar)*aux2)!=0);/* is current character a digit? */
574577
if(*aux2=='?'&&last)/* automagically calculate check digit if it's '?' */
575578
magic=digit= true;
576579
if(length==0&& (*aux2=='M'||*aux2=='m')) {
@@ -583,13 +586,13 @@ bool string2ean(const char *str, bool errorOK, ean13 *result,
583586
/* only ISSN can be here */
584587
if(type!=INVALID) gotoeaninvalid;
585588
type=ISSN;
586-
*aux1++=toupper(*aux2);
589+
*aux1++=toupper((unsignedchar)*aux2);
587590
length++;
588591
}elseif(length==9&& (digit||*aux2=='X'||*aux2=='x')&&last) {
589592
/* only ISBN and ISMN can be here */
590593
if(type!=INVALID&&type!=ISMN) gotoeaninvalid;
591594
if(type==INVALID)type=ISBN;/* ISMN must start with 'M' */
592-
*aux1++=toupper(*aux2);
595+
*aux1++=toupper((unsignedchar)*aux2);
593596
length++;
594597
}elseif(length==11&&digit&&last) {
595598
/* only UPC can be here */

‎contrib/ltree/crc32.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/* Both POSIX and CRC32 checksums */
22

3-
/* $PostgreSQL: pgsql/contrib/ltree/crc32.c,v 1.6 2006/03/11 04:38:29 momjian Exp $ */
3+
/* $PostgreSQL: pgsql/contrib/ltree/crc32.c,v 1.7 2006/09/22 21:39:57 tgl Exp $ */
44

55
#include<sys/types.h>
66
#include<stdio.h>
77
#include<sys/types.h>
88

99
#ifdefLOWER_NODE
1010
#include<ctype.h>
11-
#defineTOLOWER(x)tolower(x)
11+
#defineTOLOWER(x)tolower((unsigned char) (x))
1212
#else
1313
#defineTOLOWER(x)(x)
1414
#endif

‎contrib/ltree/ltree_io.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* in/out function for ltree and lquery
33
* Teodor Sigaev <teodor@stack.net>
4-
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.12 2006/03/11 04:38:29 momjian Exp $
4+
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.13 2006/09/22 21:39:57 tgl Exp $
55
*/
66

77
#include"ltree.h"
@@ -332,7 +332,7 @@ lquery_in(PG_FUNCTION_ARGS)
332332
{
333333
if (*ptr==',')
334334
state=LQPRS_WAITSNUM;
335-
elseif (isdigit((unsignedint)*ptr))
335+
elseif (isdigit((unsignedchar)*ptr))
336336
{
337337
curqlevel->low=atoi(ptr);
338338
state=LQPRS_WAITND;
@@ -342,7 +342,7 @@ lquery_in(PG_FUNCTION_ARGS)
342342
}
343343
elseif (state==LQPRS_WAITSNUM)
344344
{
345-
if (isdigit((unsignedint)*ptr))
345+
if (isdigit((unsignedchar)*ptr))
346346
{
347347
curqlevel->high=atoi(ptr);
348348
state=LQPRS_WAITCLOSE;
@@ -359,7 +359,7 @@ lquery_in(PG_FUNCTION_ARGS)
359359
{
360360
if (*ptr=='}')
361361
state=LQPRS_WAITEND;
362-
elseif (!isdigit((unsignedint)*ptr))
362+
elseif (!isdigit((unsignedchar)*ptr))
363363
UNCHAR;
364364
}
365365
elseif (state==LQPRS_WAITND)
@@ -371,7 +371,7 @@ lquery_in(PG_FUNCTION_ARGS)
371371
}
372372
elseif (*ptr==',')
373373
state=LQPRS_WAITSNUM;
374-
elseif (!isdigit((unsignedint)*ptr))
374+
elseif (!isdigit((unsignedchar)*ptr))
375375
UNCHAR;
376376
}
377377
elseif (state==LQPRS_WAITEND)

‎contrib/ltree/ltxtquery_io.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* txtquery io
33
* Teodor Sigaev <teodor@stack.net>
4-
* $PostgreSQL: pgsql/contrib/ltree/ltxtquery_io.c,v 1.11 2006/03/11 04:38:29 momjian Exp $
4+
* $PostgreSQL: pgsql/contrib/ltree/ltxtquery_io.c,v 1.12 2006/09/22 21:39:57 tgl Exp $
55
*/
66

77
#include"ltree.h"
@@ -81,7 +81,7 @@ gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval, uint1
8181
*lenval=1;
8282
*flag=0;
8383
}
84-
elseif (!isspace((unsignedint)*(state->buf)))
84+
elseif (!isspace((unsignedchar)*(state->buf)))
8585
ereport(ERROR,
8686
(errcode(ERRCODE_SYNTAX_ERROR),
8787
errmsg("operand syntax error")));

‎contrib/pgcrypto/imath.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2828
SOFTWARE.
2929
*/
30-
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.c,v 1.4 2006/07/19 17:05:50 neilc Exp $ */
30+
/* $PostgreSQL: pgsql/contrib/pgcrypto/imath.c,v 1.5 2006/09/22 21:39:57 tgl Exp $ */
3131

3232
#include"postgres.h"
3333
#include"px.h"
@@ -1799,7 +1799,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
17991799
returnMP_RANGE;
18001800

18011801
/* Skip leading whitespace */
1802-
while(isspace((int)*str))
1802+
while(isspace((unsignedchar)*str))
18031803
++str;
18041804

18051805
/* Handle leading sign tag (+/-, positive default) */
@@ -3127,10 +3127,10 @@ static int s_ch2val(char c, int r)
31273127
{
31283128
intout;
31293129

3130-
if(isdigit((int)c))
3130+
if(isdigit((unsignedchar)c))
31313131
out=c-'0';
3132-
elseif(r>10&&isalpha((int)c))
3133-
out=toupper(c)-'A'+10;
3132+
elseif(r>10&&isalpha((unsignedchar)c))
3133+
out=toupper((unsignedchar)c)-'A'+10;
31343134
else
31353135
return-1;
31363136

@@ -3151,7 +3151,7 @@ static char s_val2ch(int v, int caps)
31513151
charout= (v-10)+'a';
31523152

31533153
if(caps)
3154-
returntoupper(out);
3154+
returntoupper((unsignedchar)out);
31553155
else
31563156
returnout;
31573157
}

‎src/backend/parser/scan.l

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Portions Copyright (c) 1994, Regents of the University of California
2525
*
2626
* IDENTIFICATION
27-
* $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.137 2006/09/03 03:19:44 momjian Exp $
27+
* $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.138 2006/09/22 21:39:57 tgl Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -145,6 +145,9 @@ static unsigned char unescape_single_char(unsigned char c);
145145
* did not end with a newline.
146146
*
147147
* XXX perhaps \f (formfeed) should be treated as a newline as well?
148+
*
149+
* XXX if you change the set of whitespace characters, fix scanner_isspace()
150+
* to agree, and see also the plpgsql lexer.
148151
*/
149152

150153
space[\t\n\r\f]

‎src/backend/parser/scansup.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/parser/scansup.c,v 1.33 2006/07/14 14:52:22 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/parser/scansup.c,v 1.34 2006/09/22 21:39:57 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -183,3 +183,26 @@ truncate_identifier(char *ident, int len, bool warn)
183183
ident[len]='\0';
184184
}
185185
}
186+
187+
/*
188+
* scanner_isspace() --- return TRUE if flex scanner considers char whitespace
189+
*
190+
* This should be used instead of the potentially locale-dependent isspace()
191+
* function when it's important to match the lexer's behavior.
192+
*
193+
* In principle we might need similar functions for isalnum etc, but for the
194+
* moment only isspace seems needed.
195+
*/
196+
bool
197+
scanner_isspace(charch)
198+
{
199+
/* This must match scan.l's list of {space} characters */
200+
/* and plpgsql's scan.l as well */
201+
if (ch==' '||
202+
ch=='\t'||
203+
ch=='\n'||
204+
ch=='\r'||
205+
ch=='\f')
206+
return true;
207+
return false;
208+
}

‎src/backend/utils/misc/guc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.351 2006/09/2217:41:21 petere Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.352 2006/09/2221:39:57 tgl Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -6155,7 +6155,7 @@ assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
61556155
initStringInfo(&buf);
61566156
while ((c=*cp++)!=0)
61576157
{
6158-
if (isspace(c))
6158+
if (isspace((unsignedchar)c))
61596159
{
61606160
if (symLen>0)
61616161
hasSpaceAfterToken= true;
@@ -6173,7 +6173,7 @@ assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
61736173
continue;
61746174
}
61756175

6176-
if (hasSpaceAfterToken|| !isalnum(c))
6176+
if (hasSpaceAfterToken|| !isalnum((unsignedchar)c))
61776177
{
61786178
/*
61796179
* Syntax error due to token following space after token or non

‎src/bin/pg_dump/pg_dump.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.447 2006/08/21 00:57:25 tgl Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.448 2006/09/22 21:39:57 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -367,10 +367,10 @@ main(int argc, char **argv)
367367

368368
new_obj_name->next=NULL;
369369
new_obj_name->name=strdup(optarg);
370-
new_obj_name->is_include=islower(c) ? true : false;
370+
new_obj_name->is_include=islower((unsignedchar)c) ? true : false;
371371

372372
/* add new entry to the proper list */
373-
if (tolower(c)=='n')
373+
if (tolower((unsignedchar)c)=='n')
374374
{
375375
if (!schemaList_tail)
376376
schemaList_tail=schemaList=new_obj_name;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp