Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

//g loops infinitely on tainted data #4855

Closed
p5pRT opened this issue Jan 16, 2002 · 17 comments
Closed

//g loops infinitely on tainted data #4855

p5pRT opened this issue Jan 16, 2002 · 17 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 16, 2002

Migrated from rt.perl.org#8262 (status was 'resolved')

Searchable as RT8262$

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2002

From skud@infotrope.net

Created by skud@infotrope.net

This is freaky. I've found an odd situation where Perl will go into an
infinite loop when doing a regexp match on tainted data. Here's the
simplest case I can put together​:

  #!/usr/bin/perl -w

  use strict;

  print "The string we're using is '$ENV{LANG}'\n";

  while($ENV{LANG} =~ m/(.)/g ) {
  print "I'm stuck in a loop and I see letter '$1'\n";
  }

Try running that with taint checking off, and you should see it work its
way through the letters in the language you're using. Then try it with
tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

For what it's worth, this caught me in a Real World application where I
was using a CPAN module (Locale​::Maketext, by Sean Burke) which
exhibited this unusual behaviour when I turned taint checking on.

I've verified this behaviour with perl 5.6.0, 5.6.1 and bleadperl, all
on Debian, and others have demonstrated it on other platforms.

K.

`

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.7.2:

Configured by skud at Wed Jan 16 17:07:06 EST 2002.

Summary of my perl5 (revision 5.0 version 7 subversion 2 patch 14304) configuration:
  Platform:
    osname=linux, osvers=2.4.17, archname=i686-linux
    uname='linux tanqueray 2.4.17 #2 smp sun dec 23 14:01:48 est 2001 i686 unknown '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=define
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3',
    cppflags='-fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.4 20011006 (Debian prerelease)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lc -lcrypt -lutil
    perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
    libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    DEVEL14289


@INC for perl v5.7.2:
    /home/skud/bleadperl-install/lib/5.7.2/i686-linux
    /home/skud/bleadperl-install/lib/5.7.2
    /home/skud/bleadperl-install/lib/site_perl/5.7.2/i686-linux
    /home/skud/bleadperl-install/lib/site_perl/5.7.2
    /home/skud/bleadperl-install/lib/site_perl
    /usr/local/share/perl/5.6.1/
    tanqueray
    ~> ls -l /usr/local/lib/perl5/site_perl/5.6.1/
    /usr/local/lib/perl5/site_perl/5.6.0//i686-linux
    /usr/local/lib/perl5/site_perl/5.6.0/
    .


Environment for perl v5.7.2:
    HOME=/home/skud
    LANG=en
    LANGUAGE=en
    LC_ALL=en_US
    LC_CTYPE=
    LD_LIBRARY_PATH=/usr/local/lib:/home/skud/rvplayer5.0
    LOGDIR (unset)
    PATH=/usr/local/jre1.3.1_01/bin:/usr/bin/mh:/usr/lib/mh:/usr/local/netscape:/usr/local/bin:/home/skud/rvplayer5.0:/usr/local/applix:/usr/X11R6/bin:/home/skud/bin:/usr/games:/usr/sbin:/sbin:/usr/local/jre1.3.1_01/bin:/usr/bin/mh:/usr/lib/mh:/usr/local/netscape:/usr/local/bin:/home/skud/rvplayer5.0:/usr/local/applix:/usr/X11R6/bin:/home/skud/bin:/usr/games:/usr/sbin:/sbin:/usr/local/jre1.3.1_01/bin:/usr/bin/mh:/usr/lib/mh:/usr/local/netscape:/usr/local/bin:/home/skud/rvplayer5.0:/usr/local/applix:/usr/X11R6/bin:/home/skud/bin:/usr/games:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/tcsh


@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2002

From @vanstyn

Kirrily Robert <skud@​infotrope.net> wrote​:
[paraphrased]
  perl -Twle 'print "<$1>" while $ENV{LANG} =~ /(.)/g'
loops forever.

This seems to be a symptom of our current approach to localising magic.
The point that we diverge between the with-taint/no-taint variants of
the above is when we get the helem for matching, at the end of
pp_hot.c​:pp_helem​:

  /* This makes C<local $tied{foo} = $tied{foo}> possible.
  * Pushing the magical RHS on to the stack is useless, since
  * that magic is soon destined to be misled by the local(),
  * and thus the later pp_sassign() will fail to mg_get() the
  * old value. This should also cure problems with delayed
  * mg_get()s. GSAR 98-07-03 */
  if (!lval && SvGMAGICAL(sv))
  sv = sv_mortalcopy(sv);

Because the taint adds a GMG flag, we end up with the mortalcopy to
match against; we attach the pos() magic to that, and next time around
the loop we have a fresh mortalcopy and no pos().

I don't know how to solve this, but I suspect the solution is not
small.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jan 17, 2002

From [Unknown Contact. See original ticket]

Kirrily Robert wrote​:
[snip]

while\($ENV\{LANG\} =~ m/\(\.\)/g \) \{
    print "I'm stuck in a loop and I see letter '$1'\\n";
\}

Try running that with taint checking off, and you should see it work
its way through the letters in the language you're using. Then try it
with tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

It is and it isn't a bug :)

With tainting turned on, $ENV{LANG} is slightly more magical than with
tainting turned off, and each time you fetch its value, it produces a
new scalar... one with pos set to 0. As a workaround, do​:
  my $x = $ENV{LANG};
  while( $x =~ m/(.)/g ) { ....

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2003

From cmoore@hellyeah.org

This is also present in 5.8.0.

[skud - Wed Jan 16 13​:03​:13 2002]​:

This is a bug report for perl from skud <!--c--> <i>at</i> <!--a--> infotrope.net,
generated with the help of perlbug 1.33 running under perl v5.7.2.

-----------------------------------------------------------------
[Please enter your report here]

This is freaky. I've found an odd situation where Perl will go into
an
infinite loop when doing a regexp match on tainted data. Here's the
simplest case I can put together​:

\#\!/usr/bin/perl \-w

use strict;

print "The string we're using is '$ENV\{LANG\}'\\n";

while\($ENV\{LANG\} =~ m/\(\.\)/g \) \{
    print "I'm stuck in a loop and I see letter '$1'\\n";
\}

Try running that with taint checking off, and you should see it work
its
way through the letters in the language you're using. Then try it
with
tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

For what it's worth, this caught me in a Real World application where
I
was using a CPAN module (Locale​::Maketext, by Sean Burke) which
exhibited this unusual behaviour when I turned taint checking on.

I've verified this behaviour with perl 5.6.0, 5.6.1 and bleadperl, all
on Debian, and others have demonstrated it on other platforms.

K.

`

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=medium
---
Site configuration information for perl v5.7.2​:

Configured by skud at Wed Jan 16 17​:07​:06 EST 2002.

Summary of my perl5 (revision 5.0 version 7 subversion 2 patch 14304)
configuration​:
Platform​:
osname=linux, osvers=2.4.17, archname=i686-linux
uname='linux tanqueray 2.4.17 #2 smp sun dec 23 14​:01​:48 est 2001
i686 unknown '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef
usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=define
Compiler​:
cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O3',
cppflags='-fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='2.95.4 20011006 (Debian prerelease)',
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define,
longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries​:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=/lib/libc-2.2.4.so, so=so, useshrplib=false,
libperl=libperl.a
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-
rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
DEVEL14289

---
@​INC for perl v5.7.2​:
/home/skud/bleadperl-install/lib/5.7.2/i686-linux
/home/skud/bleadperl-install/lib/5.7.2
/home/skud/bleadperl-install/lib/site_perl/5.7.2/i686-linux
/home/skud/bleadperl-install/lib/site_perl/5.7.2
/home/skud/bleadperl-install/lib/site_perl
/usr/local/share/perl/5.6.1/
tanqueray
~> ls -l /usr/local/lib/perl5/site_perl/5.6.1/
/usr/local/lib/perl5/site_perl/5.6.0//i686-linux
/usr/local/lib/perl5/site_perl/5.6.0/
.

---
Environment for perl v5.7.2​:
HOME=/home/skud
LANG=en
LANGUAGE=en
LC_ALL=en_US
LC_CTYPE=
LD_LIBRARY_PATH=/usr/local/lib​:/home/skud/rvplayer5.0
LOGDIR (unset)
PATH=/usr/local/jre1.3.1_01/bin​:/usr/bin/mh​:/usr/lib/mh​:/usr/local/netscape​:/
usr/local/bin​:/home/skud/rvplayer5.0​:/usr/local/applix​:/usr/X11R6/bin​:/home/skud/
bin​:/usr/games​:/usr/sbin​:/sbin​:/usr/local/jre1.3.1_01/bin​:/usr/bin/mh​:/usr/lib/mh​:/
usr/local/netscape​:/usr/local/bin​:/home/skud/rvplayer5.0​:/usr/local/applix​:/usr/
X11R6/bin​:/home/skud/bin​:/usr/games​:/usr/sbin​:/sbin​:/usr/local/jre1.3.1_01/bin​:/
usr/bin/mh​:/usr/lib/mh​:/usr/local/netscape​:/usr/local/bin​:/home/skud/rvplayer5.0​:/
usr/local/applix​:/usr/X11R6/bin​:/home/skud/bin​:/usr/games​:/usr/sbin​:/sbin​:/usr/
local/bin​:/usr/bin​:/bin​:/usr/bin/X11​:/usr/games
PERL_BADLANG (unset)
SHELL=/usr/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2005

From @smpeters

[skud - Wed Jan 16 13​:03​:13 2002]​:

This is a bug report for perl from skud@​infotrope.net,
generated with the help of perlbug 1.33 running under perl v5.7.2.

-----------------------------------------------------------------
[Please enter your report here]

This is freaky. I've found an odd situation where Perl will go into
an
infinite loop when doing a regexp match on tainted data. Here's the
simplest case I can put together​:

\#\!/usr/bin/perl \-w

use strict;

print "The string we're using is '$ENV\{LANG\}'\\n";

while\($ENV\{LANG\} =~ m/\(\.\)/g \) \{
    print "I'm stuck in a loop and I see letter '$1'\\n";
\}

Try running that with taint checking off, and you should see it work
its
way through the letters in the language you're using. Then try it
with
tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

For what it's worth, this caught me in a Real World application where
I
was using a CPAN module (Locale​::Maketext, by Sean Burke) which
exhibited this unusual behaviour when I turned taint checking on.

I've verified this behaviour with perl 5.6.0, 5.6.1 and bleadperl, all
on Debian, and others have demonstrated it on other platforms.

K.

With Perl-5.8.7, I see...

steve@​kirk​:~/perl-current$ perl rt_8262.pl
The string we're using is 'en_US.UTF-8'
I'm stuck in a loop and I see letter 'e'
I'm stuck in a loop and I see letter 'n'
I'm stuck in a loop and I see letter '_'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'S'
I'm stuck in a loop and I see letter '.'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'T'
I'm stuck in a loop and I see letter 'F'
I'm stuck in a loop and I see letter '-'
I'm stuck in a loop and I see letter '8'
steve@​kirk​:~/perl-current$

Checking a few other recent Perls, it looks like it went away somewhere
prior to 5.8.6.

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2005

@smpeters - Status changed from 'open' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Dec 18, 2005

From laocoon@fastmail.fm

[stmpeters - Sat Dec 17 13​:23​:38 2005]​:

[skud - Wed Jan 16 13​:03​:13 2002]​:
#!/usr/bin/perl -w

use strict;

print "The string we're using is '$ENV\{LANG\}'\\n";

while\($ENV\{LANG\} =~ m/\(\.\)/g \) \{
    print "I'm stuck in a loop and I see letter '$1'\\n";
\}

Try running that with taint checking off, and you should see it work
its
way through the letters in the language you're using. Then try it
with
tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

With Perl-5.8.7, I see...

steve@​kirk​:~/perl-current$ perl rt_8262.pl
The string we're using is 'en_US.UTF-8'
I'm stuck in a loop and I see letter 'e'
I'm stuck in a loop and I see letter 'n'
I'm stuck in a loop and I see letter '_'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'S'
I'm stuck in a loop and I see letter '.'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'T'
I'm stuck in a loop and I see letter 'F'
I'm stuck in a loop and I see letter '-'
I'm stuck in a loop and I see letter '8'
steve@​kirk​:~/perl-current$

Checking a few other recent Perls, it looks like it went away somewhere
prior to 5.8.6.

Please note that this only occurs when running under -T.
Still loops here on 5.8.7 and blead.

1 similar comment
@p5pRT
Copy link
Author

p5pRT commented Dec 18, 2005

From laocoon@fastmail.fm

[stmpeters - Sat Dec 17 13​:23​:38 2005]​:

[skud - Wed Jan 16 13​:03​:13 2002]​:
#!/usr/bin/perl -w

use strict;

print "The string we're using is '$ENV\{LANG\}'\\n";

while\($ENV\{LANG\} =~ m/\(\.\)/g \) \{
    print "I'm stuck in a loop and I see letter '$1'\\n";
\}

Try running that with taint checking off, and you should see it work
its
way through the letters in the language you're using. Then try it
with
tainting on, and it'll get into an infinite loop.

Cool, huh?

There's no mention of this behaviour in perlsec.pod, so I'm figuring
it's a bug.

With Perl-5.8.7, I see...

steve@​kirk​:~/perl-current$ perl rt_8262.pl
The string we're using is 'en_US.UTF-8'
I'm stuck in a loop and I see letter 'e'
I'm stuck in a loop and I see letter 'n'
I'm stuck in a loop and I see letter '_'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'S'
I'm stuck in a loop and I see letter '.'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'T'
I'm stuck in a loop and I see letter 'F'
I'm stuck in a loop and I see letter '-'
I'm stuck in a loop and I see letter '8'
steve@​kirk​:~/perl-current$

Checking a few other recent Perls, it looks like it went away somewhere
prior to 5.8.6.

Please note that this only occurs when running under -T.
Still loops here on 5.8.7 and blead.

@p5pRT
Copy link
Author

p5pRT commented Dec 18, 2005

From @ysth

On Sat, Dec 17, 2005 at 01​:23​:38PM -0800, Steve Peters via RT wrote​:

Try running that with taint checking off, and you should see it work its
way through the letters in the language you're using. Then try it with
tainting on, and it'll get into an infinite loop.

I think you missed this part, Steve.

steve@​kirk​:~/perl-current$ perl rt_8262.pl

  ^ -T

The string we're using is 'en_US.UTF-8'
I'm stuck in a loop and I see letter 'e'
I'm stuck in a loop and I see letter 'n'
I'm stuck in a loop and I see letter '_'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'S'
I'm stuck in a loop and I see letter '.'
I'm stuck in a loop and I see letter 'U'
I'm stuck in a loop and I see letter 'T'
I'm stuck in a loop and I see letter 'F'
I'm stuck in a loop and I see letter '-'
I'm stuck in a loop and I see letter '8'
steve@​kirk​:~/perl-current$

Checking a few other recent Perls, it looks like it went away somewhere
prior to 5.8.6.

I see it failing in 5.8.7 and bleadperl (*with* the -T switch).

@p5pRT
Copy link
Author

p5pRT commented Dec 18, 2005

From BQW10602@nifty.com

On Sun, 18 Dec 2005 02​:02​:34 -0800, Yitzchak Scott-Thoennes <sthoenna@​efn.org> wrote

On Sat, Dec 17, 2005 at 01​:23​:38PM -0800, Steve Peters via RT wrote​:

Try running that with taint checking off, and you should see it work its
way through the letters in the language you're using. Then try it with
tainting on, and it'll get into an infinite loop.

I think you missed this part, Steve.

steve@​kirk​:~/perl-current$ perl rt_8262.pl

                              ^ \-T

I see it failing in 5.8.7 and bleadperl (*with* the -T switch).

Yes, the problem still remains to me, too.
But this problem seems to concern only a certain type of tainted values,
but not all tainted values.

When a value of %ENV is tainted, its copy (for example, $a = $ENV{LANG})
is also tainted; but the copy doesn't cause the infinite loop.

Similarly $ARGV[0] is harmful, while its copy ($a = shift) is harmless.
A copy of <> (for example, $a = <STDIN>) is harmless.

Regards,
SADAHIRO Tomoyuki

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2005

From @petdance

I see it failing in 5.8.7 and bleadperl (*with* the -T switch).

You can also do it on​:

while ( $ENV{LANG} =~ m/./g ) {
  print "I'm stuck in the first loop and I see letter '$&'\n";
}

--
Andy Lester => andy@​petdance.com => www.petdance.com => AIM​:petdance

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2005

From @smpeters

On Sun, Dec 18, 2005 at 11​:11​:05PM -0800, Andy Lester wrote​:

I see it failing in 5.8.7 and bleadperl (*with* the -T switch).

You can also do it on​:

while ( $ENV{LANG} =~ m/./g ) {
print "I'm stuck in the first loop and I see letter '$&'\n";
}

Yes, I did miss the -T. Reopened.

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2005

@smpeters - Status changed from 'resolved' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2005

From mjtg@cam.ac.uk

SADAHIRO Tomoyuki <bqw10602@​nifty.com> wrote

When a value of %ENV is tainted, its copy (for example, $a = $ENV{LANG})
is also tainted; but the copy doesn't cause the infinite loop.

Similarly $ARGV[0] is harmful, while its copy ($a = shift) is harmless.
A copy of <> (for example, $a = <STDIN>) is harmless

So it looks like it's magic which causes the trouble ... presumably
magic+taint is causing pos() to be reset.

Mike Guy

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2005

From @iabyn

On Mon, Dec 19, 2005 at 05​:41​:14PM +0000, Mike Guy wrote​:

SADAHIRO Tomoyuki <bqw10602@​nifty.com> wrote

When a value of %ENV is tainted, its copy (for example, $a = $ENV{LANG})
is also tainted; but the copy doesn't cause the infinite loop.

Similarly $ARGV[0] is harmful, while its copy ($a = shift) is harmless.
A copy of <> (for example, $a = <STDIN>) is harmless

So it looks like it's magic which causes the trouble ... presumably
magic+taint is causing pos() to be reset.

In something like

  $foo[0] =~ /bar/g

the expression on the LHS isn't treated as an lvalue, and it so happens
that various ops (such as aelem) take liberties in this case and return a
mortal *copy* of the element if the element happens to have get magic.

This is a problem with //g, since it wants to modify the LHS by attaching
pos magic to it, buts its axtually attaching the magic to the mortal copy.

The patch below makes the LHS of a //g expression an lvalue, and seems
to fix the problem.

Dave

--
You live and learn (although usually you just live).

Change 26410 by davem@​davem-splatty on 2005/12/19 22​:07​:49

  [perl #8262] //g loops infinitely on tainted data
  make the LHS of expr =~ /foo/g an lvalue, so that any pos magic
  attached to it stays attached.

Affected files ...

... //depot/perl/op.c#732 edit
... //depot/perl/t/op/taint.t#69 edit

Differences ...

==== //depot/perl/op.c#732 (text) ====

@​@​ -1142,8 +1142,9 @​@​
  /* FALL THROUGH */
  default​:
  nomod​:
- /* grep, foreach, subcalls, refgen */
- if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN)
+ /* grep, foreach, subcalls, refgen, m//g */
+ if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN
+ || type == OP_MATCH)
  break;
  yyerror(Perl_form(aTHX_ "Can't modify %s in %s",
  (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL)
@​@​ -1822,9 +1823,14 @​@​
  }
  if (!(right->op_flags & OPf_STACKED) && ismatchop) {
  right->op_flags |= OPf_STACKED;
- if (right->op_type != OP_MATCH &&
- ! (right->op_type == OP_TRANS &&
- right->op_private & OPpTRANS_IDENTICAL))
+ /* s/// and tr/// modify their arg.
+ * m//g also indirectly modifies the arg by setting pos magic on it */
+ if ( (right->op_type == OP_MATCH &&
+ (cPMOPx(right)->op_pmflags & PMf_GLOBAL))
+ || (right->op_type == OP_SUBST)
+ || (right->op_type == OP_TRANS &&
+ ! (right->op_private & OPpTRANS_IDENTICAL))
+ )
  left = mod(left, right->op_type);
  if (right->op_type == OP_TRANS)
  o = newBINOP(OP_NULL, OPf_STACKED, scalar(left), right);

==== //depot/perl/t/op/taint.t#69 (xtext) ====

@​@​ -17,7 +17,7 @​@​
use File​::Spec​::Functions;

BEGIN { require './test.pl'; }
-plan tests => 244;
+plan tests => 245;

$| = 1;
@​@​ -1135,3 +1135,17 @​@​
  eval { local $0, eval '1' };
  test $@​ eq '';
}
+
+# [perl #8262] //g loops infinitely on tainted data
+
+{
+ my @​a;
+ $a[0] = $^X;
+ my $i = 0;
+ while($a[0]=~ m/(.)/g ) {
+ last if $i++ > 10000;
+ }
+ test $i < 10000, "infinite m//g";
+
+}
+

@p5pRT
Copy link
Author

p5pRT commented Mar 23, 2010

From @iabyn

Now fixed by commit fd69380
in branch davem/post-5.12, which should be merged back into blead
once 5.12 has been released, and thus appear in 5.13 onwards.

@p5pRT
Copy link
Author

p5pRT commented Mar 23, 2010

@iabyn - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant