X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl.c;h=98437a3e9dfcbbbcdc9a76640bcefa098de7a182;hb=969386165da4b2b619c453c25dead6d8a086a3cb;hp=158526ab29bfefd97a8a3fbcf6f4925f6feb9ee3;hpb=f0d36289ce76f882218c0a53cd52f716a167e5bb;p=p5sagit%2Fp5-mst-13.2.git diff --git a/perl.c b/perl.c index 158526a..98437a3 100644 --- a/perl.c +++ b/perl.c @@ -125,16 +125,22 @@ char *getenv (char *); /* Usually in */ static I32 read_e_script(pTHX_ int idx, SV *buf_sv, int maxlen); -#ifdef IAMSUID -#ifndef DOSUID -#define DOSUID -#endif -#endif /* IAMSUID */ - -#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW #ifdef DOSUID -#undef DOSUID -#endif +# ifdef IAMSUID +/* Drop scriptname */ +# define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ validarg, fdscript, suidscript, linestr_sv, rsfp) +# else +/* Drop suidscript */ +# define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ validarg, scriptname, fdscript, linestr_sv, rsfp) +# endif +#else +# ifdef SETUID_SCRIPTS_ARE_SECURE_NOW +/* Drop everything. Heck, don't even try to call it */ +# define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) NOOP +# else +/* Drop almost everything */ +# define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ rsfp) +# endif #endif #define CALL_BODY_EVAL(myop) \ @@ -187,6 +193,10 @@ S_init_tls_and_interp(PerlInterpreter *my_perl) void Perl_sys_init(int* argc, char*** argv) { + dVAR; + + PERL_ARGS_ASSERT_SYS_INIT; + PERL_UNUSED_ARG(argc); /* may not be used depending on _BODY macro */ PERL_UNUSED_ARG(argv); PERL_SYS_INIT_BODY(argc, argv); @@ -195,6 +205,10 @@ Perl_sys_init(int* argc, char*** argv) void Perl_sys_init3(int* argc, char*** argv, char*** env) { + dVAR; + + PERL_ARGS_ASSERT_SYS_INIT3; + PERL_UNUSED_ARG(argc); /* may not be used depending on _BODY macro */ PERL_UNUSED_ARG(argv); PERL_UNUSED_ARG(env); @@ -202,8 +216,9 @@ Perl_sys_init3(int* argc, char*** argv, char*** env) } void -Perl_sys_term(pTHX) +Perl_sys_term() { + dVAR; if (!PL_veto_cleanup) { PERL_SYS_TERM_BODY(); } @@ -219,6 +234,9 @@ perl_alloc_using(struct IPerlMem* ipM, struct IPerlMem* ipMS, struct IPerlProc* ipP) { PerlInterpreter *my_perl; + + PERL_ARGS_ASSERT_PERL_ALLOC_USING; + /* Newx() needs interpreter, so call malloc() instead */ my_perl = (PerlInterpreter*)(*ipM->pMalloc)(ipM, sizeof(PerlInterpreter)); S_init_tls_and_interp(my_perl); @@ -279,11 +297,14 @@ void perl_construct(pTHXx) { dVAR; - PERL_UNUSED_ARG(my_perl); + + PERL_ARGS_ASSERT_PERL_CONSTRUCT; + #ifdef MULTIPLICITY init_interp(); PL_perl_destruct_level = 1; #else + PERL_UNUSED_ARG(my_perl); if (PL_perl_destruct_level > 0) init_interp(); #endif @@ -297,15 +318,19 @@ perl_construct(pTHXx) sv_setpv(&PL_sv_no,PL_No); /* value lookup in void context - happens to have the side effect - of caching the numeric forms. */ - SvIV(&PL_sv_no); + of caching the numeric forms. However, as &PL_sv_no doesn't contain + a string that is a valid numer, we have to turn the public flags by + hand: */ SvNV(&PL_sv_no); + SvIV(&PL_sv_no); + SvIOK_on(&PL_sv_no); + SvNOK_on(&PL_sv_no); SvREADONLY_on(&PL_sv_no); SvREFCNT(&PL_sv_no) = (~(U32)0)/2; sv_setpv(&PL_sv_yes,PL_Yes); - SvIV(&PL_sv_yes); SvNV(&PL_sv_yes); + SvIV(&PL_sv_yes); SvREADONLY_on(&PL_sv_yes); SvREFCNT(&PL_sv_yes) = (~(U32)0)/2; @@ -346,8 +371,9 @@ perl_construct(pTHXx) sv_setpvn(PERL_DEBUG_PAD(1), "", 0); /* ext/re needs these */ sv_setpvn(PERL_DEBUG_PAD(2), "", 0); /* even without DEBUGGING. */ #ifdef USE_ITHREADS - /* First entry is an array of empty elements */ - Perl_av_create_and_push(aTHX_ &PL_regex_padav,(SV*)newAV()); + /* First entry is a list of empty elements. It needs to be initialised + else all hell breaks loose in S_find_uninit_var(). */ + Perl_av_create_and_push(aTHX_ &PL_regex_padav, newSVpvs("")); PL_regex_pad = AvARRAY(PL_regex_padav); #endif #ifdef USE_REENTRANT_API @@ -464,6 +490,8 @@ Perl_dump_sv_child(pTHX_ SV *sv) int returned_errno; unsigned char buffer[256]; + PERL_ARGS_ASSERT_DUMP_SV_CHILD; + if(sock == -1 || debug_fd == -1) return; @@ -560,13 +588,16 @@ int perl_destruct(pTHXx) { dVAR; - VOL int destruct_level; /* 0=none, 1=full, 2=full with checks */ + VOL signed char destruct_level; /* see possible values in intrpvar.h */ HV *hv; #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP pid_t child; #endif + PERL_ARGS_ASSERT_PERL_DESTRUCT; +#ifndef MULTIPLICITY PERL_UNUSED_ARG(my_perl); +#endif /* wait for all pseudo-forked children to finish */ PERL_WAIT_FOR_CHILDREN; @@ -865,28 +896,6 @@ perl_destruct(pTHXx) * REGEXPs in the parent interpreter * we need to manually ReREFCNT_dec for the clones */ - { - I32 i = AvFILLp(PL_regex_padav) + 1; - SV * const * const ary = AvARRAY(PL_regex_padav); - - while (i) { - SV * const resv = ary[--i]; - - if (SvFLAGS(resv) & SVf_BREAK) { - /* this is PL_reg_curpm, already freed - * flag is set in regexec.c:S_regtry - */ - SvFLAGS(resv) &= ~SVf_BREAK; - } - else if(SvREPADTMP(resv)) { - SvREPADTMP_off(resv); - } - else if(SvIOKp(resv)) { - REGEXP *re = INT2PTR(REGEXP *,SvIVX(resv)); - ReREFCNT_dec(re); - } - } - } SvREFCNT_dec(PL_regex_padav); PL_regex_padav = NULL; PL_regex_pad = NULL; @@ -909,7 +918,6 @@ perl_destruct(pTHXx) } /* switches */ - PL_preprocess = FALSE; PL_minus_n = FALSE; PL_minus_p = FALSE; PL_minus_l = FALSE; @@ -1119,18 +1127,11 @@ perl_destruct(pTHXx) } /* Now absolutely destruct everything, somehow or other, loops or no. */ - SvFLAGS(PL_fdpid) |= SVTYPEMASK; /* don't clean out pid table now */ - SvFLAGS(PL_strtab) |= SVTYPEMASK; /* don't clean out strtab now */ /* the 2 is for PL_fdpid and PL_strtab */ - while (PL_sv_count > 2 && sv_clean_all()) + while (sv_clean_all() > 2) ; - SvFLAGS(PL_fdpid) &= ~SVTYPEMASK; - SvFLAGS(PL_fdpid) |= SVt_PVAV; - SvFLAGS(PL_strtab) &= ~SVTYPEMASK; - SvFLAGS(PL_strtab) |= SVt_PVHV; - AvREAL_off(PL_fdpid); /* no surviving entries */ SvREFCNT_dec(PL_fdpid); /* needed in io_close() */ PL_fdpid = NULL; @@ -1220,7 +1221,8 @@ perl_destruct(pTHXx) " flags=0x%"UVxf " refcnt=%"UVuf pTHX__FORMAT "\n" "\tallocated at %s:%d %s %s%s\n", - (void*)sv, sv->sv_flags, sv->sv_refcnt pTHX__VALUE, + (void*)sv, (UV)sv->sv_flags, (UV)sv->sv_refcnt + pTHX__VALUE, sv->sv_debug_file ? sv->sv_debug_file : "(unknown)", sv->sv_debug_line, sv->sv_debug_inpad ? "for" : "by", @@ -1254,6 +1256,10 @@ perl_destruct(pTHXx) } #endif #endif +#ifdef DEBUG_LEAKING_SCALARS_ABORT + if (PL_sv_count) + abort(); +#endif PL_sv_count = 0; #ifdef PERL_DEBUG_READONLY_OPS @@ -1350,6 +1356,8 @@ perl_free(pTHXx) { dVAR; + PERL_ARGS_ASSERT_PERL_FREE; + if (PL_veto_cleanup) return; @@ -1361,10 +1369,17 @@ perl_free(pTHXx) */ const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL"); if (!s || atoi(s) == 0) { + const U32 old_debug = PL_debug; /* Emulate the PerlHost behaviour of free()ing all memory allocated in this thread at thread exit. */ + if (DEBUG_m_TEST) { + PerlIO_puts(Perl_debug_log, "Disabling memory debugging as we " + "free this thread's memory\n"); + PL_debug &= ~ DEBUG_m_FLAG; + } while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header)) safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next)); + PL_debug = old_debug; } } #endif @@ -1494,14 +1509,14 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env) int ret; dJMPENV; + PERL_ARGS_ASSERT_PERL_PARSE; +#ifndef MULTIPLICITY PERL_UNUSED_ARG(my_perl); +#endif -#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW -#ifdef IAMSUID -#undef IAMSUID - Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now execute\n\ -setuid perl scripts securely.\n"); -#endif /* IAMSUID */ +#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW_AND_IAMSUID + Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now " + "execute\nsetuid perl scripts securely.\n"); #endif #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) @@ -1684,9 +1699,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) char **argv = PL_origargv; const char *scriptname = NULL; VOL bool dosearch = FALSE; +#ifdef DOSUID const char *validarg = ""; +#endif register SV *sv; - register char *s, c; + register char c; const char *cddir = NULL; #ifdef USE_SITECUSTOMIZE bool minus_f = FALSE; @@ -1701,6 +1718,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) SAVEFREESV(sv); init_main_stash(); + { + const char *s; for (argc--,argv++; argc > 0; argc--,argv++) { if (argv[0][0] != '-' || !argv[0][1]) break; @@ -1772,7 +1791,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) if (argv[1] && !strcmp(argv[1], "Dev:Pseudo")) break; #endif - forbid_setid('e', -1); + forbid_setid('e', FALSE); if (!PL_e_script) { PL_e_script = newSVpvs(""); add_read_e_script = TRUE; @@ -1796,7 +1815,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) goto reswitch; case 'I': /* -I handled both here and in moreswitches() */ - forbid_setid('I', -1); + forbid_setid('I', FALSE); if (!*++s && (s=argv[1]) != NULL) { argc--,argv++; } @@ -1812,14 +1831,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) else Perl_croak(aTHX_ "No directory specified for -I"); break; - case 'P': - forbid_setid('P', -1); - PL_preprocess = TRUE; - s++; - deprecate("-P"); - goto reswitch; case 'S': - forbid_setid('S', -1); + forbid_setid('S', FALSE); dosearch = TRUE; s++; goto reswitch; @@ -1894,12 +1907,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) "\" Built under %s\\n",OSNAME); #ifdef __DATE__ # ifdef __TIME__ - Perl_sv_catpvf(aTHX_ opts_prog, - " Compiled at %s %s\\n\"",__DATE__, - __TIME__); + sv_catpvs(opts_prog, + " Compiled at " __DATE__ " " __TIME__ "\\n\""); # else - Perl_sv_catpvf(aTHX_ opts_prog," Compiled on %s\\n\"", - __DATE__); + sv_catpvs(opts_prog, " Compiled on " __DATE__ "\\n\""); # endif #endif sv_catpvs(opts_prog, "; $\"=\"\\n \"; " @@ -1953,15 +1964,19 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) Perl_croak(aTHX_ "Unrecognized switch: -%s (-h will show valid options)",s); } } + } + switch_end: + { + char *s; + if ( #ifndef SECURE_INTERNAL_GETENV !PL_tainting && #endif (s = PerlEnv_getenv("PERL5OPT"))) { - const char *popt = s; while (isSPACE(*s)) s++; if (*s == '-' && *(s+1) == 'T') { @@ -1972,7 +1987,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) else { char *popt_copy = NULL; while (s && *s) { - char *d; + const char *d; while (isSPACE(*s)) s++; if (*s == '-') { @@ -1988,9 +2003,9 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) while (++s && *s) { if (isSPACE(*s)) { if (!popt_copy) { - popt_copy = SvPVX(sv_2mortal(newSVpv(popt,0))); - s = popt_copy + (s - popt); - d = popt_copy + (d - popt); + popt_copy = SvPVX(sv_2mortal(newSVpv(d,0))); + s = popt_copy + (s - d); + d = popt_copy; } *s++ = '\0'; break; @@ -2007,6 +2022,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) } } } + } #ifdef USE_SITECUSTOMIZE if (!minus_f) { @@ -2037,9 +2053,12 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) init_perllib(); { - int suidscript; - const int fdscript - = open_script(scriptname, dosearch, sv, &suidscript, &rsfp); + bool suidscript = FALSE; + +#ifdef DOSUID + const int fdscript = +#endif + open_script(scriptname, dosearch, &suidscript, &rsfp); validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp); @@ -2067,10 +2086,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) #endif ) { - /* This will croak if suidscript is >= 0, as -x cannot be used with + /* This will croak if suidscript is true, as -x cannot be used with setuid scripts. */ forbid_setid('x', suidscript); - /* Hence you can't get here if suidscript >= 0 */ + /* Hence you can't get here if suidscript is true */ find_beginning(linestr_sv, rsfp); if (cddir && PerlDir_chdir( (char *)cddir ) < 0) @@ -2159,6 +2178,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) } } + { + const char *s; if ((s = PerlEnv_getenv("PERL_SIGNALS"))) { if (strEQ(s, "unsafe")) PL_signals |= PERL_SIGNALS_UNSAFE_FLAG; @@ -2167,8 +2188,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) else Perl_croak(aTHX_ "PERL_SIGNALS illegal: \"%s\"", s); } + } #ifdef PERL_MAD + { + const char *s; if ((s = PerlEnv_getenv("PERL_XMLDUMP"))) { PL_madskills = 1; PL_minus_c = 1; @@ -2181,10 +2205,15 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) } my_setenv("PERL_XMLDUMP", NULL); /* hide from subprocs */ } + } + + { + const char *s; if ((s = PerlEnv_getenv("PERL_MADSKILLS"))) { PL_madskills = atoi(s); my_setenv("PERL_MADSKILLS", NULL); /* hide from subprocs */ } + } #endif lex_start(linestr_sv, rsfp, TRUE); @@ -2217,7 +2246,6 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) #endif CopLINE_set(PL_curcop, 0); PL_curstash = PL_defstash; - PL_preprocess = FALSE; if (PL_e_script) { SvREFCNT_dec(PL_e_script); PL_e_script = NULL; @@ -2236,8 +2264,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) FREETMPS; #ifdef MYMALLOC + { + const char *s; if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2) dump_mstats("after compilation:"); + } #endif ENTER; @@ -2261,7 +2292,10 @@ perl_run(pTHXx) int ret = 0; dJMPENV; + PERL_ARGS_ASSERT_PERL_RUN; +#ifndef MULTIPLICITY PERL_UNUSED_ARG(my_perl); +#endif oldscope = PL_scopestack_ix; #ifdef VMS @@ -2325,8 +2359,6 @@ S_run_body(pTHX_ I32 oldscope) if (!DEBUG_q_TEST) PERL_DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n")); #endif - DEBUG_S(PerlIO_printf(Perl_debug_log, "main thread is 0x%"UVxf"\n", - PTR2UV(thr))); if (PL_minus_c) { #ifdef MACOS_TRADITIONAL @@ -2379,6 +2411,9 @@ SV* Perl_get_sv(pTHX_ const char *name, I32 create) { GV *gv; + + PERL_ARGS_ASSERT_GET_SV; + gv = gv_fetchpv(name, create, SVt_PV); if (gv) return GvSV(gv); @@ -2401,6 +2436,9 @@ AV* Perl_get_av(pTHX_ const char *name, I32 create) { GV* const gv = gv_fetchpv(name, create, SVt_PVAV); + + PERL_ARGS_ASSERT_GET_AV; + if (create) return GvAVn(gv); if (gv) @@ -2424,6 +2462,9 @@ HV* Perl_get_hv(pTHX_ const char *name, I32 create) { GV* const gv = gv_fetchpv(name, create, SVt_PVHV); + + PERL_ARGS_ASSERT_GET_HV; + if (create) return GvHVn(gv); if (gv) @@ -2456,9 +2497,11 @@ Perl_get_cvn_flags(pTHX_ const char *name, STRLEN len, I32 flags) /* XXX this is probably not what they think they're getting. * It has the same effect as "sub name;", i.e. just a forward * declaration! */ + + PERL_ARGS_ASSERT_GET_CVN_FLAGS; + if ((flags & ~GV_NOADD_MASK) && !GvCVu(gv)) { - SV *const sv = newSVpvn(name,len); - SvFLAGS(sv) |= flags & SVf_UTF8; + SV *const sv = newSVpvn_flags(name, len, flags & SVf_UTF8); return newSUB(start_subparse(FALSE, 0), newSVOP(OP_CONST, 0, sv), NULL, NULL); @@ -2471,6 +2514,8 @@ Perl_get_cvn_flags(pTHX_ const char *name, STRLEN len, I32 flags) CV* Perl_get_cv(pTHX_ const char *name, I32 flags) { + PERL_ARGS_ASSERT_GET_CV; + return get_cvn_flags(name, strlen(name), flags); } @@ -2496,10 +2541,12 @@ Perl_call_argv(pTHX_ const char *sub_name, I32 flags, register char **argv) dVAR; dSP; + PERL_ARGS_ASSERT_CALL_ARGV; + PUSHMARK(SP); if (argv) { while (*argv) { - XPUSHs(sv_2mortal(newSVpv(*argv,0))); + mXPUSHs(newSVpv(*argv,0)); argv++; } PUTBACK; @@ -2520,6 +2567,8 @@ Perl_call_pv(pTHX_ const char *sub_name, I32 flags) /* name of the subroutine */ /* See G_* flags in cop.h */ { + PERL_ARGS_ASSERT_CALL_PV; + return call_sv((SV*)get_cv(sub_name, TRUE), flags); } @@ -2537,6 +2586,8 @@ Perl_call_method(pTHX_ const char *methname, I32 flags) /* name of the subroutine */ /* See G_* flags in cop.h */ { + PERL_ARGS_ASSERT_CALL_METHOD; + return call_sv(sv_2mortal(newSVpv(methname,0)), flags | G_METHOD); } @@ -2551,7 +2602,7 @@ L. */ I32 -Perl_call_sv(pTHX_ SV *sv, I32 flags) +Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) /* See G_* flags in cop.h */ { dVAR; dSP; @@ -2565,18 +2616,23 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) OP* const oldop = PL_op; dJMPENV; + PERL_ARGS_ASSERT_CALL_SV; + if (flags & G_DISCARD) { ENTER; SAVETMPS; } + if (!(flags & G_WANT)) { + /* Backwards compatibility - as G_SCALAR was 0, it could be omitted. + */ + flags |= G_SCALAR; + } Zero(&myop, 1, LOGOP); myop.op_next = NULL; if (!(flags & G_NOARGS)) myop.op_flags |= OPf_STACKED; - myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID : - (flags & G_ARRAY) ? OPf_WANT_LIST : - OPf_WANT_SCALAR); + myop.op_flags |= OP_GIMME_REVERSE(flags); SAVEOP(); PL_op = (OP*)&myop; @@ -2598,7 +2654,9 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) Zero(&method_op, 1, UNOP); method_op.op_next = PL_op; method_op.op_ppaddr = PL_ppaddr[OP_METHOD]; + method_op.op_type = OP_METHOD; myop.op_ppaddr = PL_ppaddr[OP_ENTERSUB]; + myop.op_type = OP_ENTERSUB; PL_op = (OP*)&method_op; } @@ -2621,8 +2679,9 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) redo_body: CALL_BODY_SUB((OP*)&myop); retval = PL_stack_sp - (PL_stack_base + oldmark); - if (!(flags & G_KEEPERR)) - sv_setpvn(ERRSV,"",0); + if (!(flags & G_KEEPERR)) { + CLEAR_ERRSV(); + } break; case 1: STATUS_ALL_FAILURE; @@ -2643,7 +2702,7 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) goto redo_body; } PL_stack_sp = PL_stack_base + oldmark; - if (flags & G_ARRAY) + if ((flags & G_WANT) == G_ARRAY) retval = 0; else { retval = 1; @@ -2691,6 +2750,8 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) OP* const oldop = PL_op; dJMPENV; + PERL_ARGS_ASSERT_EVAL_SV; + if (flags & G_DISCARD) { ENTER; SAVETMPS; @@ -2706,9 +2767,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) myop.op_flags = OPf_STACKED; myop.op_next = NULL; myop.op_type = OP_ENTEREVAL; - myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID : - (flags & G_ARRAY) ? OPf_WANT_LIST : - OPf_WANT_SCALAR); + myop.op_flags |= OP_GIMME_REVERSE(flags); if (flags & G_KEEPERR) myop.op_flags |= OPf_SPECIAL; @@ -2722,8 +2781,9 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) redo_body: CALL_BODY_EVAL((OP*)&myop); retval = PL_stack_sp - (PL_stack_base + oldmark); - if (!(flags & G_KEEPERR)) - sv_setpvn(ERRSV,"",0); + if (!(flags & G_KEEPERR)) { + CLEAR_ERRSV(); + } break; case 1: STATUS_ALL_FAILURE; @@ -2744,7 +2804,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) goto redo_body; } PL_stack_sp = PL_stack_base + oldmark; - if (flags & G_ARRAY) + if ((flags & G_WANT) == G_ARRAY) retval = 0; else { retval = 1; @@ -2779,6 +2839,8 @@ Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error) dSP; SV* sv = newSVpv(p, 0); + PERL_ARGS_ASSERT_EVAL_PV; + eval_sv(sv, G_SCALAR); SvREFCNT_dec(sv); @@ -2812,6 +2874,9 @@ Perl_require_pv(pTHX_ const char *pv) dVAR; dSP; SV* sv; + + PERL_ARGS_ASSERT_REQUIRE_PV; + PUSHSTACKi(PERLSI_REQUIRE); PUTBACK; sv = Perl_newSVpvf(aTHX_ "require q%c%s%c", 0, pv, 0); @@ -2825,6 +2890,8 @@ Perl_magicname(pTHX_ const char *sym, const char *name, I32 namlen) { register GV * const gv = gv_fetchpv(sym, GV_ADD, SVt_PV); + PERL_ARGS_ASSERT_MAGICNAME; + if (gv) sv_magic(GvSV(gv), (SV*)gv, PERL_MAGIC_sv, name, namlen); } @@ -2852,7 +2919,6 @@ S_usage(pTHX_ const char *name) /* XXX move this out into a module ? */ "-[mM][-]module execute \"use/no module...\" before executing program", "-n assume \"while (<>) { ... }\" loop around program", "-p assume loop like -n but print line also, like sed", -"-P run program through C preprocessor before compilation", "-s enable rudimentary parsing for switches after programfile", "-S look for programfile using PATH environment variable", "-t enable tainting warnings", @@ -2870,6 +2936,8 @@ NULL }; const char * const *p = usage_msg; + PERL_ARGS_ASSERT_USAGE; + PerlIO_printf(PerlIO_stdout(), "\nUsage: %s [switches] [--] [programfile] [arguments]", name); @@ -2892,7 +2960,7 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp) " t Trace execution", " o Method and overloading resolution", " c String/numeric conversions", - " P Print profiling info, preprocessor command for -P, source file input state", + " P Print profiling info, source file input state", " m Memory allocation", " f Format processing", " r Regular expression parsing and execution", @@ -2901,7 +2969,6 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp) " H Hash dump -- usurps values()", " X Scratchpad allocation", " D Cleaning up", - " S Thread synchronization", " T Tokenising", " R Include reference counts of dumped variables (eg when using -Ds)", " J Do not s,t,P-debug (Jump over) opcodes within package DB", @@ -2912,6 +2979,9 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp) NULL }; int i = 0; + + PERL_ARGS_ASSERT_GET_DEBUG_OPTS; + if (isALPHA(**s)) { /* if adding extra options, remember to update DEBUG_MASK */ static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAq"; @@ -2944,11 +3014,14 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp) /* This routine handles any switches that can be given during run */ -char * -Perl_moreswitches(pTHX_ char *s) +const char * +Perl_moreswitches(pTHX_ const char *s) { dVAR; UV rschar; + const char option = *s; /* used to remember option in -m/-M code */ + + PERL_ARGS_ASSERT_MORESWITCHES; switch (*s) { case '0': @@ -3014,7 +3087,7 @@ Perl_moreswitches(pTHX_ char *s) s++; return s; case 'd': - forbid_setid('d', -1); + forbid_setid('d', FALSE); s++; /* -dt indicates to the debugger that threads will be used */ @@ -3026,20 +3099,21 @@ Perl_moreswitches(pTHX_ char *s) /* The following permits -d:Mod to accepts arguments following an = in the fashion that -MSome::Mod does. */ if (*s == ':' || *s == '=') { - const char *start; + const char *start = ++s; + const char *const end = s + strlen(s); SV * const sv = newSVpvs("use Devel::"); - start = ++s; + /* We now allow -d:Module=Foo,Bar */ while(isALNUM(*s) || *s==':') ++s; if (*s != '=') - sv_catpv(sv, start); + sv_catpvn(sv, start, end - start); else { sv_catpvn(sv, start, s-start); /* Don't use NUL as q// delimiter here, this string goes in the * environment. */ Perl_sv_catpvf(aTHX_ sv, " split(/,/,q{%s});", ++s); } - s += strlen(s); + s = end; my_setenv("PERL5DB", SvPV_nolen_const(sv)); SvREFCNT_dec(sv); } @@ -3051,7 +3125,7 @@ Perl_moreswitches(pTHX_ char *s) case 'D': { #ifdef DEBUGGING - forbid_setid('D', -1); + forbid_setid('D', FALSE); s++; PL_debug = get_debug_opts( (const char **)&s, 1) | DEBUG_TOP_FLAG; #else /* !DEBUGGING */ @@ -3087,12 +3161,12 @@ Perl_moreswitches(pTHX_ char *s) } return s; case 'I': /* -I handled both here and in parse_body() */ - forbid_setid('I', -1); + forbid_setid('I', FALSE); ++s; while (*s && isSPACE(*s)) ++s; if (*s) { - char *e, *p; + const char *e, *p; p = s; /* ignore trailing spaces (possibly followed by other switches) */ do { @@ -3136,14 +3210,16 @@ Perl_moreswitches(pTHX_ char *s) } return s; case 'M': - forbid_setid('M', -1); /* XXX ? */ + forbid_setid('M', FALSE); /* XXX ? */ /* FALL THROUGH */ case 'm': - forbid_setid('m', -1); /* XXX ? */ + forbid_setid('m', FALSE); /* XXX ? */ if (*++s) { - char *start; + const char *start; + const char *end; SV *sv; const char *use = "use "; + bool colon = FALSE; /* -M-foo == 'no foo' */ /* Leading space on " no " is deliberate, to make both possibilities the same length. */ @@ -3151,29 +3227,42 @@ Perl_moreswitches(pTHX_ char *s) sv = newSVpvn(use,4); start = s; /* We allow -M'Module qw(Foo Bar)' */ - while(isALNUM(*s) || *s==':') ++s; + while(isALNUM(*s) || *s==':') { + if( *s++ == ':' ) { + if( *s == ':' ) + s++; + else + colon = TRUE; + } + } + if (s == start) + Perl_croak(aTHX_ "Module name required with -%c option", + option); + if (colon) + Perl_croak(aTHX_ "Invalid module name %.*s with -%c option: " + "contains single ':'", + (int)(s - start), start, option); + end = s + strlen(s); if (*s != '=') { - sv_catpv(sv, start); - if (*(start-1) == 'm') { + sv_catpvn(sv, start, end - start); + if (option == 'm') { if (*s != '\0') Perl_croak(aTHX_ "Can't use '%c' after -mname", *s); sv_catpvs( sv, " ()"); } } else { - if (s == start) - Perl_croak(aTHX_ "Module name required with -%c option", - s[-1]); sv_catpvn(sv, start, s-start); - sv_catpvs(sv, " split(/,/,q"); - sv_catpvs(sv, "\0"); /* Use NUL as q//-delimiter. */ - sv_catpv(sv, ++s); + /* Use NUL as q''-delimiter. */ + sv_catpvs(sv, " split(/,/,q\0"); + ++s; + sv_catpvn(sv, s, end - s); sv_catpvs(sv, "\0)"); } - s += strlen(s); + s = end; Perl_av_create_and_push(aTHX_ &PL_preambleav, sv); } else - Perl_croak(aTHX_ "Missing argument to -%c", *(s-1)); + Perl_croak(aTHX_ "Missing argument to -%c", option); return s; case 'n': PL_minus_n = TRUE; @@ -3184,7 +3273,7 @@ Perl_moreswitches(pTHX_ char *s) s++; return s; case 's': - forbid_setid('s', -1); + forbid_setid('s', FALSE); PL_doswitches = TRUE; s++; return s; @@ -3342,8 +3431,10 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n"); return s; case '*': case ' ': - if (s[1] == '-') /* Additional switches on #! line. */ - return s+2; + while( *s == ' ' ) + ++s; + if (s[0] == '-') /* Additional switches on #! line. */ + return s+1; break; case '-': case 0: @@ -3357,10 +3448,6 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n"); case 'S': /* OS/2 needs -S on "extproc" line. */ break; #endif - case 'P': - if (PL_preprocess) - return s+1; - /* FALL THROUGH */ default: Perl_croak(aTHX_ "Can't emulate -%.1s on #! line",s); } @@ -3476,7 +3563,7 @@ S_init_main_stash(pTHX) gv_SVadd(PL_errgv); #endif sv_grow(ERRSV, 240); /* Preallocate - for immediate signals. */ - sv_setpvn(ERRSV, "", 0); + CLEAR_ERRSV(); PL_curstash = PL_defstash; CopSTASH_set(&PL_compiling, PL_defstash); PL_debstash = GvHV(gv_fetchpvs("DB::", GV_ADDMULTI, SVt_PVHV)); @@ -3487,19 +3574,13 @@ S_init_main_stash(pTHX) } STATIC int -S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv, - int *suidscript, PerlIO **rsfpp) +S_open_script(pTHX_ const char *scriptname, bool dosearch, + bool *suidscript, PerlIO **rsfpp) { -#ifndef IAMSUID - const char *quote; - const char *code; - const char *cpp_discard_flag; - const char *perl; -#endif int fdscript = -1; dVAR; - *suidscript = -1; + PERL_ARGS_ASSERT_OPEN_SCRIPT; if (PL_e_script) { PL_origfilename = savepvs("-e"); @@ -3523,7 +3604,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv, * Is it a mistake to use a similar /dev/fd/ construct for * suidperl? */ - *suidscript = 1; + *suidscript = TRUE; /* PSz 20 Feb 04 * Be supersafe and do some sanity-checks. * Still, can we be sure we got the right thing? @@ -3566,76 +3647,10 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv, * perl with that fd as it has always done. */ } - if (*suidscript != 1) { + if (*suidscript) { Perl_croak(aTHX_ "suidperl needs (suid) fd script\n"); } #else /* IAMSUID */ - else if (PL_preprocess) { - const char * const cpp_cfg = CPPSTDIN; - SV * const cpp = newSVpvs(""); - SV * const cmd = newSV(0); - - if (cpp_cfg[0] == 0) /* PERL_MICRO? */ - Perl_croak(aTHX_ "Can't run with cpp -P with CPPSTDIN undefined"); - if (strEQ(cpp_cfg, "cppstdin")) - Perl_sv_catpvf(aTHX_ cpp, "%s/", BIN_EXP); - sv_catpv(cpp, cpp_cfg); - -# ifndef VMS - sv_catpvs(sv, "-I"); - sv_catpv(sv,PRIVLIB_EXP); -# endif - - DEBUG_P(PerlIO_printf(Perl_debug_log, - "PL_preprocess: scriptname=\"%s\", cpp=\"%s\", sv=\"%s\", CPPMINUS=\"%s\"\n", - scriptname, SvPVX_const (cpp), SvPVX_const (sv), - CPPMINUS)); - -# if defined(MSDOS) || defined(WIN32) || defined(VMS) - quote = "\""; -# else - quote = "'"; -# endif - -# ifdef VMS - cpp_discard_flag = ""; -# else - cpp_discard_flag = "-C"; -# endif - -# ifdef OS2 - perl = os2_execname(aTHX); -# else - perl = PL_origargv[0]; -# endif - - - /* This strips off Perl comments which might interfere with - the C pre-processor, including #!. #line directives are - deliberately stripped to avoid confusion with Perl's version - of #line. FWP played some golf with it so it will fit - into VMS's 255 character buffer. - */ - if( PL_doextract ) - code = "(1../^#!.*perl/i)|/^\\s*#(?!\\s*((ifn?|un)def|(el|end)?if|define|include|else|error|pragma)\\b)/||!($|=1)||print"; - else - code = "/^\\s*#(?!\\s*((ifn?|un)def|(el|end)?if|define|include|else|error|pragma)\\b)/||!($|=1)||print"; - - Perl_sv_setpvf(aTHX_ cmd, "\ -%s -ne%s%s%s %s | %"SVf" %s %"SVf" %s", - perl, quote, code, quote, scriptname, SVfARG(cpp), - cpp_discard_flag, SVfARG(sv), CPPMINUS); - - PL_doextract = FALSE; - - DEBUG_P(PerlIO_printf(Perl_debug_log, - "PL_preprocess: cmd=\"%s\"\n", - SvPVX_const(cmd))); - - *rsfpp = PerlProc_popen((char *)SvPVX_const(cmd), (char *)"r"); - SvREFCNT_dec(cmd); - SvREFCNT_dec(cpp); - } else if (!*scriptname) { forbid_setid(0, *suidscript); *rsfpp = PerlIO_stdin(); @@ -3834,14 +3849,22 @@ S_fd_on_nosuid_fs(pTHX_ int fd) } #endif /* IAMSUID */ +#ifdef DOSUID STATIC void -S_validate_suid(pTHX_ const char *validarg, const char *scriptname, - int fdscript, int suidscript, SV *linestr_sv, PerlIO *rsfp) +S_validate_suid(pTHX_ const char *validarg, +# ifndef IAMSUID + const char *scriptname, +# endif + int fdscript, +# ifdef IAMSUID + bool suidscript, +# endif + SV *linestr_sv, PerlIO *rsfp) { dVAR; -#ifdef IAMSUID - /* int which; */ -#endif /* IAMSUID */ + const char *s, *s2; + + PERL_ARGS_ASSERT_VALIDATE_SUID; /* do we need to emulate setuid on scripts? */ @@ -3870,9 +3893,6 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname, * Configure script will set this up for you if you want it. */ -#ifdef DOSUID - const char *s, *s2; - if (PerlLIO_fstat(PerlIO_fileno(rsfp),&PL_statbuf) < 0) /* normal stat is insecure */ Perl_croak(aTHX_ "Can't stat script \"%s\"",PL_origfilename); if (PL_statbuf.st_mode & (S_ISUID|S_ISGID)) { @@ -3881,7 +3901,7 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname, const char *s_end; # ifdef IAMSUID - if (fdscript < 0 || suidscript != 1) + if (fdscript < 0 || !suidscript) Perl_croak(aTHX_ "Need (suid) fdscript in suidperl\n"); /* We already checked this */ /* PSz 11 Nov 03 * Since the script is opened by perl, not suidperl, some of these @@ -4158,9 +4178,7 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); Perl_croak(aTHX_ "Effective UID cannot exec script\n"); /* they can't do this */ } # ifdef IAMSUID - else if (PL_preprocess) /* PSz 13 Nov 03 Caught elsewhere, useless(?!) here */ - Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n"); - else if (fdscript < 0 || suidscript != 1) + else if (fdscript < 0 || !suidscript) /* PSz 13 Nov 03 Caught elsewhere, useless(?!) here */ Perl_croak(aTHX_ "(suid) fdscript needed in suidperl\n"); else { @@ -4206,13 +4224,6 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); /* PSz 11 Nov 03 * Keep original arguments: suidperl already has fd script. */ -/* for (which = 1; PL_origargv[which] && PL_origargv[which] != scriptname; which++) ; */ -/* if (!PL_origargv[which]) { */ -/* errno = EPERM; */ -/* Perl_croak(aTHX_ "Permission denied\n"); */ -/* } */ -/* PL_origargv[which] = savepv(Perl_form(aTHX_ "/dev/fd/%d/%s", */ -/* PerlIO_fileno(rsfp), PL_origargv[which])); */ # if defined(HAS_FCNTL) && defined(F_SETFD) fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */ # endif @@ -4223,13 +4234,22 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n"); PERL_FPU_POST_EXEC Perl_croak(aTHX_ "Can't do setuid (suidperl cannot exec perl)\n"); # endif /* IAMSUID */ +} + #else /* !DOSUID */ - PERL_UNUSED_ARG(fdscript); - PERL_UNUSED_ARG(suidscript); - if (PL_euid != PL_uid || PL_egid != PL_gid) { /* (suidperl doesn't exist, in fact) */ + # ifdef SETUID_SCRIPTS_ARE_SECURE_NOW - PERL_UNUSED_ARG(rsfp); +/* Don't even need this function. */ # else +STATIC void +S_validate_suid(pTHX_ PerlIO *rsfp) +{ + PERL_ARGS_ASSERT_VALIDATE_SUID; + + if (PL_euid != PL_uid || PL_egid != PL_gid) { /* (suidperl doesn't exist, in fact) */ +# ifndef SETUID_SCRIPTS_ARE_SECURE_NOW + dVAR; + PerlLIO_fstat(PerlIO_fileno(rsfp),&PL_statbuf); /* may be either wrapped or real suid */ if ((PL_euid != PL_uid && PL_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID) || @@ -4241,22 +4261,22 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); # endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */ /* not set-id, must be wrapped */ } -#endif /* DOSUID */ - PERL_UNUSED_ARG(validarg); - PERL_UNUSED_ARG(scriptname); - PERL_UNUSED_ARG(linestr_sv); } +# endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */ +#endif /* DOSUID */ STATIC void S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp) { dVAR; - register char *s; + const char *s; register const char *s2; #ifdef MACOS_TRADITIONAL int maclines = 0; #endif + PERL_ARGS_ASSERT_FIND_BEGINNING; + /* skip forward in input to the real script? */ #ifdef MACOS_TRADITIONAL @@ -4384,7 +4404,7 @@ Perl_doing_taint(int argc, char *argv[], char *envp[]) "program input from stdin", which is substituted in place of '\0', which could never be a command line flag. */ STATIC void -S_forbid_setid(pTHX_ const char flag, const int suidscript) +S_forbid_setid(pTHX_ const char flag, const bool suidscript) /* g */ { dVAR; char string[3] = "-x"; @@ -4423,7 +4443,7 @@ S_forbid_setid(pTHX_ const char flag, const int suidscript) * * Also see comments about root running a setuid script, elsewhere. */ - if (suidscript >= 0) + if (suidscript) Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", message); #ifdef IAMSUID /* PSz 11 Nov 03 Catch it in suidperl, always! */ @@ -4562,6 +4582,9 @@ void Perl_init_argv_symbols(pTHX_ register int argc, register char **argv) { dVAR; + + PERL_ARGS_ASSERT_INIT_ARGV_SYMBOLS; + argc--,argv++; /* skip name of script */ if (PL_doswitches) { for (; argc > 0 && **argv == '-'; argc--,argv++) { @@ -4604,6 +4627,8 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register dVAR; GV* tmpgv; + PERL_ARGS_ASSERT_INIT_POSTDUMP_SYMBOLS; + PL_toptarget = newSV_type(SVt_PVFM); sv_setpvn(PL_toptarget, "", 0); PL_bodytarget = newSV_type(SVt_PVFM); @@ -4648,18 +4673,21 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register environ[0] = NULL; } if (env) { - char *s; + char *s, *old_var; SV *sv; for (; *env; env++) { - if (!(s = strchr(*env,'=')) || s == *env) + old_var = *env; + + if (!(s = strchr(old_var,'=')) || s == old_var) continue; + #if defined(MSDOS) && !defined(DJGPP) *s = '\0'; - (void)strupr(*env); + (void)strupr(old_var); *s = '='; #endif sv = newSVpv(s+1, 0); - (void)hv_store(hv, *env, s - *env, sv, 0); + (void)hv_store(hv, old_var, s - old_var, sv, 0); if (env_is_not_environ) mg_set(sv); } @@ -4834,6 +4862,9 @@ S_incpush_if_exists(pTHX_ SV *dir) { dVAR; Stat_t tmpstatbuf; + + PERL_ARGS_ASSERT_INCPUSH_IF_EXISTS; + if (PerlLIO_stat(SvPVX_const(dir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode)) { av_push(GvAVn(PL_incgv), dir); @@ -4925,7 +4956,8 @@ S_incpush(pTHX_ const char *dir, bool addsubdirs, bool addoldvers, bool usesep, SvPOK() won't be true. */ assert(caret_X); assert(SvPOKp(caret_X)); - prefix_sv = newSVpvn(SvPVX(caret_X), SvCUR(caret_X)); + prefix_sv = newSVpvn_flags(SvPVX(caret_X), SvCUR(caret_X), + SvUTF8(caret_X)); /* Firstly take off the leading .../ If all else fail we'll do the paths relative to the current directory. */ @@ -5076,6 +5108,8 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) int ret; dJMPENV; + PERL_ARGS_ASSERT_CALL_LIST; + while (av_len(paramList) >= 0) { cv = (CV*)av_shift(paramList); if (PL_savebegin) { @@ -5169,8 +5203,6 @@ void Perl_my_exit(pTHX_ U32 status) { dVAR; - DEBUG_S(PerlIO_printf(Perl_debug_log, "my_exit: thread %p, status %lu\n", - (void*)thr, (unsigned long) status)); switch (status) { case 0: STATUS_ALL_SUCCESS;