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

s/// flags influence regex use in the replacement body #6542

Closed
p5pRT opened this issue May 29, 2003 · 13 comments
Closed

s/// flags influence regex use in the replacement body #6542

p5pRT opened this issue May 29, 2003 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented May 29, 2003

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

Searchable as RT22354$

@p5pRT
Copy link
Author

p5pRT commented May 29, 2003

From perl-5.8.0@ton.iguana.be

Created by perl-5.8.0@ton.iguana.be

This code​:
  perl -wle '
sub fun {
  $a = shift;
  print "fun(<$a>)";
  print "unexpectdly matched $& at position @​-" if /^de/
}
$_ = "ab\nde";
s/^([\w\W]*)/fun("$1")/e'

outputs (as expected)​:
fun(<ab
de>)

However, this​:

  perl -wle '
sub fun {
  $a = shift;
  print "fun(<$a>)";
  print "unexpectdly matched $& at position @​-" if /^de/
}
$_ = "ab\nde";
s/^([\w\W]*)/fun("$1")/em'

outputs​:

fun(<ab
de>)
unexpectdly matched de at position 3

The only difference is the m modifier on the s///
I didn't expect the "non-reentrant" regex problems here. Until now I
though the replacement part of a s/// was safe.

Speculation​:
It seems that m modifier propagates to the regex that's used in fun() which
gets called from the body.
Presumably one or more modifiers need localizing.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.8.0:

Configured by ton at Tue Nov 12 01:56:18 CET 2002.

Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.4.19, archname=i686-linux-thread-multi-64int-ld
    uname='linux quasar 2.4.19 #5 wed oct 2 02:34:25 cest 2002 i686 unknown '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=define
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -fomit-frame-pointer',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.3 20010315 (release)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='long double', nvsize=12, 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 -lndbm -ldb -ldl -lm -lpthread -lc -lposix -lcrypt -lutil
    perllibs=-lnsl -ldl -lm -lpthread -lc -lposix -lcrypt -lutil
    libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.4'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.0:
    /usr/lib/perl5/5.8.0/i686-linux-thread-multi-64int-ld
    /usr/lib/perl5/5.8.0
    /usr/lib/perl5/site_perl/5.8.0/i686-linux-thread-multi-64int-ld
    /usr/lib/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl
    .


Environment for perl v5.8.0:
    HOME=/home/ton
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/ton/bin.Linux:/home/ton/bin:/home/ton/bin.SampleSetup:/usr/local/bin:/usr/local/sbin:/usr/local/jre/bin:/home/oracle/product/9.0.1/bin:/usr/local/ar/bin:/usr/games/bin:/usr/X11R6/bin:/usr/share/bin:/usr/bin:/usr/sbin:/bin:/sbin:.
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

From @rgs

"perl-5.8.0@​ton.iguana.be (via RT)" wrote​:

This code​:
perl -wle '
sub fun {
$a = shift;
print "fun(<$a>)";
print "unexpectdly matched $& at position @​-" if /^de/
}
$_ = "ab\nde";
s/^([\w\W]*)/fun("$1")/e'

outputs (as expected)​:
fun(<ab
de>)

However, this​:

perl \-wle '

sub fun {
$a = shift;
print "fun(<$a>)";
print "unexpectdly matched $& at position @​-" if /^de/
}
$_ = "ab\nde";
s/^([\w\W]*)/fun("$1")/em'

outputs​:

fun(<ab
de>)
unexpectdly matched de at position 3

The only difference is the m modifier on the s///
I didn't expect the "non-reentrant" regex problems here. Until now I
though the replacement part of a s/// was safe.

Speculation​:
It seems that m modifier propagates to the regex that's used in fun() which
gets called from the body.
Presumably one or more modifiers need localizing.

Yes. Good catch. Setting /m on a match or on a substitution is
equivalent to setting the global special variable $* to 1 (locally).
Thus, it will influence the behaviour of all regexps that haven't /m or
/s set in that scope.

The interaction with $*, and the fact that $* can have remote effects,
makes this bug difficult to solve.

A first step would be to make $* lexically scoped (a compile-time hint,
à la $[). Or to get rid of it.

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

From perl5-porters@ton.iguana.be

In article <20030603155453.4004_58e.rgarciasuarez@​_ree._r>,
  Rafael Garcia-Suarez <rgarciasuarez@​free.fr> writes​:

Yes. Good catch. Setting /m on a match or on a substitution is
equivalent to setting the global special variable $* to 1 (locally).
Thus, it will influence the behaviour of all regexps that haven't /m or
/s set in that scope.

That makes things even weirder​:

perl -wle '
sub fun {
  $a = shift;
  print "\$* is undef" if !defined($*);
  local $* = undef;
  print "fun(<$a>)";
  print "unexpectdly matched $& at position @​-" if /^de/
}
$_ = "ab\nde";
s/^([\w\W]*)/fun("$1")/em'

gives​:

Use of $* is deprecated at -e line 4.
$* is undef
Use of uninitialized value in scalar assignment at -e line 5.
fun(<ab
de>)

So setting $* to undef (or 0) indeed solves it.
However, the test before the local shows that $* actually
already was undef !. But removing the local makes it fail again.
Urgh !

The interaction with $*, and the fact that $* can have remote effects,
makes this bug difficult to solve.

A first step would be to make $* lexically scoped (a compile-time hint,
à la $[). Or to get rid of it.

Making $* lexically scoped probably already breaks pograms that still
depend on it. So kill it, I'd say. It has been documented as deprecated
for a long time, and gives a deprecation warning in actual code.
Now it's also clear it causes bugs in real code.
(nope, this wasn't a golf thing :-) )
--
seen in rec.arts.sf.written​: "Perl Harbor" was the C-port for Awk-land, NZ

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

From @rgs

perl5-porters@​ton.iguana.be (Ton Hospel) wrote​:

So setting $* to undef (or 0) indeed solves it.
However, the test before the local shows that $* actually
already was undef !. But removing the local makes it fail again.

That's normal, because reading the value of $* at this point doesn't
give the value of the internal PL_multiline variable, which was == 1.

Making $* lexically scoped probably already breaks pograms that still
depend on it. So kill it, I'd say. It has been documented as deprecated
for a long time, and gives a deprecation warning in actual code.

I like this idea.

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

From @rgs

Ton Hospel wrote​:

Making $* lexically scoped probably already breaks pograms that still
depend on it. So kill it, I'd say. It has been documented as deprecated
for a long time, and gives a deprecation warning in actual code.
Now it's also clear it causes bugs in real code.

I've verified that removing $* solves this bug (and breaks nothing
else in the core.) The most important point of the patch is pasted
below.

But I've a question :
As of 5.8.x, $* gives a deprecation warning :

  $ perl -we '$*=1'
  Use of $* is deprecated at -e line 1.

When removing a deprecated feature, should the deprecation
warning be removed as well ?

--- pp_hot.c (revision 1474)
+++ pp_hot.c (working copy)
@​@​ -1234,7 +1234,7 @​@​
  if (SvSCREAM(TARG))
  r_flags |= REXEC_SCREAM;

- if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
+ if ((pm->op_pmflags & PMf_MULTILINE) != PL_multiline) {
  SAVEINT(PL_multiline);
  PL_multiline = pm->op_pmflags & PMf_MULTILINE;
  }
@​@​ -1979,7 +1979,7 @​@​
  ? REXEC_COPY_STR : 0;
  if (SvSCREAM(TARG))
  r_flags |= REXEC_SCREAM;
- if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
+ if ((pm->op_pmflags & PMf_MULTILINE) != PL_multiline) {
  SAVEINT(PL_multiline);
  PL_multiline = pm->op_pmflags & PMf_MULTILINE;
  }

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

From @ap

* Rafael Garcia-Suarez <rgarciasuarez@​free.fr> [2003-06-04 22​:00]​:

When removing a deprecated feature, should the deprecation
warning be removed as well ?

Sounds to me like it would be more sensible to change it to
"Use of $* is no longer supported" or some such.

--
Regards,
Aristotle

@p5pRT
Copy link
Author

p5pRT commented Jun 10, 2003

From @floatingatoll

From​: Rafael Garcia-Suarez <rgarciasuarez@​free.fr>
  on​: Wed, 4 Jun 2003 23​:58​:55 +0200
M-id​: <20030604235855.4fd7bc15.rgarciasuarez@​free.fr>

$ perl -we '$*=1'
Use of $* is deprecated at -e line 1.

When removing a deprecated feature, should the deprecation
warning be removed as well ?

I submit that it should be retained for one release cycle following the
removal of the feature; in the same sense that warning is given ahead of
time, warning is also given when things are broken, for a time. Also,
people who weren't seeing the warnings still have a chance to see the
warning when their stuff breaks.

- R.

@p5pRT
Copy link
Author

p5pRT commented Jun 14, 2003

From guest@guest.guest.xxxxxxxx

Resolved by removing $* in perl 5.9.0.

@p5pRT
Copy link
Author

p5pRT commented Jun 14, 2003

@rgs - Status changed from 'new' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Jun 15, 2003

From whatever@davidnicol.com

When removing a deprecated feature, should the deprecation
warning be removed as well ?

I submit that ....

I submit that the error message should refer to a document
explaining the alternative approach, for instance

  $* is now an error​: see perdoc perlvar

--
David Nicol, independent consultant and contractor
  Howard Dean?

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2003

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

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2003

From @Abigail

On Sat, Jun 14, 2003 at 11​:45​:51PM -0500, david nicol wrote​:

When removing a deprecated feature, should the deprecation
warning be removed as well ?

I submit that ....

I submit that the error message should refer to a document
explaining the alternative approach, for instance

$\* is now an error&#8203;: see perdoc perlvar

Well, you can't make '$*' an error. The variable won't disappear -
it's the associated magic that disappears.

Abigail

@p5pRT p5pRT closed this as completed Jul 7, 2003
@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2003

@rgs - 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