diff --git a/embedvar.h b/embedvar.h index 05f9ed6ef11d..e2e9c4681aa4 100644 --- a/embedvar.h +++ b/embedvar.h @@ -319,9 +319,8 @@ # define PL_sv_yes (vTHX->Isv_yes) # define PL_sv_zero (vTHX->Isv_zero) # define PL_sys_intern (vTHX->Isys_intern) +# define PL_taint (vTHX->Itaint) # define PL_taint_warn (vTHX->Itaint_warn) -# define PL_tainted (vTHX->Itainted) -# define PL_tainting (vTHX->Itainting) # define PL_threadhook (vTHX->Ithreadhook) # define PL_tmps_floor (vTHX->Itmps_floor) # define PL_tmps_ix (vTHX->Itmps_ix) diff --git a/intrpvar.h b/intrpvar.h index 482f46d71885..d6a14d477f7c 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -74,8 +74,9 @@ PERLVAR(I, multideref_pc, UNOP_AUX_item *) PERLVAR(I, curpm, PMOP *) /* what to do \ interps in REs from */ PERLVAR(I, curpm_under, PMOP *) /* what to do \ interps in REs from */ -PERLVAR(I, tainting, bool) /* ? doing taint checks */ -PERLVARI(I, tainted, bool, FALSE) /* using variables controlled by $< */ +/* bool PL_tainting --- ? doing taint checks */ +/* bool PL_tainted --- using variables controlled by $< */ +PERLVAR(I, taint, TAINT_U) /* PL_delaymagic is currently used for two purposes: to assure simultaneous * updates in ($<,$>) = ..., and to assure atomic update in push/unshift diff --git a/perl.c b/perl.c index 15127adc50fe..cdb23079b740 100644 --- a/perl.c +++ b/perl.c @@ -249,6 +249,17 @@ perl_construct(pTHXx) SvREADONLY_on(&PL_sv_placeholder); SvREFCNT(&PL_sv_placeholder) = SvREFCNT_IMMORTAL; + STATIC_ASSERT_STMT( + sizeof(((TAINT_U *)0)->both) + == (sizeof(((TAINT_U *)0)->u.tainting) + sizeof(((TAINT_U *)0)->u.tainted)) + ); + STATIC_ASSERT_STMT( + sizeof(((TAINT_U *)0)->both) + == (STRUCT_OFFSET(TAINT_U, u.tainted) + sizeof(((TAINT_U *)0)->u.tainted)) + ); + STATIC_ASSERT_STMT(STRUCT_OFFSET(TAINT_U, both) == STRUCT_OFFSET(TAINT_U, u.tainting)); + /* PL_taint.u.both = 0; */ + PL_sighandlerp = Perl_sighandler; PL_sighandler1p = Perl_sighandler1; PL_sighandler3p = Perl_sighandler3; diff --git a/perl.h b/perl.h index 7641425fcc12..a60a6c0e4895 100644 --- a/perl.h +++ b/perl.h @@ -940,6 +940,8 @@ symbol would not be defined on C> platforms. * know what you're doing: tests and CPAN modules' tests are bound to fail. */ #ifdef NO_TAINT_SUPPORT +# define PL_tainting PL_taint.u.tainting +# define PL_tainted PL_taint.u.tainted # define TAINT NOOP # define TAINT_NOT NOOP # define TAINT_IF(c) NOOP @@ -948,6 +950,7 @@ symbol would not be defined on C> platforms. # define TAINT_set(s) NOOP # define TAINT_get 0 # define TAINTING_get 0 +# define TAINT_AND_TAINTING_get 0 # define TAINTING_set(s) NOOP # define TAINT_WARN_get 0 # define TAINT_WARN_set(s) NOOP @@ -1014,6 +1017,10 @@ violations are fatal. =cut */ + +#define PL_tainting PL_taint.u.tainting +#define PL_tainted PL_taint.u.tainted + /* Set to tainted if we are running under tainting mode */ # define TAINT (PL_tainted = PL_tainting) @@ -1027,6 +1034,8 @@ violations are fatal. # define TAINT_set(s) (PL_tainted = cBOOL(s)) # define TAINT_get (cBOOL(UNLIKELY(PL_tainted))) /* Is something tainted? */ # define TAINTING_get (cBOOL(UNLIKELY(PL_tainting))) +/* Efficient version of (PL_tainted && PL_tainting) */ +# define TAINT_AND_TAINTING_get (UNLIKELY(PL_taint.both == (TRUE | (TRUE << 8)))) # define TAINTING_set(s) (PL_tainting = cBOOL(s)) # define TAINT_WARN_get (PL_taint_warn) # define TAINT_WARN_set(s) (PL_taint_warn = cBOOL(s)) @@ -3309,6 +3318,14 @@ typedef struct padname PADNAME; #include "handy.h" #include "charclass_invlists.h" +typedef union { + U16 both; + struct { + bool tainting; + bool tainted; + } u; +} TAINT_U; + #if defined(USE_LARGE_FILES) && !defined(NO_64_BIT_RAWIO) # if LSEEKSIZE == 8 && !defined(USE_64_BIT_RAWIO) # define USE_64_BIT_RAWIO /* implicit */ diff --git a/sv.c b/sv.c index f4ddf9b8888c..f8e2d42c2da0 100644 --- a/sv.c +++ b/sv.c @@ -15912,7 +15912,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, #ifndef NO_TAINT_SUPPORT /* Set tainting stuff before PerlIO_debug can possibly get called */ - PL_tainting = proto_perl->Itainting; + PL_tainting = proto_perl->Itaint.u.tainting; PL_taint_warn = proto_perl->Itaint_warn; #else PL_tainting = FALSE; @@ -16057,7 +16057,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_statcache = proto_perl->Istatcache; #ifndef NO_TAINT_SUPPORT - PL_tainted = proto_perl->Itainted; + PL_tainted = proto_perl->Itaint.u.tainted; #else PL_tainted = FALSE; #endif diff --git a/sv.h b/sv.h index 4f8c4a227517..4264c21a3470 100644 --- a/sv.h +++ b/sv.h @@ -1735,8 +1735,8 @@ attention to precisely which outputs are influenced by which inputs. #define SvTAINT(sv) \ STMT_START { \ assert(TAINTING_get || !TAINT_get); \ - if (UNLIKELY(TAINT_get)) \ - SvTAINTED_on(sv); \ + if (TAINT_AND_TAINTING_get) \ + sv_taint(sv); \ } STMT_END /*