tcmd/yacc: check that arg is safe to pass to <ctype.h> isX functions - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit eb4aea5072dcca2dfee2ff4d551352dae73a821c
 (DIR) parent d2fae53d17c120530a6d12facd8e0fc297331821
 (HTM) Author: Neven Sajko <nsajko@gmail.com>
       Date:   Sun, 25 Aug 2019 13:53:10 +0000
       
       cmd/yacc: check that arg is safe to pass to <ctype.h> isX functions
       
       The functions from <ctype.h> require that their argument be
       representable as an unsigned char, anything else is an error.
       
       Change-Id: I9dafc49c431b7a2550b041603f27bac3c0010eea
       
       Diffstat:
         M src/cmd/yacc.c                      |      19 ++++++++++++++-----
       
       1 file changed, 14 insertions(+), 5 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/yacc.c b/src/cmd/yacc.c
       t@@ -349,6 +349,7 @@ void        finact(void);
        int        defin(int, char*);
        void        defout(int);
        char*        cstash(char*);
       +int        isvalidchar(long);
        long        gettok(void);
        int        fdtype(int);
        int        chfind(int, char*);
       t@@ -1680,6 +1681,12 @@ cstash(char *s)
                return temp;
        }
        
       +int
       +isvalidchar(long i)
       +{
       +        return (i & ~0xffUL) == 0;
       +}
       +
        long
        gettok(void)
        {
       t@@ -1774,6 +1781,8 @@ begin:
        
                default:
                        /* number */
       +                if(!isvalidchar(c))
       +                        return c;
                        if(isdigit(c)) {
                                numbval = c-'0';
                                base = (c=='0')? 8: 10;
       t@@ -1784,8 +1793,8 @@ begin:
                        }
                        if(islower(c) || isupper(c) || c=='_' || c=='.' || c=='$')  {
                                i = 0;
       -                        while(islower(c) || isupper(c) || isdigit(c) ||
       -                            c == '-' || c=='_' || c=='.' || c=='$') {
       +                        while(isvalidchar(c) && (islower(c) || isupper(c) || isdigit(c) ||
       +                            c == '-' || c=='_' || c=='.' || c=='$')) {
                                        if(reserve && isupper(c))
                                                c += 'a'-'A';
                                        rune = c;
       t@@ -2028,7 +2037,7 @@ swt:
                                s = -s;
                                c = Bgetrune(finput);
                        }
       -                if(isdigit(c)) {
       +                if(isvalidchar(c) && isdigit(c)) {
                                j = 0;
                                while(isdigit(c)) {
                                        j = j*10 + (c-'0');
       t@@ -2052,7 +2061,7 @@ swt:
                                }
                                goto loop;
                        }
       -                if(isupper(c) || islower(c) || c == '_' || c == '.') {
       +                if(isvalidchar(c) && (isupper(c) || islower(c) || c == '_' || c == '.')) {
                                int tok; /* tok used oustide for type info */
        
                                /* look for $name */
       t@@ -2963,7 +2972,7 @@ gtnm(void)
                sign = 0;
                val = 0;
                while((c=Bgetrune(finput)) != Beof) {
       -                if(isdigit(c)) {
       +                if(isvalidchar(c) && isdigit(c)) {
                                val = val*10 + c-'0';
                                continue;
                        }