...ghmmm... sorry and sorry... and here the patch, it is pretty small: diff -u -r -U 2 -b ../sh.old/Makefile ./Makefile --- ../sh.old/Makefile Sat Apr 19 23:22:31 2003 +++ ./Makefile Sun Apr 20 02:47:41 2003 _at__at_ -19,5 +19,5 _at__at_ LFLAGS= -8 # 8-bit lex scanner for arithmetic -CFLAGS+=-DSHELL -I. -I${.CURDIR} +CFLAGS+=-DSHELL -I. -I${.CURDIR} -DOVERFLOW # for debug: #CFLAGS+= -g -DDEBUG=2 -pg diff -u -r -U 2 -b ../sh.old/arith.h ./arith.h --- ../sh.old/arith.h Fri Jul 19 08:38:51 2002 +++ ./arith.h Sun Apr 20 02:37:37 2003 _at__at_ -35,4 +35,7 _at__at_ */ -int arith(char *); +/* XXX some day probably should go to /usr/include/machine/_inttypes.h */ +#define MAXINT_LEN 20 + +intmax_t arith(char *); int expcmd(int , char **); diff -u -r -U 2 -b ../sh.old/arith.y ./arith.y --- ../sh.old/arith.y Fri Jul 19 08:38:51 2002 +++ ./arith.y Sun Apr 20 03:52:31 2003 _at__at_ -1,2 +1,13 _at__at_ +%{ +#include <stdint.h> +#ifdef OVERFLOW +#include "options.h" +#endif + +#define YYSTYPE intmax_t + +static intmax_t arith_res; +%} + %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN _at__at_ -15,5 +26,6 _at__at_ exp: expr = { - return ($1); + arith_res = $1; + return (0); } ; _at__at_ -34,7 +46,25 _at__at_ | expr ARITH_LSHIFT expr = { $$ = $1 << $3; } | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; } - | expr ARITH_ADD expr = { $$ = $1 + $3; } - | expr ARITH_SUB expr = { $$ = $1 - $3; } - | expr ARITH_MUL expr = { $$ = $1 * $3; } + | expr ARITH_ADD expr = { + $$ = $1 + $3; +#ifdef OVERFLOW + if (Oflag && is_add_overflow($1, $3, $$)) + yyerror("overflow in"); +#endif + } + | expr ARITH_SUB expr = { + $$ = $1 - $3; +#ifdef OVERFLOW + if (Oflag && is_add_overflow($1, -$3, $$)) + yyerror("overflow in"); +#endif + } + | expr ARITH_MUL expr = { + $$ = $1 * $3; +#ifdef OVERFLOW + if (Oflag && $$/$1 != $3 ) + yyerror("overflow in"); +#endif + } | expr ARITH_DIV expr = { if ($3 == 0) _at__at_ -110,16 +140,24 _at__at_ int -arith(char *s) +is_add_overflow(intmax_t a, intmax_t b, intmax_t s) { - long result; + if (a > 0 && b > 0 && s <= 0) + return 1; + if (a < 0 && b < 0 && s >= 0) + return 1; + return 0; +} +intmax_t +arith(char *s) +{ arith_buf = arith_startbuf = s; INTOFF; - result = yyparse(); + yyparse(); arith_lex_reset(); /* reprime lex */ INTON; - return (result); + return (arith_res); } _at__at_ -143,5 +181,5 _at__at_ char *concat; char **ap; - long i; + intmax_t i; if (argc > 1) { _at__at_ -168,5 +206,5 _at__at_ i = arith(p); - out1fmt("%ld\n", i); + out1fmt("%jd\n", i); return (! i); } diff -u -r -U 2 -b ../sh.old/arith_lex.l ./arith_lex.l --- ../sh.old/arith_lex.l Fri Jul 19 08:38:51 2002 +++ ./arith_lex.l Sun Apr 20 02:37:37 2003 _at__at_ -44,8 +44,9 _at__at_ #endif /* not lint */ +#include <stdint.h> #include "y.tab.h" #include "error.h" -extern int yylval; +extern intmax_t yylval; extern char *arith_buf, *arith_startbuf; #undef YY_INPUT _at__at_ -57,5 +58,5 _at__at_ %% [ \t\n] { ; } -[0-9]+ { yylval = atol(yytext); return(ARITH_NUM); } +[0-9]+ { yylval = strtoll(yytext, NULL, 10); return(ARITH_NUM); } "(" { return(ARITH_LPAREN); } ")" { return(ARITH_RPAREN); } diff -u -r -U 2 -b ../sh.old/expand.c ./expand.c --- ../sh.old/expand.c Fri Jan 17 14:37:03 2003 +++ ./expand.c Sun Apr 20 02:37:37 2003 _at__at_ -46,4 +46,5 _at__at_ #include <sys/time.h> #include <sys/stat.h> +#include <stdint.h> #include <errno.h> #include <dirent.h> _at__at_ -367,5 +368,5 _at__at_ { char *p, *start; - int result; + intmax_t result; int begoff; int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); _at__at_ -383,8 +384,8 _at__at_ * characters have to be processed left to right. */ -#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 -#error "integers with more than 10 digits are not supported" -#endif - CHECKSTRSPACE(12 - 2, expdest); +//#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 +//#error "integers with more than 10 digits are not supported" +//#endif + CHECKSTRSPACE(MAXINT_LEN, expdest); USTPUTC('\0', expdest); start = stackblock(); _at__at_ -408,5 +409,5 _at__at_ rmescapes(p+2); result = arith(p+2); - fmtstr(p, 12, "%d", result); + fmtstr(p, MAXINT_LEN + 2, "%qd", result); while (*p++) ; diff -u -r -U 2 -b ../sh.old/options.h ./options.h --- ../sh.old/options.h Tue Aug 27 05:36:28 2002 +++ ./options.h Sun Apr 20 02:24:46 2003 _at__at_ -67,6 +67,13 _at__at_ #define Tflag optlist[16].val #define Pflag optlist[17].val +#ifdef OVERFLOW +#define Oflag optlist[18].val +#endif +#ifdef OVERFLOW +#define NOPTS 19 +#else #define NOPTS 18 +#endif struct optent { _at__at_ -96,4 +103,7 _at__at_ { "trapsasync", 'T', 0 }, { "physical", 'P', 0 }, +#ifdef OVERFLOW + { "overflow", 'O', 0 }, +#endif }; #else diff -u -r -U 2 -b ../sh.old/sh.1 ./sh.1 --- ../sh.old/sh.1 Tue Feb 25 13:27:12 2003 +++ ./sh.1 Sun Apr 20 02:52:02 2003 _at__at_ -44,5 +44,5 _at__at_ .Sh SYNOPSIS .Nm -.Op Fl /+abCEefIimnPpsTuVvx +.Op Fl /+abCEefIimnOPpsTuVvx .Op Fl /+o Ar longname .Op Fl c Ar string _at__at_ -226,4 +226,6 _at__at_ execute them. This is useful for checking the syntax of shell scripts. +.It Fl O Li interactive +If compiled with the overflow checks, turn them during arithmetic operations on. .It Fl P Li physical Change the default for theReceived on Sat Apr 19 2003 - 16:34:05 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:04 UTC