Skip Menu |

This queue is for tickets about the XML-Smart CPAN distribution.

Report information
The Basics
Id: 122986
Status: open
Priority: 0/
Queue: XML-Smart

People
Owner: Nobody in particular
Requestors: bitcard93445 [...] rainslide.net
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.78
  • 1.79
Fixed in: (no value)



Subject: Warnings disabled
After this call, warnings are left disabled: my $xml = XML::Smart->new(q`<?xml version="1.0" encoding="iso-8859-1" ?> <root> <foo arg="abc">ABC</foo> <foo arg="xyz">XYZ</foo> </root> `); warn "About to foo"; my $foo = $xml->{root}{foo}('arg', 'eq', 'xyz'); warn "This doesn't get warned";
From: george.quinlan [...] gmail.com
On Thu Sep 07 18:11:43 2017, fgssfgs wrote: Show quoted text
> After this call, warnings are left disabled: > > my $xml = XML::Smart->new(q`<?xml version="1.0" encoding="iso-8859-1" ?> > <root> > <foo arg="abc">ABC</foo> > <foo arg="xyz">XYZ</foo> > </root> > `); > > warn "About to foo"; > my $foo = $xml->{root}{foo}('arg', 'eq', 'xyz'); > warn "This doesn't get warned";
I have this same bug. I am running version 1.77 of XML::Smart. I've looked at the latest version, 1.79, and the bug is there too. The bug is in the find_args() method in XML::Smart. ############ # FIND_ARG # ############ sub find_arg { my $this = shift ; ...[snip]... foreach my $search_i ( @search ) { my ($name , $type , $value) = @{$search_i} ; $type =~ s/\s//gs ; $i++ ; my $hash ; if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;} else { $hash = $hash_i ;} my $data ; if ($name =~ /^content$/i) { $name = 'CONTENT' ;} $data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ; $data = $$data{CONTENT} if ref($data) eq 'HASH' ; _unset_sig_warn() ; if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} _reset_sig_warn() ; } You can see the call to _unset_sig_warn() just before the bunch of if tests: if none of the tests succeeds _reset_sig_warn() is called to restore the previous sig_warn behaviour. However, if one of the tests succeeds, _reset_sig_warn() is never called because the for loop is exited via the last instruction. I've corrected this in my local installation by rewriting the code as below: foreach my $hash_i ( @hashes ) { foreach my $search_i ( @search ) { my ($name , $type , $value) = @{$search_i} ; $type =~ s/\s//gs ; $i++ ; my $hash ; if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;} else { $hash = $hash_i ;} my $data ; if ($name =~ /^content$/i) { $name = 'CONTENT' ;} $data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ; $data = $$data{CONTENT} if ref($data) eq 'HASH' ; _unset_sig_warn() ; my $last; if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;} _reset_sig_warn() ; last if ($last); } With this fix the second warn message in your test example is displayed.