summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mg.c5
-rwxr-xr-xt/op/taint.t14
2 files changed, 17 insertions, 2 deletions
diff --git a/mg.c b/mg.c
index a0877c5346..c5566dca77 100644
--- a/mg.c
+++ b/mg.c
@@ -100,7 +100,10 @@ S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
SvMAGICAL_off(sv);
SvREADONLY_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+ if (!(SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK))) {
+ /* No public flags are set, so promote any private flags to public. */
+ SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+ }
}
/*
diff --git a/t/op/taint.t b/t/op/taint.t
index 9e4bba2d70..533733276a 100755
--- a/t/op/taint.t
+++ b/t/op/taint.t
@@ -17,7 +17,7 @@ use Config;
use File::Spec::Functions;
BEGIN { require './test.pl'; }
-plan tests => 255;
+plan tests => 257;
$| = 1;
@@ -1218,3 +1218,15 @@ SKIP:
eval { sprintf("# %s\n", $TAINT . "foo") };
ok(!$@, q/sprintf accepts other tainted args/);
}
+
+{
+ # 40708
+ my $n = 7e9;
+ 8e9 - $n;
+
+ my $val = $n;
+ is ($val, '7000000000', 'Assignment to untainted variable');
+ $val = $TAINT;
+ $val = $n;
+ is ($val, '7000000000', 'Assignment to tainted variable');
+}