In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/b20c4ee1fc23699f6cbe3ce96cc8fe6eb4c52c4c?hp=1ccd2973f698bfdb82dfadf6ef09ec337061a97f>

- Log -----------------------------------------------------------------
commit b20c4ee1fc23699f6cbe3ce96cc8fe6eb4c52c4c
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Mon Oct 4 12:24:37 2010 -0700

    [perl #20661] Constant strings representing a number can BECOME numbers
    
    The & | ^ operators now avoid turning on numericness of read-only
    arguments.
-----------------------------------------------------------------------

Summary of changes:
 pod/perldelta.pod |    5 +++++
 pp.c              |    8 ++++++++
 t/op/bop.t        |   16 +++++++++++++++-
 3 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index ef58531..5cd276e 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -672,6 +672,11 @@ L<[perl 
#78058]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=78058>.
 Subroutine redefinition works once more in the debugger
 L<[perl #48332]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=48332>.
 
+=item *
+
+The C<&> C<|> C<^> bitwise operators no longer coerce read-only arguments
+L<[perl #20661]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=20661>.
+
 =back
 
 =head1 Known Problems
diff --git a/pp.c b/pp.c
index c478a47..a1558de 100644
--- a/pp.c
+++ b/pp.c
@@ -2386,6 +2386,8 @@ PP(pp_bit_and)
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
+       const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
+       const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
        if (PL_op->op_private & HINT_INTEGER) {
          const IV i = SvIV_nomg(left) & SvIV_nomg(right);
          SETi(i);
@@ -2394,6 +2396,8 @@ PP(pp_bit_and)
          const UV u = SvUV_nomg(left) & SvUV_nomg(right);
          SETu(u);
        }
+       if (left_ro_nonnum)  SvNIOK_off(left);
+       if (right_ro_nonnum) SvNIOK_off(right);
       }
       else {
        do_vop(PL_op->op_type, TARG, left, right);
@@ -2412,6 +2416,8 @@ PP(pp_bit_or)
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
+       const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
+       const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
        if (PL_op->op_private & HINT_INTEGER) {
          const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
          const IV r = SvIV_nomg(right);
@@ -2424,6 +2430,8 @@ PP(pp_bit_or)
          const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
          SETu(result);
        }
+       if (left_ro_nonnum)  SvNIOK_off(left);
+       if (right_ro_nonnum) SvNIOK_off(right);
       }
       else {
        do_vop(op_type, TARG, left, right);
diff --git a/t/op/bop.t b/t/op/bop.t
index b7f82ee..fdcded1 100644
--- a/t/op/bop.t
+++ b/t/op/bop.t
@@ -15,7 +15,7 @@ BEGIN {
 # If you find tests are failing, please try adding names to tests to track
 # down where the failure is, and supply your new names as a patch.
 # (Just-in-time test naming)
-plan tests => 161 + (10*13*2) + 4;
+plan tests => 170 + (10*13*2) + 4;
 
 # numerics
 ok ((0xdead & 0xbeef) == 0x9ead);
@@ -63,6 +63,20 @@ is (($foo | $bar), ($Aoz x 75 . $zap));
 # ^ does not truncate
 is (($foo ^ $bar), ($Axz x 75 . $zap));
 
+# string constants
+sub _and($) { $_[0] & "+0" }
+sub _oar($) { $_[0] | "+0" }
+sub _xor($) { $_[0] ^ "+0" }
+is _and "waf", '# ',  'str var & const str'; # These three
+is _and  0,    '0',   'num var & const str';    # are from
+is _and "waf", '# ',  'str var & const str again'; # [perl #20661]
+is _oar "yit", '{yt', 'str var | const str';
+is _oar  0,    '0',   'num var | const str';
+is _oar "yit", '{yt', 'str var | const str again';
+is _xor "yit", 'RYt', 'str var ^ const str';
+is _xor  0,    '0',   'num var ^ const str';
+is _xor "yit", 'RYt', 'str var ^ const str again';
+
 #
 is ("ok \xFF\xFF\n" & "ok 19\n", "ok 19\n");
 is ("ok 20\n" | "ok \0\0\n", "ok 20\n");

--
Perl5 Master Repository

Reply via email to