[comp.lang.perl] Bug report on 3.44

worley@compass.com (Dale Worley) (03/28/91)

The following program causes Perl 3.44 on a Sun 3 (SunOS 4.0.1) to dump core:

    @makefiles = ("/bin/cc");

    grep(do {
		$modtime = (stat)[9];
	 }, @makefiles);

The internal representation of the program is:

{
    C_TYPE = EXPR
    C_ADDR = 0x2a001c
    C_NEXT = 0x2a029c
    C_LINE = 3 (0x2a001c)
    C_OPT = CFT_EVAL
    C_FLAGS = (COND)
    C_EXPR = {
        OP_TYPE = ASSIGN
        OP_LEN = 2
        [1]ARG_TYPE = LEXPR
        [1]ARG_FLAGS = (ARYOK)
        [1]ARG_ARG = {
            OP_TYPE = LARRAY
            OP_LEN = 1
            [1]ARG_TYPE = STAB (unevaluated)
            [1]ARG_STAB = {
                STAB_NAME = main'makefiles
            }
        }
        [2]ARG_TYPE = EXPR
        [2]ARG_FLAGS = (ARYOK)
        [2]ARG_ARG = {
            OP_TYPE = ITEM
            OP_LEN = 1
            [1]ARG_TYPE = SINGLE
            [1]ARG_STR = '/bin/cc'
        }
    }
    AC_STAB = NULL
    AC_EXPR = NULL
}
{
    C_TYPE = EXPR
    C_ADDR = 0x2a029c
    C_NEXT = 0x0
    C_LINE = 7 (0x2a029c)
    C_OPT = CFT_EVAL
    C_FLAGS = (COND,TERM)
    C_EXPR = {
        OP_TYPE = GREP
        OP_LEN = 2
        [1]ARG_TYPE = CMD (unevaluated)
        [1]ARG_CMD = {
            C_TYPE = EXPR
            C_ADDR = 0x2a021c
            C_NEXT = 0x0
            C_LINE = 6 (0x2a021c)
            C_OPT = CFT_EVAL
            C_FLAGS = (COND,TERM)
            C_EXPR = {
                OP_TYPE = ASSIGN
                OP_LEN = 2
                OP_FLAGS = (COMMON)
                [1]ARG_TYPE = LVAL
                [1]ARG_STAB = {
                    STAB_NAME = main'modtime
                }
                [2]ARG_TYPE = EXPR
                [2]ARG_ARG = {
                    OP_TYPE = LSLICE
                    OP_LEN = 3
                    [1]ARG_TYPE = A_NULL (unevaluated)
                    [2]ARG_TYPE = EXPR
                    [2]ARG_FLAGS = (ARYOK)
                    [2]ARG_ARG = {
                        OP_TYPE = LIST
                        OP_LEN = 1
                        [1]ARG_TYPE = SINGLE
                        [1]ARG_FLAGS = (ARYOK)
                        [1]ARG_STR = 'num(9)'
                    }
                    [3]ARG_TYPE = EXPR
                    [3]ARG_FLAGS = (ARYOK)
                    [3]ARG_ARG = {
                        OP_TYPE = LIST
                        OP_LEN = 1
                        [1]ARG_TYPE = EXPR
                        [1]ARG_FLAGS = (ARYOK)
                        [1]ARG_ARG = {
                            OP_TYPE = STAT
                            OP_LEN = 0
                            OP_FLAGS = (LISTISH)
                        }
                    }
                }
            }
            AC_STAB = NULL
            AC_EXPR = NULL
        }
        [2]ARG_TYPE = EXPR
        [2]ARG_FLAGS = (ARYOK)
        [2]ARG_ARG = {
            OP_TYPE = ARRAY
            OP_LEN = 1
            [1]ARG_TYPE = STAB (unevaluated)
            [1]ARG_STAB = {
                STAB_NAME = main'makefiles
            }
        }
    }
    AC_STAB = NULL
    AC_EXPR = NULL
}

The stack dump at the time of the error is:

do_stat(str = (struct string *) 0x28e4d0, arg = (struct arg *) 0x125204, gimme = (int) 1, arglast = (int *) 0xf4108) at "doio.c":689
eval(arg = (struct arg *) 0x125204, gimme = (int) 1, sp = (int) 4) at "eval.c":1259
eval(arg = (struct arg *) 0x28e450, gimme = (int) 1, sp = (int) 4) at "evalargs.xc":62
eval(arg = (struct arg *) 0x2a011c, gimme = (int) 0, sp = (int) 4) at "evalargs.xc":62
eval(arg = (struct arg *) 0x28e690, gimme = (int) 0, sp = (int) 2) at "evalargs.xc":62
cmd_exec(cmdparm = (struct cmd *) 0x2a021c, gimme = (int) 0, sp = (int)1) at "cmd.c":645
eval(arg = (struct arg *) 0x28f050, gimme = (int) 0, sp = (int) 1) at "evalargs.xc":75
do_grep(arg = (struct arg *) 0x28f050, str = (struct string *) 0x28e710, gimme = (int) 0, arglast = (int *) 0xf3b08) at "dolist.c":1353
eval(arg = (struct arg *) 0x28e350, gimme = (int) 0, sp = (int) 1) at "eval.c":807
cmd_exec(cmdparm = (struct cmd *) 0x2a001c, gimme = (int) 0, sp = (int)-1) at "cmd.c":645
main(argc = (int) 0, argv = (char **) 0x28d59c, env = (char **) 0x102fe4) at "perly.c":796

The code it is attempting to execute is:

    int
    do_stat(str,arg,gimme,arglast)
    STR *str;
    register ARG *arg;
    int gimme;
    int *arglast;
    {
	register ARRAY *ary = stack;
	register int sp = arglast[0] + 1;
	int max = 13;

->	if ((arg[1].arg_type & A_MASK) == A_WORD) {
	    tmpstab = arg[1].arg_ptr.arg_stab;

Saber-C reports that 'arg' is allocated with only 1 element, so the
reference to 'arg[1]' is invalid.