Skip Menu |

This queue is for tickets about the SOAP-Lite CPAN distribution.

Report information
The Basics
Id: 68088
Status: resolved
Priority: 0/
Queue: SOAP-Lite

People
Owner: Nobody in particular
Requestors: matt.lawrence [...] virgin.net
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.712
Fixed in: (no value)



Subject: XML::Parser::Lite fails tests under perl 5.14 RC1
I got the following error when testing under perl 5.14: Can't use string ("1") as an ARRAY ref while "strict refs" in use at (re_eval 11) line 1. The attached patch (to tests) makes the error go away, but I'm not sure that there isn't a bug here. $^R was set to the return value of $handler_of{End} when processing the second opening <foo> tag, which is 1 for the push statement (the number of items pushed onto the list), so the expression @{$^R||[]} caused this error.
Subject: soap_lite.diff
--- t/XML/Parser/Lite.t +++ t/XML/Parser/Lite.t @@ -24,7 +24,7 @@ Final => sub { push @final_from, 1; }, Char => sub { push @text_from, $_[1]; }, Start => sub { push @start_from, $_[1]; }, - End => sub { push @end_from, $_[1]; }, + End => sub { push @end_from, $_[1]; return }, ); $parser->setHandlers( Final => undef, ); $parser->setHandlers( %handler_of );
The error was probably caused by a bugfix in 5.14 which caused pragmata to be inherited by evals in regular expressions. Previously strict mode would not have been in effect. See under: http://perldoc.perl.org/perl5140delta.html#Regular-Expression-Bug-Fixes Cheers, Matt On Tue May 10 12:39:46 2011, MATTLAW wrote: Show quoted text
> I got the following error when testing under perl 5.14: > > Can't use string ("1") as an ARRAY ref while "strict refs" in use at > (re_eval 11) line 1. > > The attached patch (to tests) makes the error go away, but I'm not sure > that there isn't a bug here. > > $^R was set to the return value of $handler_of{End} when processing the > second opening <foo> tag, which is 1 for the push statement (the number > of items pushed onto the list), so the expression @{$^R||[]} caused this > error.
From: maas.frank [...] gmail.com
On Mon 16 Mei 2011 11:02:27, MATTLAW wrote: Show quoted text
> The error was probably caused by a bugfix in 5.14 which caused pragmata > to be inherited by evals in regular expressions. Previously strict mode > would not have been in effect.
You're right. Your patch does patch the test-script, but it does not solve the problem ;-). XML::Parser::Lite allows (for some undocumented reason) that the handlers return an arrayref which is used in the regexp. The test script is in accordance with the documentation and does not return an arrayref. Worse: it does not explicitly return anything, so the result of the last statement is returned. This results in code like @{1} which perl < 5.14.0 erroneously would allow in regexp, but starting 5.14.0 it won't anymore. I've created a patch that patches XML/Parser/Lite.pm in such a way that the subs that are used in the regexp will always return an empty arrayref, unless the handler function returns its own arrayref. There is one caveat: I have no idea what the Char handler should return (if anything), so I've made it always to return an empty arrayref (look at the code and you'll see what I mean, I hope). Hope this helps someone - it helped me ;-) Regards, Frank
Subject: XML_Parser_Lite.diff
--- Lite.pm.org 2011-06-01 12:52:02.000000000 +0200 +++ Lite.pm 2011-06-01 12:51:10.000000000 +0200 @@ -167,7 +167,8 @@ sub _start { die "multiple roots, wrong element '$_[0]'\n" if $level++ && !@stack; push(@stack, $_[0]); - Start(__PACKAGE__, @_); + my $r=Start(__PACKAGE__, @_); + ref($r) eq 'ARRAY' ? $r : undef; } sub _char { @@ -181,30 +182,36 @@ die "junk '$_[0]' @{[$level ? 'after' : 'before']} XML element\n" if index("\n\r\t ", substr($_[0],$i,1)) < 0; # or should '< $[' be there } + # not sure about this... + return []; } sub _end { no warnings qw(uninitialized); pop(@stack) eq $_[0] or die "mismatched tag '$_[0]'\n"; - my $x=End(__PACKAGE__, $_[0]); - $x; + my $r=End(__PACKAGE__, $_[0]); + ref($r) eq 'ARRAY' ? $r : undef; } sub comment { - Comment(__PACKAGE__, $_[0]); + my $r=Comment(__PACKAGE__, $_[0]); + ref($r) eq 'ARRAY' ? $r : undef; } sub end { - pop(@stack) eq $_[0] or die "mismatched tag '$_[0]'\n"; - End(__PACKAGE__, $_[0]); - } + pop(@stack) eq $_[0] or die "mismatched tag '$_[0]'\n"; + my $r=End(__PACKAGE__, $_[0]); + ref($r) eq 'ARRAY' ? $r : undef; +} sub _doctype { - Doctype(__PACKAGE__, $_[0]); + my $r=Doctype(__PACKAGE__, $_[0]); + ref($r) eq 'ARRAY' ? $r : undef; } sub _xmldecl { - XMLDecl(__PACKAGE__, $_[0]); + my $r=XMLDecl(__PACKAGE__, $_[0]); + ref($r) eq 'ARRAY' ? $r : undef; }
RT-Send-CC: maas.frank [...] gmail.com
Char(__PACKAGE__, $_[0]), return if @stack;
RT-Send-CC: maas.frank [...] gmail.com
Oops.. Previous reply got mangled :-/ On Wed Jun 01 07:12:57 2011, FrankM wrote: Show quoted text
> On Mon 16 Mei 2011 11:02:27, MATTLAW wrote:
> > The error was probably caused by a bugfix in 5.14 which caused pragmata > > to be inherited by evals in regular expressions. Previously strict mode > > would not have been in effect.
> > You're right. Your patch does patch the test-script, but it does not > solve the problem ;-).
Your patch definitely looks like a more plausible fix than mine ;-) Show quoted text
> > I've created a patch that patches XML/Parser/Lite.pm in such a way that > the subs that are used in the regexp will always return an empty > arrayref, unless the handler function returns its own arrayref. There is > one caveat: I have no idea what the Char handler should return (if > anything), so I've made it always to return an empty arrayref (look at > the code and you'll see what I mean, I hope). >
The original _char method returns nothing as long as an element has been seen, even after the patch. The important thing is that the Char() handler's return value is never used, so afaict there's no need to patch that method. sub _char { Char(__PACKAGE__, $_[0]), return if @stack;
From: maas.frank [...] gmail.com
On Wed 01 Jun 2011 09:52:03, MATTLAW wrote: Show quoted text
> The original _char method returns nothing as long as an element has been > seen, > even after the patch. The important thing is that the Char() handler's > return > value is never used, so afaict there's no need to patch that method. > > sub _char { > Char(__PACKAGE__, $_[0]), return if @stack; >
In my version it goes on after this with: for (my $i=0; $i < length $_[0]; $i++) { die "junk '$_[0]' @{[$level ? 'after' : 'before']} XML element\n" if index("\n\r\t ", substr($_[0],$i,1)) < 0; # or should '< $[' be there } That is reached when '@stack' is empty. I am uncertain as to what this returns, which is primarily due to the fact that I don't really understand that last bit of code (why it's an if). Since ::_char is used in the REGEXP I found it better to safely return an [] at the end... Frank
Subject: Re: [rt.cpan.org #68088] XML::Parser::Lite fails tests under perl 5.14 RC1
Date: Fri, 03 Jun 2011 17:38:34 +0100
To: bug-SOAP-Lite [...] rt.cpan.org
From: Matt Lawrence <matt.lawrence [...] virgin.net>
On 03/06/11 13:20, Frank M. via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=68088> > > On Wed 01 Jun 2011 09:52:03, MATTLAW wrote:
>> The original _char method returns nothing as long as an element has been >> seen, >> even after the patch. The important thing is that the Char() handler's >> return >> value is never used, so afaict there's no need to patch that method. >> >> sub _char { >> Char(__PACKAGE__, $_[0]), return if @stack; >>
> In my version it goes on after this with: > > for (my $i=0; $i< length $_[0]; $i++) { > die "junk '$_[0]' @{[$level ? 'after' : 'before']} XML element\n" > if index("\n\r\t ", substr($_[0],$i,1))< 0; # or should '< $[' > be there > } > > That is reached when '@stack' is empty. I am uncertain as to what this > returns, which is primarily due to the fact that I don't really > understand that last bit of code (why it's an if). Since ::_char is used > in the REGEXP I found it better to safely return an [] at the end... >
@stack will only be empty at the very beginning and at the very end of the document. This loop is checking for non-spaces in those areas. When the last thing in a subroutine is a loop, it's equivalent to a bare "return" so it's safe anyway because false values can't cause the bug. As I mentioned above this handler differs from the others in that the return value of the internal _char handler can *never* be that of the user-configured Char() handler, so there is no possible configuration of the object that can cause the bug. Matt
I've just had the same problem installing version 0.712 under 5.14.1. When will it be fixed and a new version released to CPAN?
fixed in SVN in rev #376 Thanks for reporting & the patch, Martin
fixed in >= 0.713