diff --git a/CHANGES b/CHANGES index 8a3f610..069476b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ --- $MawkId: CHANGES,v 1.405 2024/12/10 01:25:31 tom Exp $ +-- $MawkId: CHANGES,v 1.409 2024/12/13 00:44:41 tom Exp $ + +20241212 + + modify calls on stdtod() to disallow hexadecimal, infinite and + not-a-number values unless the "--posix" option is given (report by + Xose Vazquez Perez). + + fix a regression in rexp3.c for pattern /^.$/ (cf: 20240819) 20241209 + modify use of OFMT when given a format such as %c which cannot fully diff --git a/MANIFEST b/MANIFEST index 35a7b9c..bfe0a7f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,4 @@ -MANIFEST for mawk, version t20241209 +MANIFEST for mawk, version t20241212 -------------------------------------------------------------------------------- MANIFEST this file ACKNOWLEDGMENT acknowledgements diff --git a/cast.c b/cast.c index e66ab9d..87cc60f 100644 --- a/cast.c +++ b/cast.c @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: cast.c,v 1.32 2024/11/17 20:39:54 tom Exp $ + * $MawkId: cast.c,v 1.34 2024/12/13 00:20:03 tom Exp $ */ #define Visible_CELL @@ -26,50 +26,91 @@ the GNU General Public License, version 2, 1991. const int mpow2[NUM_CELL_TYPES] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; +#define isXDIGIT(c) \ + (scan_code[(c)] == SC_DIGIT \ + || ((c) >= 'A' && (c) <= 'F') \ + || ((c) >= 'a' && (c) <= 'f')) + +static void +string_to_double(CELL *cp) +{ + const char *q = string(cp)->str; + const char *r = string(cp)->len + q; + + cp->dval = 0.0; + + /* if non-posix, disallow hexadecimal, infinity and not-a-number */ + if (!posix_space_flag) { + const char *s; + + while ((q != r) && (scan_code[(UChar) q[0]] == SC_SPACE)) + q++; + if (q == r) + goto done; + s = q; + if (scan_code[(UChar) q[0]] == SC_PLUS || + scan_code[(UChar) q[0]] == SC_MINUS) + q++; + if (q[0] == '0') { + if (q + 1 == r) /* just "0" is legal */ + goto done; + if (q[1] == 'x' || q[1] == 'X') { + if (q + 2 == r) /* "0x" by itself is zero */ + goto done; + if (isXDIGIT((UChar) q[2])) /* ignore hexadecimal */ + goto done; + } + } else if (scan_code[(UChar) q[0]] != SC_DIGIT && q[0] != '.') { + goto done; /* ignore non-number such as "inf" */ + } + q = s; + } + + errno = 0; +#ifdef FPE_TRAPS_ON /* look for overflow error */ + cp->dval = strtod(q, (char **) 0); + if (errno && cp->dval != 0.0) /* ignore underflow */ + rt_error("overflow converting %s to double", q); +#else + cp->dval = strtod(q, (char **) 0); +#endif + free_STRING(string(cp)); + + done: + cp->type = C_DOUBLE; +} + void cast1_to_d(CELL *cp) { switch (cp->type) { case C_NOINIT: cp->dval = 0.0; + cp->type = C_DOUBLE; break; case C_DOUBLE: - return; + break; case C_MBSTRN: case C_STRING: - { - register STRING *s = (STRING *) cp->ptr; - - errno = 0; -#ifdef FPE_TRAPS_ON /* look for overflow error */ - cp->dval = strtod(s->str, (char **) 0); - if (errno && cp->dval != 0.0) /* ignore underflow */ - rt_error("overflow converting %s to double", s->str); -#else - cp->dval = strtod(s->str, (char **) 0); -#endif - free_STRING(s); - } + string_to_double(cp); break; case C_STRNUM: /* don't need to convert, but do need to free the STRING part */ free_STRING(string(cp)); + cp->type = C_DOUBLE; break; default: bozo("cast on bad type"); } - cp->type = C_DOUBLE; } void cast2_to_d(CELL *cp) { - register STRING *s; - switch (cp->type) { case C_NOINIT: cp->dval = 0.0; @@ -83,17 +124,7 @@ cast2_to_d(CELL *cp) case C_MBSTRN: case C_STRING: - s = (STRING *) cp->ptr; - - errno = 0; -#ifdef FPE_TRAPS_ON /* look for overflow error */ - cp->dval = strtod(s->str, (char **) 0); - if (errno && cp->dval != 0.0) /* ignore underflow */ - rt_error("overflow converting %s to double", s->str); -#else - cp->dval = strtod(s->str, (char **) 0); -#endif - free_STRING(s); + string_to_double(cp); break; default: @@ -117,17 +148,7 @@ cast2_to_d(CELL *cp) case C_MBSTRN: case C_STRING: - s = (STRING *) cp->ptr; - - errno = 0; -#ifdef FPE_TRAPS_ON /* look for overflow error */ - cp->dval = strtod(s->str, (char **) 0); - if (errno && cp->dval != 0.0) /* ignore underflow */ - rt_error("overflow converting %s to double", s->str); -#else - cp->dval = strtod(s->str, (char **) 0); -#endif - free_STRING(s); + string_to_double(cp); break; default: @@ -321,6 +342,7 @@ check_strnum(CELL *cp) { char *temp; register unsigned char *s, *q; + char code; cp->type = C_STRING; /* assume not C_STRNUM */ s = (unsigned char *) string(cp)->str; @@ -330,16 +352,27 @@ check_strnum(CELL *cp) if (s == q) return; - while (scan_code[q[-1]] == SC_SPACE) + while ((code = scan_code[q[-1]]) == SC_SPACE) q--; - if (scan_code[q[-1]] != SC_DIGIT && - q[-1] != '.') + if (code != SC_DIGIT && code != SC_DOT) return; switch (scan_code[*s]) { - case SC_DIGIT: case SC_PLUS: case SC_MINUS: + if (!posix_space_flag) { + if ((code = scan_code[s[1]]) != SC_DIGIT && code != SC_DOT) + return; + } + /* FALLTHRU */ + case SC_DIGIT: + if (!posix_space_flag) { + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') + return; + } + } + /* FALLTHRU */ case SC_DOT: errno = 0; diff --git a/error.c b/error.c index 44cbe84..8de7d2a 100644 --- a/error.c +++ b/error.c @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: error.c,v 1.28 2024/08/29 00:19:40 tom Exp $ + * $MawkId: error.c,v 1.29 2024/12/11 21:57:28 tom Exp $ */ #define Visible_CELL @@ -156,6 +156,7 @@ yyerror(const char *s GCC_UNUSED) unexpected_char(); break; +#ifndef LCOV_UNUSED case BAD_DECIMAL: compile_error( "syntax error in decimal constant %s", @@ -167,6 +168,7 @@ yyerror(const char *s GCC_UNUSED) "syntax error at or near /%s/", string_buff); break; +#endif default: compile_error("syntax error"); @@ -306,15 +308,18 @@ type_to_str(int type) case ST_VAR: retval = "variable"; break; +#ifndef LCOV_UNUSED case ST_KEYWORD: retval = "keyword"; break; case ST_BUILTIN: retval = "builtin"; break; +#endif case ST_ARRAY: retval = "array"; break; +#ifndef LCOV_UNUSED case ST_FIELD: retval = "field"; break; @@ -327,6 +332,7 @@ type_to_str(int type) case ST_FUNCT: retval = "function"; break; +#endif case ST_LOCAL_VAR: retval = "local variable"; break; diff --git a/package/debian/changelog b/package/debian/changelog index 4411770..55112da 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,10 +1,10 @@ -mawk-cur (1.3.4-20241209) unstable; urgency=low +mawk-cur (1.3.4-20241212) unstable; urgency=low * maintenance updates - -- Thomas E. Dickey Mon, 09 Dec 2024 03:36:10 -0500 + -- Thomas E. Dickey Tue, 10 Dec 2024 19:46:15 -0500 -mawk-cur (1.3.4-20241118) unstable; urgency=low +mawk-cur (1.3.4-20241209) unstable; urgency=low * maintenance updates diff --git a/package/freebsd/Makefile b/package/freebsd/Makefile index 23c9dc7..28abe18 100644 --- a/package/freebsd/Makefile +++ b/package/freebsd/Makefile @@ -2,7 +2,7 @@ # $FreeBSD: head/lang/mawk/Makefile 516890 2019-11-06 14:17:48Z wen $ PORTNAME= mawk -DISTVERSION= 1.3.4.20241209 +DISTVERSION= 1.3.4.20241212 CATEGORIES= lang MASTER_SITES= https://invisible-island.net/archives/${PORTNAME}/ \ https://invisible-mirror.net/archives/${PORTNAME}/ diff --git a/package/mawk.spec b/package/mawk.spec index f2404e3..9167d29 100644 --- a/package/mawk.spec +++ b/package/mawk.spec @@ -1,9 +1,9 @@ Summary: mawk - pattern scanning and text processing language %global AppProgram mawk %global AppVersion 1.3.4 -%global AppPatched 20241209 +%global AppPatched 20241212 %global MySite https://invisible-island.net -# $MawkId: mawk.spec,v 1.132 2024/12/10 01:25:31 tom Exp $ +# $MawkId: mawk.spec,v 1.134 2024/12/13 00:44:41 tom Exp $ Name: %{AppProgram} Version: %{AppVersion} Release: %{AppPatched} diff --git a/patchlev.h b/patchlev.h index 9ecb0af..c7b677c 100644 --- a/patchlev.h +++ b/patchlev.h @@ -11,9 +11,9 @@ the GNU General Public License, version 2, 1991. */ /* - * $MawkId: patchlev.h,v 1.159 2024/12/10 01:25:31 tom Exp $ + * $MawkId: patchlev.h,v 1.161 2024/12/13 00:44:41 tom Exp $ */ #define PATCH_BASE 1 #define PATCH_LEVEL 3 #define PATCH_STRING ".4" -#define DATE_STRING "20241209" +#define DATE_STRING "20241212" diff --git a/rexp2.c b/rexp2.c index 7eea9d9..4803c0d 100644 --- a/rexp2.c +++ b/rexp2.c @@ -12,7 +12,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: rexp2.c,v 1.46 2024/09/05 17:44:48 tom Exp $ + * $MawkId: rexp2.c,v 1.48 2024/12/10 21:34:14 tom Exp $ */ /* test a string against a machine */ @@ -322,7 +322,6 @@ REtest(char *str, /* string to test */ m++; RE_CASE(); -#ifndef LCOV_UNUSED case M_ANY + U_OFF + END_ON: /* NOTREACHED */ if (s >= str_end || (s + 1) < str_end) { @@ -331,7 +330,6 @@ REtest(char *str, /* string to test */ s++; m++; RE_CASE(); -#endif case M_ANY + U_ON + END_OFF: if (s >= str_end) { @@ -343,7 +341,6 @@ REtest(char *str, /* string to test */ u_flag = U_OFF; RE_CASE(); -#ifndef LCOV_UNUSED case M_ANY + U_ON + END_ON: /* NOTREACHED */ if (s >= str_end) { @@ -353,7 +350,6 @@ REtest(char *str, /* string to test */ m++; u_flag = U_OFF; RE_CASE(); -#endif case M_START + U_OFF + END_OFF: case M_START + U_ON + END_OFF: diff --git a/rexp3.c b/rexp3.c index 298b87c..0f70cbe 100644 --- a/rexp3.c +++ b/rexp3.c @@ -12,7 +12,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: rexp3.c,v 1.65 2024/08/27 20:48:02 tom Exp $ + * $MawkId: rexp3.c,v 1.69 2024/12/11 21:45:11 tom Exp $ */ /* match a string against a machine */ @@ -214,9 +214,7 @@ REmatch(char *str, /* string to test */ TR_AT("next"); RE_CASE(); -#ifndef LCOV_UNUSED case M_STR + U_ON + END_ON: - /* NOTREACHED */ TR_AT("now"); if (s >= str_end) { RE_FILL(); @@ -241,7 +239,6 @@ REmatch(char *str, /* string to test */ u_flag = U_OFF; TR_AT("next"); RE_CASE(); -#endif case M_CLASS + U_OFF + END_OFF: if (s >= str_end) { @@ -332,10 +329,8 @@ REmatch(char *str, /* string to test */ m++; RE_CASE(); -#ifndef LCOV_UNUSED case M_ANY + U_OFF + END_ON: - /* NOTREACHED */ - if (s >= str_end) { + if ((s >= str_end) || ((s + 1) < str_end)) { RE_FILL(); } else if (!ss) { if (cb_ss && current_best(s)) { @@ -347,7 +342,6 @@ REmatch(char *str, /* string to test */ s = str_end; m++; RE_CASE(); -#endif case M_ANY + U_ON + END_OFF: if (s < str) @@ -368,9 +362,7 @@ REmatch(char *str, /* string to test */ u_flag = U_OFF; RE_CASE(); -#ifndef LCOV_UNUSED case M_ANY + U_ON + END_ON: - /* NOTREACHED */ if (s < str) s = str; if (s >= str_end) { @@ -388,7 +380,6 @@ REmatch(char *str, /* string to test */ m++; u_flag = U_OFF; RE_CASE(); -#endif CASE_UANY(M_START + END_OFF): if (s != str || no_bol) { diff --git a/test/mawkerrs b/test/mawkerrs index eb2bebe..5d447f5 100755 --- a/test/mawkerrs +++ b/test/mawkerrs @@ -1,5 +1,5 @@ #!/bin/sh -# $MawkId: mawkerrs,v 1.19 2024/11/11 23:40:39 tom Exp $ +# $MawkId: mawkerrs,v 1.21 2024/12/11 00:43:22 tom Exp $ ############################################################################### # copyright 2024, Thomas E. Dickey # @@ -245,11 +245,26 @@ echo 'mawk: line 1: illegal reference to variable bar' >$STDERR $PROG -Wd 'function foo() { bar = 1; }function bar(){ }BEGIN{ print(); }' 2>&1 | cmp -s - "$STDERR" || Fail "illegal reference to variable" Finish "test for illegal reference to variable" +Begin "test for illegal reference to variable NR" +echo 'mawk: line 1: illegal reference to variable NR' >$STDERR +$PROG -Wd '{ NR[1] = "alpha"; }' 2>&1 | cmp -s - "$STDERR" || Fail "illegal reference to array ENVIRON" +Finish "test for illegal reference to variable NR" + Begin "test for illegal reference to array" echo 'mawk: line 1: illegal reference to array A' >$STDERR $PROG -Wd 'function foo() { A[1] = 1; }function A(){ }BEGIN{ print(); }' 2>&1 | cmp -s - "$STDERR" || Fail "illegal reference to array" Finish "test for illegal reference to array" +Begin "test for illegal reference to array ENVIRON" +echo 'mawk: line 1: illegal reference to array ENVIRON' >$STDERR +$PROG -Wd '{ ENVIRON = "alpha"; }' 2>&1 | cmp -s - "$STDERR" || Fail "illegal reference to array ENVIRON" +Finish "test for illegal reference to array ENVIRON" + +Begin "test for reference to undefined function" +echo 'mawk: line 2: function f never defined' >$STDERR +$PROG -Wd '{ f(z); }' 2>&1 | cmp -s - "$STDERR" || Fail "illegal reference to undefined function" +Finish "test for reference to undefined function" + ######## print.c Begin "test sprintf buffer-overflow"