From 28d7bf8a5130fe40808668a21384fa275fe9d6fe Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Tue, 27 Aug 2024 23:54:59 +0000 Subject: [PATCH] snapshot of project "mawk", label t20240827 --- CHANGES | 8 +- MANIFEST | 2 +- bi_funct.c | 4 +- config.guess | 15 +- config.sub | 733 +++++++++++++++++++++++++++++---------- execute.c | 18 +- package/debian/changelog | 6 + package/freebsd/Makefile | 2 +- package/mawk.spec | 4 +- parse.c | 396 ++++++++++----------- parse.y | 22 +- patchlev.h | 4 +- rexp3.c | 7 +- symtype.h | 3 +- test/mawkerrs | 49 ++- 15 files changed, 869 insertions(+), 404 deletions(-) diff --git a/CHANGES b/CHANGES index e778cb3..7e4e9b6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ --- $MawkId: CHANGES,v 1.386 2024/08/25 22:51:21 tom Exp $ +-- $MawkId: CHANGES,v 1.391 2024/08/27 23:54:59 tom Exp $ + +20240827 + + amend fix for Original Mawk #48, providing for deep function + recursion, but disallowing more than 255 parameters for printf, etc. + + add test-cases to test/mawkerrs + + update config.guess and config.sub 20240825 + modify struct declarations to simplify further changes to reduce use diff --git a/MANIFEST b/MANIFEST index 3e8c1af..a9cb427 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,4 @@ -MANIFEST for mawk, version t20240825 +MANIFEST for mawk, version t20240827 -------------------------------------------------------------------------------- MANIFEST this file ACKNOWLEDGMENT acknowledgements diff --git a/bi_funct.c b/bi_funct.c index dc2adc6..672e9f1 100644 --- a/bi_funct.c +++ b/bi_funct.c @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: bi_funct.c,v 1.131 2024/08/25 18:27:52 tom Exp $ + * $MawkId: bi_funct.c,v 1.132 2024/08/26 08:11:02 tom Exp $ */ #define Visible_ARRAY @@ -63,7 +63,7 @@ const BI_REC bi_funct[] = { "index", bi_index, 2, 2 }, { "substr", bi_substr, 2, 3 }, - { "sprintf", bi_sprintf, 1, 255 }, + { "sprintf", bi_sprintf, 1, MAX_ARGS }, { "sin", bi_sin, 1, 1 }, { "cos", bi_cos, 1, 1 }, { "atan2", bi_atan2, 2, 2 }, diff --git a/config.guess b/config.guess index f47d666..48a6846 100755 --- a/config.guess +++ b/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2023 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2023-10-19' +timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -60,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2023 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -123,7 +123,7 @@ set_cc_for_build() { dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do + for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break @@ -634,7 +634,8 @@ EOF sed 's/^ //' << EOF > "$dummy.c" #include - main() + int + main () { if (!__power_pc()) exit(1); @@ -718,7 +719,8 @@ EOF #include #include - int main () + int + main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); @@ -1621,6 +1623,7 @@ cat > "$dummy.c" <." version="\ GNU config.sub ($timestamp) -Copyright 1992-2023 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -120,7 +120,6 @@ case $# in esac # Split fields of configuration type -# shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; - kfreebsd*-gnu*- | kopensolaris*-gnu*-) + kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; @@ -1864,6 +2245,8 @@ case $kernel-$os-$obj in ;; os2-emx-) ;; + rtmk-nova-) + ;; *-eabi*- | *-gnueabi*-) ;; none--*) @@ -1890,7 +2273,7 @@ case $vendor in *-riscix*) vendor=acorn ;; - *-sunos*) + *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) diff --git a/execute.c b/execute.c index 59f1e81..44360a9 100644 --- a/execute.c +++ b/execute.c @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: execute.c,v 1.60 2024/08/25 19:43:50 tom Exp $ + * $MawkId: execute.c,v 1.61 2024/08/26 23:38:53 tom Exp $ */ #define Visible_ARRAY @@ -45,11 +45,8 @@ static char dz_msg[] = "division by zero"; #define CHECK_DIVZERO(x) do { if ((x) == 0.0 ) rt_error(dz_msg); } while (0) #endif -#define inc_sp() if ( ++sp == stack_danger) eval_overflow() -#define dec_sp() if ( sp-- == stack_under) eval_underflow() - #define SAFETY 16 -#define DANGER (EVAL_STACK_SIZE-SAFETY) +#define DANGER (EVAL_STACK_SIZE - SAFETY - MAX_ARGS) /* The stack machine that executes the code */ @@ -59,6 +56,7 @@ static CELL *stack_base = eval_stack; static CELL *stack_under = eval_stack; static CELL *stack_danger = eval_stack + DANGER; +#ifdef DEBUG static void eval_overflow(void) { @@ -71,6 +69,16 @@ eval_underflow(void) bozo("eval stack underflow"); } +#define inc_sp() if ( ++sp == stack_danger) eval_overflow() +#define dec_sp() if ( sp-- == stack_under) eval_underflow() + +#else + +#define inc_sp() ++sp +#define dec_sp() sp-- + +#endif + /* holds info for array loops (on a stack) */ typedef struct aloop_state { struct aloop_state *link; diff --git a/package/debian/changelog b/package/debian/changelog index 1d244cd..d348d46 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,3 +1,9 @@ +mawk-cur (1.3.4-20240827) unstable; urgency=low + + * maintenance updates + + -- Thomas E. Dickey Sun, 25 Aug 2024 19:46:51 -0400 + mawk-cur (1.3.4-20240825) unstable; urgency=low * maintenance updates diff --git a/package/freebsd/Makefile b/package/freebsd/Makefile index 2003304..08e9201 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.20240825 +DISTVERSION= 1.3.4.20240827 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 eef58b8..14f7ba1 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 20240825 +%global AppPatched 20240827 %global MySite https://invisible-island.net -# $MawkId: mawk.spec,v 1.124 2024/08/25 22:51:21 tom Exp $ +# $MawkId: mawk.spec,v 1.126 2024/08/27 07:48:11 tom Exp $ Name: %{AppProgram} Version: %{AppVersion} Release: %{AppPatched} diff --git a/parse.c b/parse.c index 268b9b1..9112cb7 100644 --- a/parse.c +++ b/parse.c @@ -1704,7 +1704,7 @@ static YYINT *yylexp = 0; static YYINT *yylexemes = 0; #endif /* YYBTYACC */ -#line 1184 "parse.y" +#line 1192 "parse.y" /* * Check for special case where there is a forward reference to a newly @@ -3119,112 +3119,120 @@ case 81: #line 432 "parse.y" { const BI_REC *p = yystack.l_mark[-4].bip ; yyval.start = yystack.l_mark[-3].start ; - if ( (int)p->min_args > yystack.l_mark[-1].ival || (int)p->max_args < yystack.l_mark[-1].ival ) - compile_error( - "wrong number of arguments in call to %s" , - p->name ) ; + if ( (int)p->min_args > yystack.l_mark[-1].ival ) + compile_error( + "not enough arguments in call to %s: %d (need %d)" , + p->name, yystack.l_mark[-1].ival, (int)p->min_args ) ; + if ( (int)p->max_args < yystack.l_mark[-1].ival ) + compile_error( + "too many arguments in call to %s: %d (maximum %d)" , + p->name, yystack.l_mark[-1].ival, (int)p->max_args ) ; if ( p->min_args != p->max_args ) /* variable args */ { code1(_PUSHINT) ; code1(yystack.l_mark[-1].ival) ; } func2(_BUILTIN , p->fp) ; } -#line 3131 "parse.c" +#line 3135 "parse.c" break; case 82: -#line 446 "parse.y" +#line 450 "parse.y" { yyval.start = code_offset ; } -#line 3136 "parse.c" +#line 3140 "parse.c" break; case 83: -#line 451 "parse.y" +#line 455 "parse.y" { func2(_PRINT, yystack.l_mark[-4].fp) ; + if ( yystack.l_mark[-2].ival > MAX_ARGS ) + compile_error("too many arguments in call to %s: %d (maximum %d)", + ( yystack.l_mark[-4].fp == bi_printf ) ? "printf" : "print", + yystack.l_mark[-2].ival, MAX_ARGS) ; if ( yystack.l_mark[-4].fp == bi_printf && yystack.l_mark[-2].ival == 0 ) - compile_error("no arguments in call to printf") ; + compile_error("no arguments in call to printf") ; print_flag = 0 ; yyval.start = yystack.l_mark[-3].start ; } -#line 3146 "parse.c" +#line 3154 "parse.c" break; case 84: -#line 459 "parse.y" +#line 467 "parse.y" { yyval.fp = bi_print ; print_flag = 1 ;} -#line 3151 "parse.c" +#line 3159 "parse.c" break; case 85: -#line 460 "parse.y" +#line 468 "parse.y" { yyval.fp = bi_printf ; print_flag = 1 ; } -#line 3156 "parse.c" +#line 3164 "parse.c" break; case 86: -#line 463 "parse.y" +#line 471 "parse.y" { code2op(_PUSHINT, yystack.l_mark[0].ival) ; } -#line 3161 "parse.c" +#line 3169 "parse.c" break; case 87: -#line 465 "parse.y" +#line 473 "parse.y" { yyval.ival = yystack.l_mark[-1].arg2p->cnt ; zfree(yystack.l_mark[-1].arg2p,sizeof(ARG2_REC)) ; code2op(_PUSHINT, yyval.ival) ; } -#line 3168 "parse.c" +#line 3176 "parse.c" break; case 88: -#line 469 "parse.y" +#line 477 "parse.y" { yyval.ival=0 ; code2op(_PUSHINT, 0) ; } -#line 3173 "parse.c" +#line 3181 "parse.c" break; case 89: -#line 473 "parse.y" +#line 481 "parse.y" { yyval.arg2p = ZMALLOC(ARG2_REC) ; yyval.arg2p->start = yystack.l_mark[-2].start ; yyval.arg2p->cnt = 2 ; } -#line 3181 "parse.c" +#line 3189 "parse.c" break; case 90: -#line 478 "parse.y" +#line 486 "parse.y" { yyval.arg2p = yystack.l_mark[-2].arg2p ; yyval.arg2p->cnt++ ; } -#line 3186 "parse.c" +#line 3194 "parse.c" break; case 92: -#line 483 "parse.y" +#line 491 "parse.y" { code2op(_PUSHINT, yystack.l_mark[-1].ival) ; } -#line 3191 "parse.c" +#line 3199 "parse.c" break; case 93: -#line 490 "parse.y" +#line 498 "parse.y" { yyval.start = yystack.l_mark[-1].start ; eat_nl() ; code_jmp(_JZ, (INST*)0) ; } -#line 3196 "parse.c" +#line 3204 "parse.c" break; case 94: -#line 495 "parse.y" +#line 503 "parse.y" { patch_jmp( code_ptr ) ; } -#line 3201 "parse.c" +#line 3209 "parse.c" break; case 95: -#line 498 "parse.y" +#line 506 "parse.y" { eat_nl() ; code_jmp(_JMP, (INST*)0) ; } -#line 3206 "parse.c" +#line 3214 "parse.c" break; case 96: -#line 503 "parse.y" +#line 511 "parse.y" { patch_jmp(code_ptr) ; patch_jmp(CDP(yystack.l_mark[0].start)) ; } -#line 3213 "parse.c" +#line 3221 "parse.c" break; case 97: -#line 512 "parse.y" +#line 520 "parse.y" { eat_nl() ; BC_new() ; } -#line 3218 "parse.c" +#line 3226 "parse.c" break; case 98: -#line 517 "parse.y" +#line 525 "parse.y" { yyval.start = yystack.l_mark[-5].start ; code_jmp(_JNZ, CDP(yystack.l_mark[-5].start)) ; BC_clear(code_ptr, CDP(yystack.l_mark[-2].start)) ; } -#line 3225 "parse.c" +#line 3233 "parse.c" break; case 99: -#line 523 "parse.y" +#line 531 "parse.y" { eat_nl() ; BC_new() ; yyval.start = yystack.l_mark[-1].start ; @@ -3241,10 +3249,10 @@ case 99: code2(_JMP, (INST*)0) ; /* code2() not code_jmp() */ } } -#line 3245 "parse.c" +#line 3253 "parse.c" break; case 100: -#line 543 "parse.y" +#line 551 "parse.y" { INST *p1 = CDP(yystack.l_mark[-1].start) ; INST *p2 = CDP(yystack.l_mark[0].start) ; @@ -3267,10 +3275,10 @@ case 100: BC_clear(code_ptr, CDP(yystack.l_mark[0].start)) ; } } -#line 3271 "parse.c" +#line 3279 "parse.c" break; case 101: -#line 570 "parse.y" +#line 578 "parse.y" { int cont_offset = code_offset ; unsigned len = code_pop(code_ptr) ; @@ -3292,25 +3300,25 @@ case 101: BC_clear(code_ptr, CDP(cont_offset)) ; } -#line 3296 "parse.c" +#line 3304 "parse.c" break; case 102: -#line 593 "parse.y" +#line 601 "parse.y" { yyval.start = code_offset ; } -#line 3301 "parse.c" +#line 3309 "parse.c" break; case 103: -#line 595 "parse.y" +#line 603 "parse.y" { yyval.start = yystack.l_mark[-1].start ; code1(_POP) ; } -#line 3306 "parse.c" +#line 3314 "parse.c" break; case 104: -#line 598 "parse.y" +#line 606 "parse.y" { yyval.start = code_offset ; } -#line 3311 "parse.c" +#line 3319 "parse.c" break; case 105: -#line 600 "parse.y" +#line 608 "parse.y" { if ( code_ptr - 2 == CDP(yystack.l_mark[-1].start) && code_ptr[-2].op == _PUSHD && @@ -3325,17 +3333,17 @@ case 105: code2(_JMP, (INST*)0) ; } } -#line 3329 "parse.c" +#line 3337 "parse.c" break; case 106: -#line 617 "parse.y" +#line 625 "parse.y" { eat_nl() ; BC_new() ; code_push((INST*)0,0, scope, active_funct) ; } -#line 3336 "parse.c" +#line 3344 "parse.c" break; case 107: -#line 621 "parse.y" +#line 629 "parse.y" { INST *p1 = CDP(yystack.l_mark[-1].start) ; eat_nl() ; BC_new() ; @@ -3343,18 +3351,18 @@ case 107: code_push(p1, (unsigned) CodeOffset(p1), scope, active_funct) ; code_ptr -= code_ptr - p1 ; } -#line 3347 "parse.c" +#line 3355 "parse.c" break; case 108: -#line 634 "parse.y" +#line 642 "parse.y" { check_array(yystack.l_mark[0].stp) ; code_array(yystack.l_mark[0].stp) ; code1(A_TEST) ; } -#line 3355 "parse.c" +#line 3363 "parse.c" break; case 109: -#line 639 "parse.y" +#line 647 "parse.y" { yyval.start = yystack.l_mark[-3].arg2p->start ; code2op(A_CAT, yystack.l_mark[-3].arg2p->cnt) ; zfree(yystack.l_mark[-3].arg2p, sizeof(ARG2_REC)) ; @@ -3363,10 +3371,10 @@ case 109: code_array(yystack.l_mark[0].stp) ; code1(A_TEST) ; } -#line 3367 "parse.c" +#line 3375 "parse.c" break; case 110: -#line 650 "parse.y" +#line 658 "parse.y" { if ( yystack.l_mark[-1].ival > 1 ) { code2op(A_CAT, yystack.l_mark[-1].ival) ; } @@ -3377,10 +3385,10 @@ case 110: else code2(AE_PUSHA, yystack.l_mark[-4].stp->stval.array) ; yyval.start = yystack.l_mark[-3].start ; } -#line 3381 "parse.c" +#line 3389 "parse.c" break; case 111: -#line 663 "parse.y" +#line 671 "parse.y" { if ( yystack.l_mark[-1].ival > 1 ) { code2op(A_CAT, yystack.l_mark[-1].ival) ; } @@ -3391,10 +3399,10 @@ case 111: else code2(AE_PUSHI, yystack.l_mark[-4].stp->stval.array) ; yyval.start = yystack.l_mark[-3].start ; } -#line 3395 "parse.c" +#line 3403 "parse.c" break; case 112: -#line 675 "parse.y" +#line 683 "parse.y" { if ( yystack.l_mark[-2].ival > 1 ) { code2op(A_CAT,yystack.l_mark[-2].ival) ; } @@ -3408,10 +3416,10 @@ case 112: yyval.start = yystack.l_mark[-4].start ; } -#line 3412 "parse.c" +#line 3420 "parse.c" break; case 113: -#line 692 "parse.y" +#line 700 "parse.y" { yyval.start = yystack.l_mark[-4].start ; if ( yystack.l_mark[-2].ival > 1 ) { code2op(A_CAT, yystack.l_mark[-2].ival) ; } @@ -3419,20 +3427,20 @@ case 113: code_array(yystack.l_mark[-5].stp) ; code1(A_DEL) ; } -#line 3423 "parse.c" +#line 3431 "parse.c" break; case 114: -#line 700 "parse.y" +#line 708 "parse.y" { yyval.start = code_offset ; check_array(yystack.l_mark[-1].stp) ; code_array(yystack.l_mark[-1].stp) ; code1(DEL_A) ; } -#line 3433 "parse.c" +#line 3441 "parse.c" break; case 115: -#line 711 "parse.y" +#line 719 "parse.y" { eat_nl() ; BC_new() ; yyval.start = code_offset ; @@ -3443,10 +3451,10 @@ case 115: code2(SET_ALOOP, (INST*)0) ; } -#line 3447 "parse.c" +#line 3455 "parse.c" break; case 116: -#line 725 "parse.y" +#line 733 "parse.y" { INST *p2 = CDP(yystack.l_mark[0].start) ; @@ -3455,15 +3463,15 @@ case 116: code_jmp(ALOOP, p2) ; code1(POP_AL) ; } -#line 3459 "parse.c" +#line 3467 "parse.c" break; case 117: -#line 742 "parse.y" +#line 750 "parse.y" { yyval.start = code_offset ; code2(F_PUSHA, yystack.l_mark[0].cp) ; } -#line 3464 "parse.c" +#line 3472 "parse.c" break; case 118: -#line 744 "parse.y" +#line 752 "parse.y" { check_var(yystack.l_mark[0].stp) ; yyval.start = code_offset ; if ( is_local(yystack.l_mark[0].stp) ) @@ -3472,10 +3480,10 @@ case 118: CODE_FE_PUSHA() ; } -#line 3476 "parse.c" +#line 3484 "parse.c" break; case 119: -#line 753 "parse.y" +#line 761 "parse.y" { if ( yystack.l_mark[-1].ival > 1 ) { code2op(A_CAT, yystack.l_mark[-1].ival) ; } @@ -3489,78 +3497,78 @@ case 119: yyval.start = yystack.l_mark[-3].start ; } -#line 3493 "parse.c" +#line 3501 "parse.c" break; case 120: -#line 767 "parse.y" +#line 775 "parse.y" { yyval.start = yystack.l_mark[0].start ; CODE_FE_PUSHA() ; } -#line 3498 "parse.c" +#line 3506 "parse.c" break; case 121: -#line 769 "parse.y" +#line 777 "parse.y" { yyval.start = yystack.l_mark[-1].start ; } -#line 3503 "parse.c" +#line 3511 "parse.c" break; case 122: -#line 773 "parse.y" +#line 781 "parse.y" { field_A2I() ; } -#line 3508 "parse.c" +#line 3516 "parse.c" break; case 123: -#line 776 "parse.y" +#line 784 "parse.y" { code1(F_ASSIGN) ; } -#line 3513 "parse.c" +#line 3521 "parse.c" break; case 124: -#line 777 "parse.y" +#line 785 "parse.y" { code1(F_ADD_ASG) ; } -#line 3518 "parse.c" +#line 3526 "parse.c" break; case 125: -#line 778 "parse.y" +#line 786 "parse.y" { code1(F_SUB_ASG) ; } -#line 3523 "parse.c" +#line 3531 "parse.c" break; case 126: -#line 779 "parse.y" +#line 787 "parse.y" { code1(F_MUL_ASG) ; } -#line 3528 "parse.c" +#line 3536 "parse.c" break; case 127: -#line 780 "parse.y" +#line 788 "parse.y" { code1(F_DIV_ASG) ; } -#line 3533 "parse.c" +#line 3541 "parse.c" break; case 128: -#line 781 "parse.y" +#line 789 "parse.y" { code1(F_MOD_ASG) ; } -#line 3538 "parse.c" +#line 3546 "parse.c" break; case 129: -#line 782 "parse.y" +#line 790 "parse.y" { code1(F_POW_ASG) ; } -#line 3543 "parse.c" +#line 3551 "parse.c" break; case 130: -#line 789 "parse.y" +#line 797 "parse.y" { func2(_BUILTIN, bi_split) ; } -#line 3548 "parse.c" +#line 3556 "parse.c" break; case 131: -#line 793 "parse.y" +#line 801 "parse.y" { yyval.start = yystack.l_mark[-2].start ; check_array(yystack.l_mark[0].stp) ; code_array(yystack.l_mark[0].stp) ; } -#line 3556 "parse.c" +#line 3564 "parse.c" break; case 132: -#line 800 "parse.y" +#line 808 "parse.y" { code2(_PUSHI, &fs_shadow) ; } -#line 3561 "parse.c" +#line 3569 "parse.c" break; case 133: -#line 802 "parse.y" +#line 810 "parse.y" { if ( CDP(yystack.l_mark[-1].start) == code_ptr - 2 ) { @@ -3580,25 +3588,25 @@ case 133: } } } -#line 3584 "parse.c" +#line 3592 "parse.c" break; case 134: -#line 825 "parse.y" +#line 833 "parse.y" { yyval.start = code_offset ; code2(_PUSHI,field) ; func2(_BUILTIN,bi_length) ; } -#line 3592 "parse.c" +#line 3600 "parse.c" break; case 135: -#line 830 "parse.y" +#line 838 "parse.y" { yyval.start = yystack.l_mark[-1].start ; func2(_BUILTIN,bi_length) ; } -#line 3599 "parse.c" +#line 3607 "parse.c" break; case 136: -#line 834 "parse.y" +#line 842 "parse.y" { SYMTAB* stp = yystack.l_mark[-1].stp; yyval.start = code_offset; @@ -3645,25 +3653,25 @@ case 136: break; } } -#line 3649 "parse.c" +#line 3657 "parse.c" break; case 137: -#line 882 "parse.y" +#line 890 "parse.y" { yyval.start = code_offset ; code2(_PUSHI,field) ; func2(_BUILTIN,bi_length) ; } -#line 3657 "parse.c" +#line 3665 "parse.c" break; case 138: -#line 891 "parse.y" +#line 899 "parse.y" { yyval.start = yystack.l_mark[-3].start ; func2(_BUILTIN, bi_match) ; } -#line 3664 "parse.c" +#line 3672 "parse.c" break; case 139: -#line 898 "parse.y" +#line 906 "parse.y" { INST *p1 = CDP(yystack.l_mark[0].start) ; @@ -3683,92 +3691,92 @@ case 139: } } } -#line 3687 "parse.c" +#line 3695 "parse.c" break; case 140: -#line 922 "parse.y" +#line 930 "parse.y" { yyval.start = code_offset ; code1(_EXIT0) ; } -#line 3693 "parse.c" +#line 3701 "parse.c" break; case 141: -#line 925 "parse.y" +#line 933 "parse.y" { yyval.start = yystack.l_mark[-1].start ; code1(_EXIT) ; } -#line 3698 "parse.c" +#line 3706 "parse.c" break; case 142: -#line 929 "parse.y" +#line 937 "parse.y" { yyval.start = code_offset ; code1(_RET0) ; } -#line 3704 "parse.c" +#line 3712 "parse.c" break; case 143: -#line 932 "parse.y" +#line 940 "parse.y" { yyval.start = yystack.l_mark[-1].start ; code1(_RET) ; } -#line 3709 "parse.c" +#line 3717 "parse.c" break; case 144: -#line 938 "parse.y" +#line 946 "parse.y" { yyval.start = code_offset ; code2(F_PUSHA, &field[0]) ; code1(_PUSHINT) ; code1(0) ; func2(_BUILTIN, bi_getline) ; getline_flag = 0 ; } -#line 3719 "parse.c" +#line 3727 "parse.c" break; case 145: -#line 945 "parse.y" +#line 953 "parse.y" { yyval.start = yystack.l_mark[0].start ; code1(_PUSHINT) ; code1(0) ; func2(_BUILTIN, bi_getline) ; getline_flag = 0 ; } -#line 3728 "parse.c" +#line 3736 "parse.c" break; case 146: -#line 951 "parse.y" +#line 959 "parse.y" { code1(_PUSHINT) ; code1(F_IN) ; func2(_BUILTIN, bi_getline) ; /* getline_flag already off in yylex() */ } -#line 3736 "parse.c" -break; -case 147: -#line 956 "parse.y" - { code2(F_PUSHA, &field[0]) ; - code1(_PUSHINT) ; code1(PIPE_IN) ; - func2(_BUILTIN, bi_getline) ; - } #line 3744 "parse.c" break; -case 148: -#line 961 "parse.y" - { +case 147: +#line 964 "parse.y" + { code2(F_PUSHA, &field[0]) ; code1(_PUSHINT) ; code1(PIPE_IN) ; func2(_BUILTIN, bi_getline) ; } #line 3752 "parse.c" break; +case 148: +#line 969 "parse.y" + { + code1(_PUSHINT) ; code1(PIPE_IN) ; + func2(_BUILTIN, bi_getline) ; + } +#line 3760 "parse.c" +break; case 149: -#line 967 "parse.y" +#line 975 "parse.y" { getline_flag = 1 ; } -#line 3757 "parse.c" +#line 3765 "parse.c" break; case 152: -#line 972 "parse.y" +#line 980 "parse.y" { yyval.start = code_offset ; code2(F_PUSHA, field+0) ; } -#line 3764 "parse.c" +#line 3772 "parse.c" break; case 153: -#line 976 "parse.y" +#line 984 "parse.y" { yyval.start = yystack.l_mark[-1].start ; } -#line 3769 "parse.c" +#line 3777 "parse.c" break; case 154: -#line 984 "parse.y" +#line 992 "parse.y" { INST *p5 = CDP(yystack.l_mark[-1].start) ; INST *p6 = CDP(yystack.l_mark[0].start) ; @@ -3786,41 +3794,41 @@ case 154: func2(_BUILTIN, yystack.l_mark[-5].fp) ; yyval.start = yystack.l_mark[-3].start ; } -#line 3790 "parse.c" +#line 3798 "parse.c" break; case 155: -#line 1003 "parse.y" +#line 1011 "parse.y" { yyval.fp = bi_sub ; } -#line 3795 "parse.c" +#line 3803 "parse.c" break; case 156: -#line 1004 "parse.y" +#line 1012 "parse.y" { yyval.fp = bi_gsub ; } -#line 3800 "parse.c" +#line 3808 "parse.c" break; case 157: -#line 1009 "parse.y" +#line 1017 "parse.y" { yyval.start = code_offset ; code2(F_PUSHA, &field[0]) ; } -#line 3807 "parse.c" +#line 3815 "parse.c" break; case 158: -#line 1014 "parse.y" +#line 1022 "parse.y" { yyval.start = yystack.l_mark[-1].start ; } -#line 3812 "parse.c" +#line 3820 "parse.c" break; case 159: -#line 1022 "parse.y" +#line 1030 "parse.y" { resize_fblock(yystack.l_mark[-1].fbp) ; restore_ids() ; switch_code_to_main() ; } -#line 3821 "parse.c" +#line 3829 "parse.c" break; case 160: -#line 1031 "parse.y" +#line 1039 "parse.y" { eat_nl() ; scope = SCOPE_FUNCT ; active_funct = yystack.l_mark[-3].fbp ; @@ -3839,10 +3847,10 @@ case 160: improve_arglist(yystack.l_mark[-3].fbp->name); free_arglist(); } -#line 3843 "parse.c" +#line 3851 "parse.c" break; case 161: -#line 1052 "parse.y" +#line 1060 "parse.y" { FBLOCK *fbp ; if ( yystack.l_mark[0].stp == NULL ) @@ -3868,32 +3876,32 @@ case 161: } yyval.fbp = fbp ; } -#line 3872 "parse.c" +#line 3880 "parse.c" break; case 162: -#line 1079 "parse.y" +#line 1087 "parse.y" { yyval.fbp = yystack.l_mark[0].fbp ; if ( yystack.l_mark[0].fbp->code ) compile_error("redefinition of %s" , yystack.l_mark[0].fbp->name) ; } -#line 3880 "parse.c" +#line 3888 "parse.c" break; case 163: -#line 1085 "parse.y" +#line 1093 "parse.y" { yyval.ival = init_arglist() ; } -#line 3885 "parse.c" +#line 3893 "parse.c" break; case 165: -#line 1090 "parse.y" +#line 1098 "parse.y" { init_arglist(); yystack.l_mark[0].stp = save_arglist(yystack.l_mark[0].stp->name) ; yystack.l_mark[0].stp->offset = 0 ; yyval.ival = 1 ; } -#line 3894 "parse.c" +#line 3902 "parse.c" break; case 166: -#line 1096 "parse.y" +#line 1104 "parse.y" { if ( is_local(yystack.l_mark[0].stp) ) compile_error("%s is duplicated in argument list", yystack.l_mark[0].stp->name) ; @@ -3903,10 +3911,10 @@ case 166: yyval.ival = yystack.l_mark[-2].ival + 1 ; } } -#line 3907 "parse.c" +#line 3915 "parse.c" break; case 167: -#line 1108 "parse.y" +#line 1116 "parse.y" { /* we may have to recover from a bungled function definition */ /* can have local ids, before code scope @@ -3915,10 +3923,10 @@ case 167: switch_code_to_main() ; } -#line 3919 "parse.c" +#line 3927 "parse.c" break; case 168: -#line 1121 "parse.y" +#line 1129 "parse.y" { yyval.start = yystack.l_mark[-1].start ; code2(_CALL, yystack.l_mark[-2].fbp) ; @@ -3927,29 +3935,29 @@ case 168: check_fcall(yystack.l_mark[-2].fbp, scope, code_move_level, active_funct, yystack.l_mark[0].ca_p) ; } -#line 3931 "parse.c" +#line 3939 "parse.c" break; case 169: -#line 1132 "parse.y" +#line 1140 "parse.y" { yyval.ca_p = (CA_REC *) 0 ; } -#line 3936 "parse.c" +#line 3944 "parse.c" break; case 170: -#line 1134 "parse.y" +#line 1142 "parse.y" { yyval.ca_p = yystack.l_mark[0].ca_p ; yyval.ca_p->link = yystack.l_mark[-1].ca_p ; yyval.ca_p->arg_num = (NUM_ARGS) (yystack.l_mark[-1].ca_p ? yystack.l_mark[-1].ca_p->arg_num+1 : 0) ; yyval.ca_p->call_lineno = token_lineno; } -#line 3945 "parse.c" +#line 3953 "parse.c" break; case 171: -#line 1150 "parse.y" +#line 1158 "parse.y" { yyval.ca_p = (CA_REC *) 0 ; } -#line 3950 "parse.c" +#line 3958 "parse.c" break; case 172: -#line 1152 "parse.y" +#line 1160 "parse.y" { yyval.ca_p = ZMALLOC(CA_REC) ; yyval.ca_p->link = yystack.l_mark[-2].ca_p ; yyval.ca_p->type = CA_EXPR ; @@ -3957,10 +3965,10 @@ case 172: yyval.ca_p->call_offset = code_offset ; yyval.ca_p->call_lineno = token_lineno; } -#line 3961 "parse.c" +#line 3969 "parse.c" break; case 173: -#line 1160 "parse.y" +#line 1168 "parse.y" { yyval.ca_p = ZMALLOC(CA_REC) ; yyval.ca_p->type = ST_NONE ; yyval.ca_p->link = yystack.l_mark[-2].ca_p ; @@ -3969,25 +3977,25 @@ case 173: code_call_id(yyval.ca_p, yystack.l_mark[-1].stp) ; } -#line 3973 "parse.c" +#line 3981 "parse.c" break; case 174: -#line 1171 "parse.y" +#line 1179 "parse.y" { yyval.ca_p = ZMALLOC(CA_REC) ; yyval.ca_p->type = CA_EXPR ; yyval.ca_p->call_offset = code_offset ; } -#line 3981 "parse.c" +#line 3989 "parse.c" break; case 175: -#line 1177 "parse.y" +#line 1185 "parse.y" { yyval.ca_p = ZMALLOC(CA_REC) ; yyval.ca_p->type = ST_NONE ; code_call_id(yyval.ca_p, yystack.l_mark[-1].stp) ; } -#line 3989 "parse.c" +#line 3997 "parse.c" break; -#line 3991 "parse.c" +#line 3999 "parse.c" default: break; } diff --git a/parse.y b/parse.y index 7954a6d..8ddbf06 100644 --- a/parse.y +++ b/parse.y @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: parse.y,v 1.39 2024/08/25 19:49:34 tom Exp $ + * $MawkId: parse.y,v 1.41 2024/08/26 21:04:00 tom Exp $ */ %{ @@ -431,10 +431,14 @@ builtin : BUILTIN mark LPAREN arglist RPAREN { const BI_REC *p = $1 ; $$ = $2 ; - if ( (int)p->min_args > $4 || (int)p->max_args < $4 ) - compile_error( - "wrong number of arguments in call to %s" , - p->name ) ; + if ( (int)p->min_args > $4 ) + compile_error( + "not enough arguments in call to %s: %d (need %d)" , + p->name, $4, (int)p->min_args ) ; + if ( (int)p->max_args < $4 ) + compile_error( + "too many arguments in call to %s: %d (maximum %d)" , + p->name, $4, (int)p->max_args ) ; if ( p->min_args != p->max_args ) /* variable args */ { code1(_PUSHINT) ; code1($4) ; } func2(_BUILTIN , p->fp) ; @@ -449,8 +453,12 @@ mark : /* empty */ /* print_statement */ statement : print mark pr_args pr_direction separator { func2(_PRINT, $1) ; + if ( $3 > MAX_ARGS ) + compile_error("too many arguments in call to %s: %d (maximum %d)", + ( $1 == bi_printf ) ? "printf" : "print", + $3, MAX_ARGS) ; if ( $1 == bi_printf && $3 == 0 ) - compile_error("no arguments in call to printf") ; + compile_error("no arguments in call to printf") ; print_flag = 0 ; $$ = $2 ; } @@ -878,7 +886,7 @@ p_expr : LENGTH LPAREN RPAREN } } ; -p_expr : LENGTH %prec CAT /* fixes s/r conflict length vs length() */ +p_expr : LENGTH %prec CAT /* fixes s/r conflict length vs length() */ { $$ = code_offset ; code2(_PUSHI,field) ; func2(_BUILTIN,bi_length) ; diff --git a/patchlev.h b/patchlev.h index 2b9f72f..2db60b9 100644 --- a/patchlev.h +++ b/patchlev.h @@ -11,9 +11,9 @@ the GNU General Public License, version 2, 1991. */ /* - * $MawkId: patchlev.h,v 1.151 2024/08/25 22:51:21 tom Exp $ + * $MawkId: patchlev.h,v 1.153 2024/08/27 07:48:11 tom Exp $ */ #define PATCH_BASE 1 #define PATCH_LEVEL 3 #define PATCH_STRING ".4" -#define DATE_STRING "20240825" +#define DATE_STRING "20240827" diff --git a/rexp3.c b/rexp3.c index 8218a32..298b87c 100644 --- a/rexp3.c +++ b/rexp3.c @@ -12,7 +12,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: rexp3.c,v 1.63 2024/08/25 17:16:24 tom Exp $ + * $MawkId: rexp3.c,v 1.65 2024/08/27 20:48:02 tom Exp $ */ /* match a string against a machine */ @@ -259,10 +259,8 @@ REmatch(char *str, /* string to test */ m++; RE_CASE(); -#ifndef LCOV_UNUSED case M_CLASS + U_OFF + END_ON: - /* NOTREACHED */ - if (s >= str_end || !ison(*m->s_data.bvp, s[0])) { + if (s >= str_end || s[1] || !ison(*m->s_data.bvp, s[0])) { RE_FILL(); } else if (!ss) { if (cb_ss && current_best(s)) { @@ -274,7 +272,6 @@ REmatch(char *str, /* string to test */ s = str_end; m++; RE_CASE(); -#endif case M_CLASS + U_ON + END_OFF: if (s < str) diff --git a/symtype.h b/symtype.h index eebbc85..99cd455 100644 --- a/symtype.h +++ b/symtype.h @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: symtype.h,v 1.28 2024/08/25 17:21:52 tom Exp $ + * $MawkId: symtype.h,v 1.29 2024/08/26 08:08:39 tom Exp $ */ /* types related to symbols are defined here */ @@ -21,6 +21,7 @@ the GNU General Public License, version 2, 1991. #include +#define MAX_ARGS 255 typedef unsigned char NUM_ARGS; typedef unsigned char SYM_TYPE; diff --git a/test/mawkerrs b/test/mawkerrs index 045cec2..be77b15 100755 --- a/test/mawkerrs +++ b/test/mawkerrs @@ -1,5 +1,5 @@ #!/bin/sh -# $MawkId: mawkerrs,v 1.12 2024/08/19 20:49:13 tom Exp $ +# $MawkId: mawkerrs,v 1.18 2024/08/27 07:50:27 tom Exp $ ############################################################################### # copyright 2024, Thomas E. Dickey # @@ -205,12 +205,57 @@ echo 'mawk: line 2: missing } near end of file' >$STDERR $PROG -Wd 'BEGIN{ printf "?\n"' 2>&1 | cmp -s - "$STDERR" || Fail "missing right brace" Finish "test for missing right-brace" +Begin "test for enough arguments of index()" +echo 'mawk: line 1: not enough arguments in call to index: 1 (need 2)' >$STDERR +$PROG -Wd 'BEGIN{ foo = index("?"); }' 2>&1 | cmp -s - "$STDERR" || Fail "enough arguments for index()" +Finish "test for enough arguments of index()" + +Begin "test for too many arguments of index()" +echo 'mawk: line 1: too many arguments in call to index: 4 (maximum 2)' >$STDERR +$PROG -Wd 'BEGIN{ foo = index("?",1,2,3); }' 2>&1 | cmp -s - "$STDERR" || Fail "too many arguments for index()" +Finish "test for too many arguments of index()" + +Begin "test for too many arguments of print()" +echo 'mawk: line 1: too many arguments in call to print: 256 (maximum 255)' >$STDERR +$PROG -Wd 'BEGIN{ print 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; }' 2>&1 | cmp -s - "$STDERR" || Fail "too many arguments for print()" +Finish "test for too many arguments of print()" + +Begin "test for return outside function" +echo 'mawk: line 1: return outside function body' >$STDERR +$PROG -Wd 'BEGIN{ return ; }' 2>&1 | cmp -s - "$STDERR" || Fail "return outside function" +Finish "test for return outside function" + +Begin "test for improper use of next" +echo 'mawk: line 1: improper use of next' >$STDERR +$PROG -Wd 'function foo() { next; }BEGIN{ }' 2>&1 | cmp -s - "$STDERR" || Fail "improper use of next" +Finish "test for improper use of next" + +Begin "test for improper use of nextfile" +echo 'mawk: line 1: improper use of nextfile' >$STDERR +$PROG -Wd 'function foo() { nextfile; }BEGIN{ }' 2>&1 | cmp -s - "$STDERR" || Fail "improper use of nextfile" +Finish "test for improper use of nextfile" + +Begin "test for redefinition of function" +echo 'mawk: line 1: redefinition of foo' >$STDERR +$PROG -Wd 'function foo() { print; }function foo(){ printf "?"; }BEGIN{ }' 2>&1 | cmp -s - "$STDERR" || Fail "redefinition of function" +Finish "test for redefinition of function" + +Begin "test for illegal reference to variable" +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 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" + ######## print.c Begin "test sprintf buffer-overflow" echo 'mawk: program limit exceeded: sprintf buffer size=8192' >$STDERR echo ' FILENAME="" FNR=0 NR=0' >>$STDERR -$PROG 'BEGIN{ foo = sprintf("%10000s\n", "x"); print length(foo); }' 2>&1 | cmp -s - "$STDERR" || Fail "missing right brace" +$PROG 'BEGIN{ foo = sprintf("%10000s\n", "x"); print length(foo); }' 2>&1 | cmp -s - "$STDERR" || Fail "sprintf buffer-overflow" Finish "test sprintf buffer-overflow" ######## scan.c