lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

this is a fix against Lua 5.1-work2 to avoid potential crashes with 8 bit
characters. The result of some dereferenced char pointers miss the uchar()
cast but are passed to ctype macros later on.

Explanation follows, in case anyone is interested:

Quoting the POSIX specs (aligned with ISO C):

  The  tolower()  function  has  as a domain a type int, the
  value of which is representable as an unsigned char or the
  value  of  EOF.

Dito for islower(), isprint() and other ctype macros/functions.

WRONG: char *p;          ... islower(*p)
OK:    char *p;          ... islower((int)((unsigned char)*p))
OK:    unsigned char *p; ... islower((int)*p)

Bye,
     Mike
--- lua-5.1-work2/src/lib/lstrlib.c	2004-08-09 15:30:33.000000000 +0200
+++ lua-5.1-work2-ctype/src/lib/lstrlib.c	2004-10-30 22:21:38.000000000 +0200
@@ -250,7 +250,7 @@
   while (++p < ec) {
     if (*p == ESC) {
       p++;
-      if (match_class(c, *p))
+      if (match_class(c, uchar(*p)))
         return sig;
     }
     else if ((*(p+1) == '-') && (p+2 < ec)) {
@@ -267,7 +267,7 @@
 static int luaI_singlematch (int c, const char *p, const char *ep) {
   switch (*p) {
     case '.': return 1;  /* matches any char */
-    case ESC: return match_class(c, *(p+1));
+    case ESC: return match_class(c, uchar(*(p+1)));
     case '[': return matchbracketclass(c, p, ep-1);
     default:  return (uchar(*p) == c);
   }
@@ -393,7 +393,7 @@
         }
         default: {
           if (isdigit(uchar(*(p+1)))) {  /* capture results (%0-%9)? */
-            s = match_capture(ms, s, *(p+1));
+            s = match_capture(ms, s, uchar(*(p+1)));
             if (s == NULL) return NULL;
             p+=2; goto init;  /* else return match(ms, s, p+2) */
           }
--- lua-5.1-work2/src/luac/print.c	2004-09-01 23:22:34.000000000 +0200
+++ lua-5.1-work2-ctype/src/luac/print.c	2004-10-30 22:22:55.000000000 +0200
@@ -33,7 +33,7 @@
    case '\r': printf("\\r"); break;
    case '\t': printf("\\t"); break;
    case '\v': printf("\\v"); break;
-   default:   printf(isprint(*s) ? "%c" : "\\%03d",*s);
+   default:   printf(isprint((unsigned char)*s) ? "%c" : "\\%03d",*s);
   }
  }
  putchar('"');