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

[perl #132833] COW bug in :encoding layer

Thread Previous
From:
Tony Cook via RT
Date:
February 12, 2018 07:11
Subject:
[perl #132833] COW bug in :encoding layer
Message ID:
rt-4.0.24-2705-1518419486-136.132833-15-0@perl.org
On Thu, 08 Feb 2018 12:16:59 -0800, pali@cpan.org wrote:
> Following code modifies variable $valid:
> 
> use strict;
> use warnings;
> use Data::Dumper;
> 
> my $valid = "\x61\x00\x00\x00";
> my $tmp = $valid;
> print Dumper $valid;
> open my $fh, '<:encoding(UTF32-LE)', \$tmp or die;
> my $str = <$fh>;
> close $fh;
> print Dumper $valid;
> 
> Output is:
> 
> $VAR1 = 'a';
> $VAR1 = '';
> 
> This is perl 5, version 24, subversion 1 (v5.24.1) built for x86_64-
> linux-gnu-thread-multi

This appears to be a bug in Unicode::decode() - it's modifying a buffer that doesn't belong to it (SvLEN() for the SV is zero).

Adding a call to SvGROW() fixes it:

diff --git a/cpan/Encode/Unicode/Unicode.xs b/cpan/Encode/Unicode/Unicode.xs
index b3b1d2fea8..2a5c647625 100644
--- a/cpan/Encode/Unicode/Unicode.xs
+++ b/cpan/Encode/Unicode/Unicode.xs
@@ -328,6 +328,7 @@ CODE:
        }
     }
     if (check && !(check & ENCODE_LEAVE_SRC)) {
+        SvGROW(str, 1+e-s);
        if (s < e) {
            Move(s,SvPVX(str),e-s,U8);
            SvCUR_set(str,(e-s));

Replacing that block with a call to sv_chop() instead would also fix it, except for what I think is a bug in PerlIO::encoding:

	    /* Create a "dummy" SV to represent the available data from layer below */
	    if (SvLEN(e->dataSV) && SvPVX_const(e->dataSV)) {
		Safefree(SvPVX_mutable(e->dataSV));
	    }

since SvPVX(sv) might not point to the beginning of the allocated block with an SvOOK() SV.

Tony


---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=132833

Thread Previous


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