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

Modifying an alias to a read-only item of an argument list of a subroutine works, while it's expected to fail #6453

Closed
p5pRT opened this issue Apr 16, 2003 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 16, 2003

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

Searchable as RT21979$

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2003

From trivizki@bigfoot.com

This is a bug report for perl from trivizki@​bigfoot.com,
generated with the help of perlbug 1.34 running under perl v5.8.0.

sub subname{
*_=\$_[0];
s///;
}
subname("string");

Runs with no errors and even modifies $_, although it should not run, as it tries to modify
An alias to (an alias to) a read only value.
Actually, the above should give exactly the same error message the code below gives​:

sub subname{
$_[0]=~s///;
}
subname("string");

"Modification of a read-only value attempted" as the codes should act the same - $_ is just an
alias to $_[0].

Perl 5.6.1 behaved as I expected, while 5.8 did run the code on my system as well as
on a friend's who's running a *nix based system(Mandrake).

Thanks,
Ido


Flags​:
  category=core
  severity=low


Site configuration information for perl v5.8.0​:

Configured by ActiveState at Tue Feb 4 18​:07​:44 2003.

Summary of my perl5 (revision 5 version 8 subversion 0) configuration​:
  Platform​:
  osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
  uname=''
  config_args='undef'
  hint=recommended, useposix=true, d_sigaction=undef
  usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define
  useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
  use64bitint=undef use64bitall=undef uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cl', ccflags ='-nologo -Gf -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX',
  optimize='-MD -Zi -DNDEBUG -O1',
  cppflags='-DWIN32'
  ccversion='', gccversion='', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='link', ldflags ='-nologo -nodefaultlib -debug -opt​:ref,icf -libpath​:"C​:\Perl\lib\CORE" -machine​:x86'
  libpth="C​:\Perl\lib\CORE"
  libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
  perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
  libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
  gnulibc_version='undef'
  Dynamic Linking​:
  dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt​:ref,icf -libpath​:"C​:\Perl\lib\CORE" -machine​:x86'

Locally applied patches​:
  ACTIVEPERL_LOCAL_PATCHES_ENTRY


@​INC for perl v5.8.0​:
  C​:/Perl/lib
  C​:/Perl/site/lib
  .


Environment for perl v5.8.0​:
  HOME (unset)
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=C​:\Program Files\Borland\Delphi7\Bin;C​:\Program Files\Borland\Delphi7\Projects\Bpl\;C​:\WINDOWS\system32;C​:\WINDOWS;C​:\WINDOWS\System32\Wbem;C​:\Program Files\Common Files\Ulead Systems\MPEG;C​:\Perl\bin
  PERL_BADLANG (unset)
  SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Apr 17, 2003

From enache@rdslink.ro

On Wed, Apr 16, 2003 at 10​:05​:55PM -0000, trivizki@​bigfoot.com (via RT) wrote​:

sub subname{
*_=\$_[0];
s///;
}
subname("string");

Runs with no errors and even modifies $_, although it should not run, as it tries to modify
An alias to (an alias to) a read only value.

$ perl -e 'sub a { ${\$_[0]} = 5 } a "a"'
$

With ithreads constants are now copied on the pad - see op.c​:6088, so
they have their SVf_PADTMP flag on.

So the code in S_refto with take this path when creating a reference

  else if (SvPADTMP(sv) && !IS_PADGV(sv))
  sv = newSVsv(sv);

and the SVf_READONLY flag will be lost.
Is this a feature ? all this seems rather messy and inefficient - and
I don't feel that adding another test in S_refto is the right thing
to do.

Regards
Adi

@p5pRT
Copy link
Author

p5pRT commented Apr 17, 2003

From sky@nanisky.com

On torsdag, apr 17, 2003, at 16​:39 Europe/Stockholm, Enache Adrian
wrote​:

On Wed, Apr 16, 2003 at 10​:05​:55PM -0000, trivizki@​bigfoot.com (via
RT) wrote​:

sub subname{
*_=\$_[0];
s///;
}
subname("string");

Runs with no errors and even modifies $_, although it should not run,
as it tries to modify
An alias to (an alias to) a read only value.

$ perl -e 'sub a { ${\$_[0]} = 5 } a "a"'
$

With ithreads constants are now copied on the pad - see op.c​:6088, so
they have their SVf_PADTMP flag on.

So the code in S_refto with take this path when creating a reference

else if \(SvPADTMP\(sv\) && \!IS\_PADGV\(sv\)\)
    sv = newSVsv\(sv\);

and the SVf_READONLY flag will be lost.
Is this a feature ? all this seems rather messy and inefficient - and
I don't feel that adding another test in S_refto is the right thing
to do.

Regards
Adi

Try running it in non threaded perl and see what it does, it should
do the same thing!

Arthur

@p5pRT
Copy link
Author

p5pRT commented Apr 18, 2003

From enache@rdslink.ro

On Thu, Apr 17, 2003 at 08​:24​:51PM +0200, Arthur Bergman wrote​:

On torsdag, apr 17, 2003, at 16​:39 Europe/Stockholm, Enache Adrian
wrote​:

$ perl -e 'sub a { ${\$_[0]} = 5 } a "a"'
$

With ithreads constants are now copied on the pad - see op.c​:6088, so
they have their SVf_PADTMP flag on.

So the code in S_refto with take this path when creating a reference

else if (SvPADTMP(sv) && !IS_PADGV(sv))
sv = newSVsv(sv);

and the SVf_READONLY flag will be lost.
Is this a feature ? all this seems rather messy and inefficient - and
I don't feel that adding another test in S_refto is the right thing
to do.

Regards
Adi

Try running it in non threaded perl and see what it does, it should
do the same thing!

Are you sure ?

$ ./perl -e 'sub a { ${\$_[0]} = 5 } a "a"'
Modification of a read-only value attempted at -e line 1.
$ ./perl -Ilib -V
Summary of my perl5 (revision 5.0 version 9 subversion 0 patch 19254) configuration​:
  Platform​:
  osname=linux, osvers=2.4.18-14, archname=i686-linux-stdio
  uname='linux ratsnest.hole 2.4.18-14 #1 wed sep 4 12​:13​:11 edt 2002 i686 athlon i386 gnulinux '
  config_args=''
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=undef useithreads=undef usemultiplicity=undef
  useperlio=undef d_sfio=undef uselargefiles=undef usesocks=undef
  use64bitint=undef use64bitall=undef uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
[..]

Regards
Adi

@p5pRT
Copy link
Author

p5pRT commented Apr 19, 2003

From sky@nanisky.com

On fredag, apr 18, 2003, at 03​:21 Europe/Stockholm, Enache Adrian wrote​:

Try running it in non threaded perl and see what it does, it should
do the same thing!

Are you sure ?

$ ./perl -e 'sub a { ${\$_[0]} = 5 } a "a"'
Modification of a read-only value attempted at -e line 1.

Yes I am sure, if it does one thing in non threaded perl, threaded perl
should do the same!

So this is a bug in the threads code.

Arthur

@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2005

From @ysth

Created by @ysth

  perl -we'use Devel​::Peek; sub {Dump $_[0]}->("Foo")'

shows $_[0] having the PADTMP and PADBUSY flags under threaded perl
but not threaded perl. This triggers the PADTMP case in pp.c​:S_refto
which makes \$_[0] generate a ref to a copy to the constant instead
of to the constant itself.

As a result, this​:

  perl -wle'sub { print ${\$_[0]} .= "bar" }->("foo")'

erroneously prints foobar with a threaded perl but correctly gives
"Modification of a read-only value attempted" with an unthreaded perl.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.7:

Configured by gerrit at Mon Aug 22 21:57:25     2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=cygwin, osvers=1.5.18(0.13242), archname=cygwin-thread-multi-64int
    uname='cygwin_nt-5.1 inspiron 1.5.18(0.13242) 2005-07-02 20:30 i686 unknown unknown cygwin '
    config_args='-de -Dmksymlinks -Duse64bitint -Dusethreads -Uusemymalloc -Doptimize=-O3 -Dman3ext=3pm -Dusesitecustomize'
    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=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing -pipe -I/usr/local/include',
    optimize='-O3',
    cppflags='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='3.4.4 (cygming special) (gdc 0.12, using dmd 0.125)', 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='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='ld2', ldflags =' -s -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib /lib
    libs=-lgdbm -ldb -lcrypt -lgdbm_compat
    perllibs=-lcrypt -lgdbm_compat
    libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' -s'
    cccdlflags=' ', lddlflags=' -s -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.7:
    /usr/lib/perl5/5.8/cygwin
    /usr/lib/perl5/5.8
    /usr/lib/perl5/site_perl/5.8/cygwin
    /usr/lib/perl5/site_perl/5.8
    /usr/lib/perl5/site_perl/5.8
    /usr/lib/perl5/vendor_perl/5.8/cygwin
    /usr/lib/perl5/vendor_perl/5.8
    /usr/lib/perl5/vendor_perl/5.8
    .


Environment for perl v5.8.7:
    CYGWIN=tty ntsec title server
    HOME=/home/sthoenna
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/bin:/cygdrive/c/Perl5.6/bin/:/cygdrive/c/Perl/bin/:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/Common Files/Adaptec Shared/System:/usr/bin:/usr/lib/lapack
    PERL_BADLANG (unset)
    SHELL (unset)


@p5pRT
Copy link
Author

p5pRT commented Jan 6, 2012

From @dk

I'd like to reopen this old bug as I've hit it in my own code... I've no
idea how to fix it properly, but at least before that is decided either
way, I believe issuing a warning gives some idea that there's undefined
behavior​:

Inline Patch
--- pp.c.0    2012-01-06 01:07:34.511988700 +0100
+++ pp.c    2012-01-06 19:04:06.311428300 +0100
@@ -515,9 +515,11 @@
     SvTEMP_off(sv);
     SvREFCNT_inc_void_NN(sv);
     }
-    else if (SvPADTMP(sv) && !IS_PADGV(sv))
+    else if (SvPADTMP(sv) && !IS_PADGV(sv)) {
+        Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
+         "Implicit copy of a read-only scalar due to aliasing");
         sv = newSVsv(sv);
-    else {
+    } else {
     SvTEMP_off(sv);
     SvREFCNT_inc_void_NN(sv);
     }

@p5pRT
Copy link
Author

p5pRT commented Jun 30, 2013

From @cpansprout

On Tue Oct 11 17​:09​:58 2005, ysth wrote​:

This is a bug report for perl from sthoenna@​efn.org,
generated with the help of perlbug 1.35 running under perl v5.8.7.

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

perl -we'use Devel​::Peek; sub {Dump $_[0]}->("Foo")'

shows $_[0] having the PADTMP and PADBUSY flags under threaded perl
but not threaded perl. This triggers the PADTMP case in pp.c​:S_refto
which makes \$_[0] generate a ref to a copy to the constant instead
of to the constant itself.

As a result, this​:

perl -wle'sub { print ${\$_[0]} .= "bar" }->("foo")'

erroneously prints foobar with a threaded perl but correctly gives
"Modification of a read-only value attempted" with an unthreaded perl.

This is a duplicate of #21979.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 30, 2013

From [Unknown Contact. See original ticket]

On Tue Oct 11 17​:09​:58 2005, ysth wrote​:

This is a bug report for perl from sthoenna@​efn.org,
generated with the help of perlbug 1.35 running under perl v5.8.7.

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

perl -we'use Devel​::Peek; sub {Dump $_[0]}->("Foo")'

shows $_[0] having the PADTMP and PADBUSY flags under threaded perl
but not threaded perl. This triggers the PADTMP case in pp.c​:S_refto
which makes \$_[0] generate a ref to a copy to the constant instead
of to the constant itself.

As a result, this​:

perl -wle'sub { print ${\$_[0]} .= "bar" }->("foo")'

erroneously prints foobar with a threaded perl but correctly gives
"Modification of a read-only value attempted" with an unthreaded perl.

This is a duplicate of #21979.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 30, 2013

@cpansprout - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2013

From @cpansprout

Fixed in 82b84d0.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2013

From [Unknown Contact. See original ticket]

Fixed in 82b84d0.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2013

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

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

No branches or pull requests

1 participant