Fix unportable usages of tolower(). On signed-char machines, it is necessary
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Mar 2008 03:26:44 +0000 (03:26 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Mar 2008 03:26:44 +0000 (03:26 +0000)
to explicitly cast the output back to char before comparing it to a char
value, else we get the wrong result for high-bit-set characters.  Found by
Rolf Jentsch.  Also, fix several places where <ctype.h> functions were being
called without casting the argument to unsigned char; this is likewise
unportable, but we keep making that mistake :-(.  These found by buildfarm
member salamander, which I will desperately miss if it ever goes belly-up.

src/backend/utils/adt/like_match.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/preproc/preproc.y

index 7d32426cb45ada5699b288b8b4031e3bffabbac0..91e5778b38ca236e4df0bd854264d8ccf0c62504 100644 (file)
@@ -71,7 +71,7 @@
  */
 
 #ifdef MATCH_LOWER
-#define TCHAR(t) tolower((t))
+#define TCHAR(t) ((char) tolower((unsigned char) (t)))
 #else
 #define TCHAR(t) (t)
 #endif
index 7649235f314835a564bd09252a2131cdaf64097f..f496c705bae7f221b34a7ed2a510ee9e0f32e0ec 100644 (file)
@@ -122,13 +122,15 @@ next_insert(char *text, int pos, bool questionmarks)
                        string = string ? false : true;
                else if (!string)
                {
-                       if (text[p] == '$' && isdigit(text[p + 1]))
+                       if (text[p] == '$' && isdigit((unsigned char) text[p + 1]))
                        {
                                /* this can be either a dollar quote or a variable */
                                int                     i;
 
-                               for (i = p + 1; isdigit(text[i]); i++);
-                               if (!isalpha(text[i]) && isascii(text[i]) && text[i] != '_')
+                               for (i = p + 1; isdigit((unsigned char) text[i]); i++)
+                                       /* empty loop body */ ;
+                               if (!isalpha((unsigned char) text[i]) &&
+                                       isascii((unsigned char) text[i]) && text[i] != '_')
                                        /* not dollar delimited quote */
                                        return p;
                        }
index d9f5999c99ccb6267a89fd89cdb7cacf27be0eb1..1b6763b23f6375adb583e52b77c2d756eac9d6d0 100644 (file)
@@ -5845,7 +5845,7 @@ prepared_name: name               {
                                                int i;
 
                                                for (i = 0; i< strlen($1); i++)
-                                                       $1[i] = tolower($1[i]);
+                                                       $1[i] = tolower((unsigned char) $1[i]);
 
                                                $$ = make3_str(make_str("\""), $1, make_str("\""));
                                        }