develooper Front page | perl.perl5.porters | Postings from February 2003

Re: [perl #20933] \substr reuses lvalues (sometimes)

Thread Previous | Thread Next
From:
Slaven Rezic
Date:
February 14, 2003 04:19
Subject:
Re: [perl #20933] \substr reuses lvalues (sometimes)
Message ID:
871y2bi05q.fsf@vran.herceg.de
"Joshua b.Jore (via RT)" <perlbug-followup@perl.org> writes:

> # New Ticket Created by  Joshua b. Jore 
> # Please include the string:  [perl #20933]
> # in the subject line of all future correspondence about this issue. 
> # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=20933 >
> 
> 
> This is a bug report for perl from josh@lavendergreens.org,
> generated with the help of perlbug 1.33 running under perl v5.6.1.
> 
> 
> -----------------------------------------------------------------
> [Please enter your report here]
> 
> The following code prints "abbb" when it should be "abab". BrowserUK
> of perlmonks.org clued me into this error.
> 
> $s = "ab";
> $r[0] = \ substr $s, 0, 1;
> $r[1] = \ substr $s, 1, 1;
> print ${ $r[0] };
> print ${ $r[1] };
> 
> $r[$_] = \ substr $s, $_, 1 for (0, 1);
> print ${ $r[0] };
> print ${ $r[1] };
> 

The patch below fixes the problem. The fix is not very elegant,
though.

--- bleedperl/pp.c	Sun Feb  2 18:59:19 2003
+++ bleedperl2/pp.c	Fri Feb 14 11:13:40 2003
@@ -476,6 +476,17 @@ S_refto(pTHX_ SV *sv)
     }
     else if (SvPADTMP(sv) && !IS_PADGV(sv))
         sv = newSVsv(sv);
+    else if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'x') {
+	/* [perl #20933] */
+	SV* new_sv = newSVsv(sv);
+	sv_upgrade(new_sv, SVt_PVLV);
+	sv_magic(new_sv, Nullsv, PERL_MAGIC_substr, Nullch, 0);
+	LvTYPE(new_sv) = 'x';
+	LvTARG(new_sv) = SvREFCNT_inc(LvTARG(sv));
+	LvTARGOFF(new_sv) = LvTARGOFF(sv);
+	LvTARGLEN(new_sv) = LvTARGLEN(sv);
+	sv = new_sv;
+    }
     else {
 	SvTEMP_off(sv);
 	(void)SvREFCNT_inc(sv);
--- bleedperl/t/op/substr.t	Wed Mar 21 02:18:37 2001
+++ bleedperl2/t/op/substr.t	Fri Feb 14 09:53:01 2003
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..174\n";
+print "1..175\n";
 
 #P = start of string  Q = start of substr  R = end of substr  S = end of string
 
@@ -585,3 +585,10 @@ ok 173, $x eq "\xFFb\x{100}\x{200}";
 substr($x = "\x{100}\x{200}", 2, 0, "\xFFb");
 ok 174, $x eq "\x{100}\x{200}\xFFb";
 
+# [perl #20933]
+{
+  my $s = "ab";
+  my @r;
+  $r[$_] = \ substr $s, $_, 1 for (0, 1);
+  ok 175, join("", map { $$_ } @r) eq "ab";
+}


> [Please do not change anything below this line]
> -----------------------------------------------------------------
> ---
> Flags:
>     category=core
>     severity=low
> ---
> Site configuration information for perl v5.6.1:
> 
> Configured by root at Mon Feb  3 03:46:05 CST 2003.
> 
> Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
>   Platform:
>     osname=openbsd, osvers=3.2, archname=i386-openbsd
>     uname='openbsd'
>     config_args='-Dopenbsd_distribution=defined -dsE'
>     hint=recommended, useposix=true, d_sigaction=define
>     usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
>     useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
>     use64bitint=undef use64bitall=undef uselongdouble=undef
>   Compiler:
>     cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include',
>     optimize='-O2',
>     cppflags='-fno-strict-aliasing -I/usr/local/include'
>     ccversion='', gccversion='2.95.3 20010125 (prerelease)', gccosandvers='openbsd3.2'
>     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, usemymalloc=n, prototype=define
>   Linker and Libraries:
>     ld='cc', ldflags =''
>     libpth=/usr/lib
>     libs=-lm -lc -lutil
>     perllibs=-lm -lc -lutil
>     libc=/usr/lib/libc.so.28.5, so=so, useshrplib=true, libperl=libperl.so.6.1
>   Dynamic Linking:
>     dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=define, ccdlflags='-Wl,-R/usr/libdata/perl5/i386-openbsd/5.6.1/CORE'
>     cccdlflags='-DPIC -fPIC ', lddlflags='-shared -fPIC '
> 
> Locally applied patches:
> 
> 
> ---
> @INC for perl v5.6.1:
>     /usr/libdata/perl5/i386-openbsd/5.6.1
>     /usr/local/libdata/perl5/i386-openbsd/5.6.1
>     /usr/libdata/perl5
>     /usr/local/libdata/perl5
>     /usr/local/libdata/perl5/site_perl/i386-openbsd
>     /usr/libdata/perl5/site_perl/i386-openbsd
>     /usr/local/libdata/perl5/site_perl
>     /usr/libdata/perl5/site_perl
>     /usr/local/lib/perl5/site_perl
>     .
> 
> ---
> Environment for perl v5.6.1:
>     HOME=/home/josh
>     LANG (unset)
>     LANGUAGE (unset)
>     LD_LIBRARY_PATH (unset)
>     LOGDIR (unset)
>     PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
>     PERL_BADLANG (unset)
>     SHELL=/bin/ksh
> 
> 
> 

-- 
Slaven Rezic - slaven@rezic.de

    tktimex - project time manager
    http://sourceforge.net/projects/ptktools/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About