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

foreach variable referenced in format segfaults #6545

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

foreach variable referenced in format segfaults #6545

p5pRT opened this issue May 29, 2003 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented May 29, 2003

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

Searchable as RT22372$

@p5pRT
Copy link
Author

p5pRT commented May 29, 2003

From kjetilho@ifi.uio.no

This is a bug report for perl from kjetilho@​ifi.uio.no,
generated with the help of perlbug 1.34 running under perl v5.8.0.


[Please enter your report here]

this script will dump core on both Solaris and Linux. it works
fine in versions prior to 5.8.0.

format STDOUT =
^<<<<<<<<<<<<<<~~
$el

@p5pRT
Copy link
Author

p5pRT commented May 29, 2003

From @nwc10

On Thu, May 29, 2003 at 08​:40​:19PM -0000, kjetilho@​ifi.uio.no (via RT) wrote​:

# New Ticket Created by kjetilho@​ifi.uio.no
# Please include the string​: [perl #22372]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=22372 >

This is a bug report for perl from kjetilho@​ifi.uio.no,
generated with the help of perlbug 1.34 running under perl v5.8.0.

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

this script will dump core on both Solaris and Linux. it works
fine in versions prior to 5.8.0.

format STDOUT =
^<<<<<<<<<<<<<<~~
$el

D'oh! to perlbug (as you report in bug 22373)
Could you send the example code (with the period) in reply to this,
as your mailer, RT and the rest of perl.org should be well behaved and
get it right.

Thanks,

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented May 29, 2003

From kjetilho@ifi.uio.no

this script will dump core on both Solaris and Linux. it works
fine in versions prior to 5.8.0.

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
<ends>

clearly perlbug doesn't handle reports with solitary periods ...
let's try again. this crashes​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $el (keys %hash) {
  write;
}

this works​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $e (keys %hash) {
  $el = $e;
  write;
}

--
Kjetil T. | read and make up your own mind
  | http​://www.cactus48.com/truth.html

@p5pRT
Copy link
Author

p5pRT commented May 29, 2003

From kjetilho@ifi.uio.no

(I already sent this once, <1rhe7dxz0i.fsf@​vingodur.ifi.uio.no>, not
sure why it didn't show up?)

let's try again. this crashes​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $el (keys %hash) {
  write;
}

this works​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $e (keys %hash) {
  $el = $e;
  write;
}

--
Kjetil T.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2003

From @andk

Kjetil Torgrim Homme <kjetilho@​ifi.uio.no> writes​:

(I already sent this once, <1rhe7dxz0i.fsf@​vingodur.ifi.uio.no>, not
sure why it didn't show up?)

let's try again. this crashes​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el

One workaround against the sendmail problem should be to replace the
"." with a "}". Please verify that the bug you describe persists if
you replace the dot with a bracket and if so, send the modified
bugreport.

The other workaround is, of course, just to indent the whole program
in the mail.

--
andreas

@p5pRT
Copy link
Author

p5pRT commented May 30, 2003

From enache@rdslink.ro

On Fri, May 30, 2003 at 12​:41​:48AM +0200, Kjetil Torgrim Homme wrote​:

let's try again. this crashes​:

format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $el (keys %hash) {
write;
}

Have a look at these snippets from sv_chop()​:

  register STRLEN delta;
...
  SV_CHECK_THINKFIRST(sv);
...
  if (!SvOOK(sv)) {
  if (!SvLEN(sv)) { /* make copy of shared string */
...
  SvGROW(sv, len + 1);
  Move(pvx,SvPVX(sv),len,char);
...
  delta = ptr - SvPVX(sv);
  SvLEN(sv) -= delta;
  SvCUR(sv) -= delta;
  SvPVX(sv) += delta;

Both SV_CHECK_THINKFIRST and SvGROW may reallocate SvPVX(sv) elsewhere;
So the "delta" will be set to some random value - and the consequences
are easy to guess.

Regards,
Adi

Inline Patch
--- /arc/bleadperl/sv.c	2003-05-13 02:03:25.000000000 +0300
+++ ./sv.c	2003-05-30 17:21:22.000000000 +0300
@@ -4501,6 +4501,8 @@ Efficient removal of characters from the
 SvPOK(sv) must be true and the C<ptr> must be a pointer to somewhere inside
 the string buffer.  The C<ptr> becomes the first character of the adjusted
 string. Uses the "OOK hack".
+Beware: after this function returns, C<ptr> and SvPVX(sv) may no longer
+refer to the same chunk of data.
 
 =cut
 */
@@ -4509,9 +4511,9 @@ void
 Perl_sv_chop(pTHX_ register SV *sv, register char *ptr)
 {
     register STRLEN delta;
-
     if (!ptr || !SvPOKp(sv))
 	return;
+    delta = ptr - SvPVX(sv);
     SV_CHECK_THINKFIRST(sv);
     if (SvTYPE(sv) < SVt_PVIV)
 	sv_upgrade(sv,SVt_PVIV);
@@ -4531,7 +4533,6 @@ Perl_sv_chop(pTHX_ register SV *sv, regi
 	SvFLAGS(sv) |= SVf_OOK; 
     }
     SvNIOK_off(sv);
-    delta = ptr - SvPVX(sv);
     SvLEN(sv) -= delta;
     SvCUR(sv) -= delta;
     SvPVX(sv) += delta;
--- /arc/bleadperl/t/op/write.t	2002-04-29 00:31:14.000000000 +0300
+++ ./t/op/write.t	2003-05-30 18:39:45.000000000 +0300
@@ -5,7 +5,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-print "1..47\n";
+print "1..48\n";
 
 my $CAT = ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') ? 'type'
 	: ($^O eq 'MacOS') ? 'catenate'
@@ -271,7 +271,19 @@ if (`$CAT Op_write.tmp` eq $right)
 else
     { print "not ok 11\n"; }
 
-# 12..47: scary format testing from Merijn H. Brand
+{
+    my $el;
+    format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+    my %hash = (12 => 3);
+    for $el (keys %hash) {
+	write;
+    }
+}
+
+# 13..48: scary format testing from Merijn H. Brand
 
 if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'MacOS' ||
     ($^O eq 'os2' and not eval '$OS2::can_fork')) {
@@ -281,7 +293,7 @@ if ($^O eq 'VMS' || $^O eq 'MSWin32' || 
 
 use strict;	# Amazed that this hackery can be made strict ...
 
-my $test = 12;
+my $test = 13;
 
 # Just a complete test for format, including top-, left- and bottom marging
 # and format detection through glob entries

@p5pRT
Copy link
Author

p5pRT commented May 30, 2003

From @iabyn

On Thu, May 29, 2003 at 10​:45​:49PM +0200, Kjetil Torgrim Homme wrote​:

this script will dump core on both Solaris and Linux. it works
fine in versions prior to 5.8.0.
format STDOUT =
^<<<<<<<<<<<<<<~~
$el
.

%hash = ("k" => "v");
for $el (keys %hash) {
write;
}

This is due to keys returning a shared hash string SV, and pp_formline()
directly modifying that value by the use of SvCUR_set() at pp_ctl.c​:798.

That's what the problem is; I don't understand enough about all this
'ere new-fangled shared string and COW malarky to know what the correct
way of fixing this is. Over to Nicolas perhaps?

Dave

--
The optimist believes that he lives in the best of all possible worlds.
As does the pessimist.

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From enache@rdslink.ro

On Sat, May 31, 2003 at 12​:18​:33AM +0100, Dave Mitchell wrote​:

This is due to keys returning a shared hash string SV, and pp_formline()
directly modifying that value by the use of SvCUR_set() at pp_ctl.c​:798.

That's what the problem is; I don't understand enough about all this
'ere new-fangled shared string and COW malarky to know what the correct
way of fixing this is. Over to Nicolas perhaps?

Have a look at my reply/patch to this
http​://nntp.perl.org/group/perl.perl5.porters/76292

The way sv_chop() sometimes builds a OOK-hacked SV from scratch still
makes very little sense to me - the fact that sv_chop() may reallocate
the scalar's buffer is probably a bug.

Regards,
Adi

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From @rgs

Enache Adrian wrote​:

+{
+ my $el;
+ format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+ my %hash = (12 => 3);
+ for $el (keys %hash) {
+ write;
+ }
+}
+
+# 13..48​: scary format testing from Merijn H. Brand

This outputs nothing for me.
Moreover you apparenly forgot to update the skip count a few lines
below :

if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'MacOS' ||
($^O eq 'os2' and not eval '$OS2​::can_fork')) {
...

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From @nwc10

On Sat, May 31, 2003 at 11​:10​:56AM +0200, Rafael Garcia-Suarez wrote​:

Enache Adrian wrote​:

+{
+ my $el;
+ format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+ my %hash = (12 => 3);
+ for $el (keys %hash) {
+ write;
+ }
+}
+
+# 13..48​: scary format testing from Merijn H. Brand

This outputs nothing for me.

I was playing with trying to make a regression test last night
(before I realised that Enache Adrian has already solved the bug)
and I was having trouble making output.

I was thinking that the only reliable way I could think of to make sure
the test made the bug happen was to spawn off a fresh perl.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From enache@rdslink.ro

On Sat, May 31, 2003 at 11​:10​:56AM +0200, Rafael Garcia-Suarez wrote​:

Enache Adrian wrote​:

+{
+ my $el;
+ format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+ my %hash = (12 => 3);
+ for $el (keys %hash) {
+ write;
+ }
+}
This outputs nothing for me.

That's curious, because blead ~ 19600 just worked.
Changing 'my $el' to 'our $el' makes it work again (blead@​19641).

Moreover you apparenly forgot to update the skip count a few lines
below :

Oops.
Modified patch for t/op/write.t below.

Inline Patch
--- /arc/bleadperl/t/op/write.t	2002-04-29 00:31:14.000000000 +0300
+++ ./t/op/write.t	2003-05-31 14:10:11.000000000 +0300
@@ -5,7 +5,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-print "1..47\n";
+print "1..48\n";
 
 my $CAT = ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') ? 'type'
 	: ($^O eq 'MacOS') ? 'catenate'
@@ -271,17 +271,29 @@ if (`$CAT Op_write.tmp` eq $right)
 else
     { print "not ok 11\n"; }
 
-# 12..47: scary format testing from Merijn H. Brand
+{
+    our $el;
+    format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+    my %hash = (12 => 3);
+    for $el (keys %hash) {
+	write;
+    }
+}
+
+# 13..48: scary format testing from Merijn H. Brand
 
 if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'MacOS' ||
     ($^O eq 'os2' and not eval '$OS2::can_fork')) {
-  foreach (12..47) { print "ok $_ # skipped: '|-' and '-|' not supported\n"; }
+  foreach (13..48) { print "ok $_ # skipped: '|-' and '-|' not supported\n"; }
   exit(0);
 }
 
 use strict;	# Amazed that this hackery can be made strict ...
 
-my $test = 12;
+my $test = 13;
 
 # Just a complete test for format, including top-, left- and bottom marging
 # and format detection through glob entries

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From enache@rdslink.ro

On Sat, May 31, 2003 at 02​:18​:11PM +0300, Enache Adrian wrote​:

That's curious, because blead ~ 19600 just worked.
Changing 'my $el' to 'our $el' makes it work again (blead@​19641).

Another example​:
#! perl
my $ebb = 4;
for my $el ($ebb) {
  format STDOUT =
(@​<<<<)
$el
.
  write;
}
__END__

blead@​19582, 5.8.0 : (4 )
blead@​19641 : ( )

Regards,
Adi

@p5pRT
Copy link
Author

p5pRT commented May 31, 2003

From @rgs

Enache Adrian wrote​:

On Sat, May 31, 2003 at 11​:10​:56AM +0200, Rafael Garcia-Suarez wrote​:

Enache Adrian wrote​:

+{
+ my $el;
+ format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze
+$el
+.
+ my %hash = (12 => 3);
+ for $el (keys %hash) {
+ write;
+ }
+}
This outputs nothing for me.

That's curious, because blead ~ 19600 just worked.
Changing 'my $el' to 'our $el' makes it work again (blead@​19641).

Qualifies as a bug. Maybe the jumbo closure patch (19367) is
responsible?
In the meantime, I've applied your updated patch.

Moreover you apparenly forgot to update the skip count a few lines
below :

Oops.
Modified patch for t/op/write.t below.

--- /arc/bleadperl/t/op/write.t 2002-04-29 00​:31​:14.000000000 +0300
+++ ./t/op/write.t 2003-05-31 14​:10​:11.000000000 +0300
@​@​ -5,7 +5,7 @​@​ BEGIN {
@​INC = '../lib';
}

-print "1..47\n";
+print "1..48\n";

my $CAT = ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') ? 'type'
: ($^O eq 'MacOS') ? 'catenate'
@​@​ -271,17 +271,29 @​@​ if (`$CAT Op_write.tmp` eq $right)
else
{ print "not ok 11\n"; }

-# 12..47​: scary format testing from Merijn H. Brand
+{
+ our $el;
+ format STDOUT =
+ok ^<<<<<<<<<<<<<<~~ # sv_chop() naze

"naze" really sounds like french slang, doesn't it ?

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2003

@rspier - Status changed from 'new' 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