X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/ec2a1de722601129850327b38324ac227c58147a..235ac35db87eeb01f0e613de4bd82180b6fa10e8:/mg.c diff --git a/mg.c b/mg.c index c8c935a..56e8065 100644 --- a/mg.c +++ b/mg.c @@ -272,7 +272,7 @@ Perl_mg_length(pTHX_ SV *sv) if (DO_UTF8(sv)) { const U8 *s = (U8*)SvPV_const(sv, len); - len = Perl_utf8_length(aTHX_ s, s + len); + len = utf8_length(s, s + len); } else (void)SvPV_const(sv, len); @@ -379,7 +379,7 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen) } else { const char type = mg->mg_type; - if (isUPPER(type)) { + if (isUPPER(type) && type != PERL_MAGIC_uvar) { sv_magic(nsv, (type == PERL_MAGIC_tied) ? SvTIED_obj(sv, mg) @@ -497,9 +497,18 @@ Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg) if (PL_curpm) { register const REGEXP * const rx = PM_GETRE(PL_curpm); if (rx) { - return mg->mg_obj - ? rx->nparens /* @+ */ - : rx->lastparen; /* @- */ + if (mg->mg_obj) { /* @+ */ + /* return the number possible */ + return rx->nparens; + } else { /* @- */ + I32 paren = rx->lastparen; + + /* return the last filled */ + while ( paren >= 0 + && (rx->startp[paren] == -1 || rx->endp[paren] == -1) ) + paren--; + return (U32)paren; + } } } @@ -531,7 +540,7 @@ Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg) if (i > 0 && RX_MATCH_UTF8(rx)) { const char * const b = rx->subbeg; if (b) - i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i)); + i = utf8_length((U8*)b, (U8*)(b+i)); } sv_setiv(sv, i); @@ -758,10 +767,13 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) SvTAINTED_off(sv); } else if (strEQ(remaining, "PEN")) { - if (!PL_compiling.cop_io) + if (!(CopHINTS_get(&PL_compiling) & HINT_LEXICAL_IO)) sv_setsv(sv, &PL_sv_undef); else { - sv_setsv(sv, PL_compiling.cop_io); + sv_setsv(sv, + Perl_refcounted_he_fetch(aTHX_ + PL_compiling.cop_hints_hash, + 0, "open", 4, 0, 0)); } } break; @@ -816,10 +828,11 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) else if (PL_compiling.cop_warnings == pWARN_ALL) { /* Get the bit mask for $warnings::Bits{all}, because * it could have been extended by warnings::register */ - SV **bits_all; HV * const bits=get_hv("warnings::Bits", FALSE); - if (bits && (bits_all=hv_fetchs(bits, "all", FALSE))) { - sv_setsv(sv, *bits_all); + if (bits) { + SV ** const bits_all = hv_fetchs(bits, "all", FALSE); + if (bits_all) + sv_setsv(sv, *bits_all); } else { sv_setpvn(sv, WARN_ALLstring, WARNsize) ; @@ -850,6 +863,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) i = t1 - s1; s = rx->subbeg + s1; assert(rx->subbeg); + assert(rx->sublen >= s1); getrx: if (i >= 0) { @@ -857,8 +871,13 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) TAINT_NOT; sv_setpvn(sv, s, i); PL_tainted = oldtainted; - if (RX_MATCH_UTF8(rx) && is_utf8_string((U8*)s, i)) + if ( (rx->extflags & RXf_CANY_SEEN) + ? (RX_MATCH_UTF8(rx) + && (!i || is_utf8_string((U8*)s, i))) + : (RX_MATCH_UTF8(rx)) ) + { SvUTF8_on(sv); + } else SvUTF8_off(sv); if (PL_tainting) { @@ -964,7 +983,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) case '/': break; case '[': - WITH_THR(sv_setiv(sv, (IV)CopARYBASE_get(PL_curcop))); + sv_setiv(sv, (IV)CopARYBASE_get(PL_curcop)); break; case '|': if (GvIOp(PL_defoutgv)) @@ -1069,8 +1088,7 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) Stat_t sbuf; int i = 0, j = 0; - strncpy(eltbuf, s, 255); - eltbuf[255] = 0; + my_strlcpy(eltbuf, s, sizeof(eltbuf)); elt = eltbuf; do { /* DCL$PATH may be a search list */ while (1) { /* as may dev portion of any element */ @@ -1099,11 +1117,20 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) char tmpbuf[256]; Stat_t st; I32 i; +#ifdef VMS /* Hmm. How do we get $Config{path_sep} from C? */ + const char path_sep = '|'; +#else + const char path_sep = ':'; +#endif s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, - s, strend, ':', &i); + s, strend, path_sep, &i); s++; if (i >= (I32)sizeof tmpbuf /* too long -- assume the worst */ - || *tmpbuf != '/' +#ifdef VMS + || !strchr(tmpbuf, ':') /* no colon thus no device name -- assume relative path */ +#else + || *tmpbuf != '/' /* no starting slash -- assume relative path */ +#endif || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) { MgTAINTEDDIR_on(mg); return 0; @@ -1166,7 +1193,7 @@ static void restore_sigmask(pTHX_ SV *save_sv) { const sigset_t * const ossetp = (const sigset_t *) SvPV_nolen_const( save_sv ); - (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0); + (void)sigprocmask(SIG_SETMASK, ossetp, NULL); } #endif int @@ -1212,14 +1239,12 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg) SV** svp = NULL; if (strEQ(s,"__DIE__")) svp = &PL_diehook; - else if (strEQ(s,"__WARN__")) + else if (strEQ(s,"__WARN__") && PL_warnhook != PERL_WARNHOOK_FATAL) svp = &PL_warnhook; - else - Perl_croak(aTHX_ "No such hook: %s", s); if (svp && *svp) { - SV * const to_dec = *svp; + SV *const to_dec = *svp; *svp = NULL; - SvREFCNT_dec(to_dec); + SvREFCNT_dec(to_dec); } } else { @@ -1299,7 +1324,17 @@ Perl_csighandler(int sig) exit(1); #endif #endif - if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) + if ( +#ifdef SIGILL + sig == SIGILL || +#endif +#ifdef SIGBUS + sig == SIGBUS || +#endif +#ifdef SIGSEGV + sig == SIGSEGV || +#endif + (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)) /* Call the perl level handler now-- * with risk we may be in malloc() etc. */ (*PL_sighandlerp)(sig); @@ -1372,7 +1407,8 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) Perl_croak(aTHX_ "No such hook: %s", s); i = 0; if (*svp) { - to_dec = *svp; + if (*svp != PERL_WARNHOOK_FATAL) + to_dec = *svp; *svp = NULL; } } @@ -1423,7 +1459,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) SvREFCNT_dec(to_dec); return 0; } - s = SvPV_force(sv,len); + s = SvOK(sv) ? SvPV_force(sv,len) : "DEFAULT"; if (strEQ(s,"IGNORE")) { if (i) { #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS @@ -1659,7 +1695,7 @@ Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key) } int -Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg) +Perl_magic_existspack(pTHX_ SV *sv, const MAGIC *mg) { return magic_methpack(sv,mg,"EXISTS"); } @@ -2230,10 +2266,11 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) } } else if (strEQ(mg->mg_ptr, "\017PEN")) { - if (!PL_compiling.cop_io) - PL_compiling.cop_io = newSVsv(sv); - else - sv_setsv(PL_compiling.cop_io,sv); + PL_compiling.cop_hints |= HINT_LEXICAL_IO; + PL_hints |= HINT_LOCALIZE_HH | HINT_LEXICAL_IO; + PL_compiling.cop_hints_hash + = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints_hash, + sv_2mortal(newSVpvs("open")), sv); } break; case '\020': /* ^P */ @@ -2277,11 +2314,16 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) accumulate |= ptr[i] ; any_fatals |= (ptr[i] & 0xAA) ; } - if (!accumulate) - PL_compiling.cop_warnings = pWARN_NONE; + if (!accumulate) { + if (!specialWARN(PL_compiling.cop_warnings)) + PerlMemShared_free(PL_compiling.cop_warnings); + PL_compiling.cop_warnings = pWARN_NONE; + } /* Yuck. I can't see how to abstract this: */ else if (isWARN_on(((STRLEN *)SvPV_nolen_const(sv)) - 1, WARN_ALL) && !any_fatals) { + if (!specialWARN(PL_compiling.cop_warnings)) + PerlMemShared_free(PL_compiling.cop_warnings); PL_compiling.cop_warnings = pWARN_ALL; PL_dowarn |= G_WARN_ONCE ; } @@ -2510,8 +2552,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) } if (i) (void)setgroups(i, gary); - if (gary) - Safefree(gary); + Safefree(gary); } #else /* HAS_SETGROUPS */ PL_egid = SvIV(sv); @@ -2570,15 +2611,14 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) setproctitle("%s", s); # endif } -#endif -#if defined(__hpux) && defined(PSTAT_SETCMD) +#elif defined(__hpux) && defined(PSTAT_SETCMD) if (PL_origalen != 1) { union pstun un; s = SvPV_const(sv, len); un.pst_command = (char *)s; pstat(PSTAT_SETCMD, un, len, 0, 0); } -#endif +#else if (PL_origalen > 1) { /* PL_origalen is set in perl_parse(). */ s = SvPV_force(sv,len); @@ -2592,17 +2632,23 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) Copy(s, PL_origargv[0], len, char); PL_origargv[0][len] = 0; memset(PL_origargv[0] + len + 1, +#ifdef PERL_DARWIN + /* Special case for darwin: see [perl #38868] */ + (int)'\0', +#else /* Is the space counterintuitive? Yes. - * (You were expecting \0?) + * (You were expecting \0?) * Does it work? Seems to. (In Linux 2.4.20 at least.) * --jhi */ (int)' ', +#endif PL_origalen - len - 1); } PL_origargv[0][PL_origalen-1] = 0; for (i = 1; i < PL_origargc; i++) PL_origargv[i] = 0; } +#endif UNLOCK_DOLLARZERO_MUTEX; break; #endif @@ -2732,7 +2778,7 @@ Perl_sighandler(int sig) #endif EXTEND(SP, 2); PUSHs((SV*)rv); - PUSHs(newSVpv((void*)sip, sizeof(*sip))); + PUSHs(newSVpv((char *)sip, sizeof(*sip))); } va_end(args); @@ -2807,10 +2853,10 @@ S_restore_magic(pTHX_ const void *p) /* downgrade public flags to private, and discard any other private flags */ - U32 public = SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK); - if (public) { - SvFLAGS(sv) &= ~( public | SVp_IOK|SVp_NOK|SVp_POK ); - SvFLAGS(sv) |= ( public << PRIVSHIFT ); + const U32 pubflags = SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK); + if (pubflags) { + SvFLAGS(sv) &= ~( pubflags | (SVp_IOK|SVp_NOK|SVp_POK) ); + SvFLAGS(sv) |= ( pubflags << PRIVSHIFT ); } } } @@ -2855,8 +2901,9 @@ S_unwind_handler_stack(pTHX_ const void *p) =for apidoc magic_sethint Triggered by a store to %^H, records the key/value pair to -C. It is assumed that hints aren't storing anything -that would need a deep copy. Maybe we should warn if we find a reference. +C. It is assumed that hints aren't storing +anything that would need a deep copy. Maybe we should warn if we find a +reference. =cut */ @@ -2875,8 +2922,8 @@ Perl_magic_sethint(pTHX_ SV *sv, MAGIC *mg) Doing this here saves a lot of doing it manually in perl code (and forgetting to do it, and consequent subtle errors. */ PL_hints |= HINT_LOCALIZE_HH; - PL_compiling.cop_hints - = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints, + PL_compiling.cop_hints_hash + = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints_hash, (SV *)mg->mg_ptr, sv); return 0; } @@ -2884,7 +2931,8 @@ Perl_magic_sethint(pTHX_ SV *sv, MAGIC *mg) /* =for apidoc magic_sethint -Triggered by a delete from %^H, records the key to C. +Triggered by a delete from %^H, records the key to +C. =cut */ @@ -2892,13 +2940,15 @@ int Perl_magic_clearhint(pTHX_ SV *sv, MAGIC *mg) { dVAR; + PERL_UNUSED_ARG(sv); + assert(mg->mg_len == HEf_SVKEY); PERL_UNUSED_ARG(sv); PL_hints |= HINT_LOCALIZE_HH; - PL_compiling.cop_hints - = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints, + PL_compiling.cop_hints_hash + = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints_hash, (SV *)mg->mg_ptr, &PL_sv_placeholder); return 0; }