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

Re: [perl #50256] segfault on perl -e 'split //, unpack "(B)*", "ab"'

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
February 5, 2008 17:01
Subject:
Re: [perl #50256] segfault on perl -e 'split //, unpack "(B)*", "ab"'
Message ID:
20080206010119.GR38653@plum.flirble.org
On Sat, Jan 26, 2008 at 05:27:05AM +0000, var Arnfjr Bjarmason wrote:
> This looks to my untrained eye like something unpack is causing its
> return value to be a damaged PMOP.
> 
>     $ ./perl -le 'split //, unpack("(B)*", "ab")'
>     Segmentation fault
>     $ ./perl -le 'my $s = unpack("(B)*", "ab"); split //, $s'
>     $ ./perl -le 'my $s = unpack("(B)*", "ab"); unpack "(a)*", $s'
>     $ ./perl -le 'unpack "(a)*", unpack("(B)*", "ab");'
>     Invalid type '0' in unpack at -e line 1.

To save duplication, it turned out to be stack issue, as explained in

http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-02/msg00178.html

How many bonus items do you want on the stack in scalar context?

$ perl -Ds -e 'scalar unpack("(B)*", "ab")'

EXECUTING...

    =>  
    =>  
    =>  
    =>  PV("(B)*"\0)  
    =>  PV("(B)*"\0)  PV("ab"\0)  
    =>  PV("0"\0)  PV("0"\0)  
$ perl -Ds -e 'scalar unpack("(B)*", "abc")'

EXECUTING...

    =>  
    =>  
    =>  
    =>  PV("(B)*"\0)  
    =>  PV("(B)*"\0)  PV("abc"\0)  
    =>  PV("0"\0)  PV("0"\0)  PV("0"\0)  
$ perl -Ds -e 'scalar unpack("(B)*", "abcd")'

EXECUTING...

    =>  
    =>  
    =>  
    =>  PV("(B)*"\0)  
    =>  PV("(B)*"\0)  PV("abcd"\0)  
    =>  PV("0"\0)  PV("0"\0)  PV("0"\0)  PV("0"\0)  


Basically () constructions in scalar context were broken, but it seems that
most ops don't notice. Fixed in change 33239

Nicholas Clark

Change 33239 by nicholas@nicholas-bouvard on 2008/02/06 01:00:43

	in unpack, () groups in scalar context were still returning a list,
	resulting in garbage on the stack, which could manifest as a SEGV
	(Bug 50256)

Affected files ...

... //depot/perl/pp_pack.c#141 edit
... //depot/perl/t/op/pack.t#115 edit

Differences ...

==== //depot/perl/pp_pack.c#141 (text) ====

@@ -1258,6 +1258,7 @@
 	    symptr->previous = &savsym;
             symptr->level++;
 	    PUTBACK;
+	    if (len && unpack_only_one) len = 1;
 	    while (len--) {
   	        symptr->patptr = savsym.grpbeg;
 		if (utf8) symptr->flags |=  FLAG_PARSE_UTF8;

==== //depot/perl/t/op/pack.t#115 (xtext) ====

@@ -12,7 +12,7 @@
 my $no_signedness = $] > 5.009 ? '' :
   "Signed/unsigned pack modifiers not available on this perl";
 
-plan tests => 14696;
+plan tests => 14697;
 
 use strict;
 use warnings qw(FATAL all);
@@ -1980,3 +1980,8 @@
     is(unpack('@!4 a*', "\x{301}\x{302}\x{303}\x{304}\x{305}"),
        "\x{303}\x{304}\x{305}", 'Test basic utf8 @!');
 }
+{
+    #50256
+    my ($v) = split //, unpack ('(B)*', 'ab');
+    is($v, 0); # Doesn't SEGV :-)
+}

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