Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-XML-Twig for openSUSE:Factory checked in at 2026-10-03 20:13:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-XML-Twig (Old) and /work/SRC/openSUSE:Factory/.perl-XML-Twig.new.1631729 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-XML-Twig" Sat Oct 3 20:13:14 2026 rev:39 rq:1381962 version:3.550.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-XML-Twig/perl-XML-Twig.changes 2025-06-14 16:17:21.789361078 +0200 +++ /work/SRC/openSUSE:Factory/.perl-XML-Twig.new.1631729/perl-XML-Twig.changes 2026-10-03 20:13:21.872177741 +0200 @@ -1,0 +2,13 @@ +Thu Oct 1 11:44:27 UTC 2026 - Tina Müller <[email protected]> + +- updated to 3.550.0 (3.55) + see /usr/share/doc/packages/perl-XML-Twig/Changes + + 3.55 2026-10-01 minor maintenance release + - added Scalar::Util as a dependency + - improved some tests + - minor bug fixes + see https://github.com/mirod/xmltwig/issues/47 bsc#1282902 + see https://github.com/mirod/xmltwig/issues/46 + +------------------------------------------------------------------- Old: ---- XML-Twig-3.54.tar.gz New: ---- README.md XML-Twig-3.55.tar.gz _scmsync.obsinfo build.specials.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-XML-Twig.spec ++++++ --- /var/tmp/diff_new_pack.FrmmrM/_old 2026-10-03 20:13:22.974223884 +0200 +++ /var/tmp/diff_new_pack.FrmmrM/_new 2026-10-03 20:13:22.976223968 +0200 @@ -1,7 +1,7 @@ # # spec file for package perl-XML-Twig # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,15 +18,16 @@ %define cpan_name XML-Twig Name: perl-XML-Twig -Version: 3.540.0 +Version: 3.550.0 Release: 0 -# 3.54 -> normalize -> 3.540.0 -%define cpan_version 3.54 +# 3.55 -> normalize -> 3.550.0 +%define cpan_version 3.55 License: Artistic-1.0 OR GPL-1.0-or-later Summary: XML, The Perl Way URL: https://metacpan.org/release/%{cpan_name} Source0: https://cpan.metacpan.org/authors/id/M/MI/MIROD/%{cpan_name}-%{cpan_version}.tar.gz Source1: cpanspec.yml +Source100: README.md Patch0: perl-XML-Twig-CVE-2016-9180.patch BuildArch: noarch BuildRequires: perl @@ -39,7 +40,7 @@ Provides: perl(XML::Twig::Entity_list) Provides: perl(XML::Twig::Notation) Provides: perl(XML::Twig::Notation_list) -Provides: perl(XML::Twig::XPath) +Provides: perl(XML::Twig::XPath) = 0.20.0 Provides: perl(XML::Twig::XPath::Attribute) Provides: perl(XML::Twig::XPath::Elt) Provides: perl(XML::Twig::XPath::Namespace) ++++++ README.md ++++++ ## Build Results Current state of perl in openSUSE:Factory is  The current state of perl in the devel project build (devel:languages:perl)  ++++++ XML-Twig-3.54.tar.gz -> XML-Twig-3.55.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/Changes new/XML-Twig-3.55/Changes --- old/XML-Twig-3.54/Changes 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/Changes 2026-10-01 09:47:21.000000000 +0200 @@ -1,5 +1,15 @@ CHANGES +3.55 2026-10-01 minor maintenance release + +- added Scalar::Util as a dependency + +- improved some tests + +- minor bug fixes + see https://github.com/mirod/xmltwig/issues/47 + see https://github.com/mirod/xmltwig/issues/46 + 3.54 2025-06-11 minor maintenance release - changed the minimum version of Perl to 5.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/META.json new/XML-Twig-3.55/META.json --- old/XML-Twig-3.54/META.json 2025-06-11 10:06:45.000000000 +0200 +++ new/XML-Twig-3.55/META.json 2026-10-01 09:48:39.000000000 +0200 @@ -42,6 +42,6 @@ "url" : "http://github.com/mirod/xmltwig" } }, - "version" : "3.54", + "version" : "3.55", "x_serialization_backend" : "JSON::PP version 4.16" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/META.yml new/XML-Twig-3.55/META.yml --- old/XML-Twig-3.54/META.yml 2025-06-11 10:06:45.000000000 +0200 +++ new/XML-Twig-3.55/META.yml 2026-10-01 09:48:39.000000000 +0200 @@ -21,5 +21,5 @@ XML::Parser: '2.23' resources: repository: http://github.com/mirod/xmltwig -version: '3.54' +version: '3.55' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/Makefile.PL new/XML-Twig-3.55/Makefile.PL --- old/XML-Twig-3.54/Makefile.PL 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/Makefile.PL 2025-06-11 16:25:25.000000000 +0200 @@ -151,7 +151,7 @@ sub slurp { my( $file)= @_; my $in; - open( $in, "<$file") or return ''; + open( $in, '<', $file) or return ''; local undef $/; return <$in>; } @@ -159,6 +159,6 @@ sub spit { my $file= shift; my $out; - open( $out, ">$file") or ( warn "cannot update $file: $!" && return); + open( $out, '>', $file) or ( warn "cannot update $file: $!" && return); print {$out} @_; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/lib/XML/Twig.pm new/XML-Twig-3.55/lib/XML/Twig.pm --- old/XML-Twig-3.54/lib/XML/Twig.pm 2025-06-11 10:06:07.000000000 +0200 +++ new/XML-Twig-3.55/lib/XML/Twig.pm 2026-10-01 09:38:55.000000000 +0200 @@ -1,6 +1,7 @@ use strict; use warnings; + # This is created in the caller's space # I realize (now!) that it's not clean, but it's been there for 10+ years... BEGIN @@ -23,6 +24,8 @@ require 5.010; use utf8; +use Scalar::Util qw(weaken looks_like_number); +use List::Util qw(first); use vars qw($VERSION @ISA %valid_option); @@ -34,9 +37,6 @@ *isa= *UNIVERSAL::isa; -# flag, set to true if the weaken sub is available -use vars qw( $weakrefs); - # flag set to true if the version of expat seems to be 1.95.2, which has annoying bugs # wrt doctype handling. This is global for performance reasons. my $expat_1_95_2=0; @@ -141,9 +141,10 @@ my $SEP= qr/\s*(?:$|\|)/; +my $DEBUG_HANDLER; BEGIN { -$VERSION = '3.54'; +$VERSION = '3.55'; use XML::Parser; my $needVersion = '2.23'; @@ -156,18 +157,6 @@ $FB_XMLCREF = 0x0400; # Encode::FB_XMLCREF; $FB_HTMLCREF = 0x0200; # Encode::FB_HTMLCREF; -# test whether we can use weak references -# set local empty signal handler to trap error messages -{ local $SIG{__DIE__}; - ## no critic (ProhibitStringyEval) - if( eval( 'require Scalar::Util') && defined( \&Scalar::Util::weaken)) - { import Scalar::Util( 'weaken'); $weakrefs= 1; } - elsif( eval( 'require WeakRef')) - { import WeakRef; $weakrefs= 1; } - else - { $weakrefs= 0; } -} - # used to store the gi's # should be set for each twig really, at least when there are several # the init ensures that special gi's are always the same @@ -732,7 +721,7 @@ $self->{twig_autoflush}= 1; # auto flush by default $self->{twig}= $self; - if( $weakrefs) { weaken( $self->{twig}); } + weaken( $self->{twig}); return $self; } @@ -1581,7 +1570,7 @@ { return 0; } } -my $DEBUG_HANDLER= 0; # 0 or 1 (output the handler checking code) or 2 (super verbose) +$DEBUG_HANDLER= 0; # 0 or 1 (output the handler checking code) or 2 (super verbose) my $handler_string; # store the handler itself sub _set_debug_handler { $DEBUG_HANDLER= shift; } sub _warn_debug_handler { if( $DEBUG_HANDLER < 3) { warn @_; } else { $handler_string .= join( '', @_); } } @@ -1753,66 +1742,91 @@ # the score sub _parse_predicate_in_handler { my( $flag, $score)= @_[1..2]; - $_[0]=~ s{( ($REG_STRING) # quoted string - |($REG_REGEXP) # regexp - |\@($REG_TAG_NAME)(\s* $REG_MATCH \s* $REG_REGEXP) # @att and regexp - |\@($REG_TAG_NAME)(?=\s*(?:[><=!])) # @att followed by a comparison operator - |\@($REG_TAG_NAME) # @att (not followed by a comparison operator) - |=~|!~ # matching operators - |([><]=?|=|!=)(?=\s*[\d+-]) # test before a number - |([><]=?|=|!=) # test, other cases - |($REG_FUNCTION) # no arg functions + $_[0]=~ s{(?<token> + (?<tstr>$REG_STRING) # quoted string + |(?<tregexp>$REG_REGEXP) # regexp + |(?<tatt_re>\@(?<att>$REG_TAG_NAME) \s* (?<op>$REG_MATCH) \s* (?<re>$REG_REGEXP)) # @att and regexp + |(?<tatt_num>\@(?<att>$REG_TAG_NAME) \s* (?<op>$REG_COMP) \s* (?<nb>$REG_NUMBER)) # @att then comparison operator then number + |(?<tatt_op>\@(?<att>$REG_TAG_NAME)(?=\s*(?:[><=!]))) # @att followed by a comparison operator + |(?<tbare_att>\@(?<att>$REG_TAG_NAME)) # @att (not followed by a comparison operator) + |=~|!~ # matching operators + |(?<tbare_num_test>[><]=?|=|!=)(?=\s*[\d+-]) # test before a number + |(?<tbare_test>[><]=?|=|!=) # test, other cases # this bit is a mess, but it is the only solution with this half-baked parser - |(string\(\s*$REG_NAME?\s*\)\s*$REG_MATCH\s*$REG_REGEXP) # string( child)=~ /regexp/ or string()=~ /regexp/ - |(string\(\s*$REG_NAME\s*\)\s*$REG_COMP\s*$REG_STRING) # string( child) = "value" (or other test) - |(string\(\s*$REG_NAME\s*\)\s*$REG_COMP\s*$REG_NUMBER) # string( child) = nb (or other test) - |(\band\b|\bor\b) - # |($REG_NAME(?=\s*(and|or|$))) # nested tag name (needs to be after all other unquoted strings) - |($REG_TAG_IN_PREDICATE) # nested tag name (needs to be after all other unquoted strings) + |(?<tstr_re>string\(\s*(?<tag>$REG_NAME?)\s*\)\s*(?<op>$REG_MATCH)\s*(?<re>$REG_REGEXP)) # string( child) =~ /regexp/ or string()=~ /regexp/ + |(?<tstr_str>string\(\s*(?<tag>$REG_NAME?)\s*\)\s*(?<op>$REG_COMP)\s*(?<string>$REG_STRING)) # string( child) = "value" (or other test) + |(?<tstr_num>string\(\s*(?<tag>$REG_NAME?)\s*\)\s*(?<op>$REG_COMP)\s*(?<nb>$REG_NUMBER)) # string( child) = nb (or other test) + |(?<tfunc>$REG_FUNCTION) # no arg functions + |(?<tand_or>\band\b|\bor\b) + |(?<tntag>$REG_TAG_IN_PREDICATE) # nested tag name (needs to be after all other unquoted strings) )} - { my( $token, $str, $regexp, $att_re_name, $att_re_regexp, $att, $bare_att, $num_test, $alpha_test, $func, $str_regexp, $str_test_alpha, $str_test_num, $and_or, $tag) - = ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15); - + { $score->{predicates}++; + my %m = %+; # save the matches, so further regexps don't overwrite it # store tests on text (they are not always allowed) - if( $func || $str_regexp || $str_test_num || $str_test_alpha ) { $flag->{test_on_text}= 1; } + if( $m{tfunc} || $m{tstr_re} || $m{tstr_num} || $m{tstr_str} ) { $flag->{test_on_text}= 1; } - if( defined $str) { _safe_string( $token) } - elsif( defined $regexp){ _safe_regexp( $token) } - elsif( $tag) { qq{(\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->has_child( '$tag'))} } - elsif( $att) { $att=~ m{^#} ? qq{ (\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->{att}->{'$att'})} - : qq{\$elt->{'$att'}} - } - elsif( $att_re_name) { $att_re_name=~ m{^#} ? qq{ (\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->{att}->{'$att_re_name'}$att_re_regexp)} - : qq{\$elt->{'$att_re_name'}$att_re_regexp} - } - # for some reason Devel::Cover flags the following lines as not tested. They are though. - elsif( $bare_att) { $bare_att=~ m{^#} ? qq{(\$elt->{'$ST_ELT'} && defined(\$elt->{'$ST_ELT'}->{att}->{'$bare_att'}))} - : qq{defined( \$elt->{'$bare_att'})} - } - elsif( $num_test && ($num_test eq '=') ) { "==" } # others tests are unchanged - elsif( $alpha_test) { $PERL_ALPHA_TEST{$alpha_test} } - elsif( $func && $func=~ m{^string}) - { "\$elt->{'$ST_ELT'}->text"; } - elsif( $str_regexp && $str_regexp =~ m{string\(\s*($REG_TAG_NAME)?\s*\)\s*($REG_MATCH)\s*($REG_REGEXP)}) - { my( $rtag, $rmatch, $rregexp)= ($1, $2, _safe_regexp( $3)); - if( $1) { "defined( _first_n { \$_->text $rmatch $rregexp } 1, \$elt->{'$ST_ELT'}->_children( '$rtag'))" } - else { "\$elt->text $rmatch $rregexp" } - } - elsif( $str_test_alpha && $str_test_alpha =~ m{string\(\s*($REG_TAG_NAME)\s*\)\s*($REG_COMP)\s*($REG_STRING)}) - { my( $tag, $op, $str)= ($1, $2, _safe_string($3)); - $str=~ s{(?<=.)'(?=.)}{\\'}g; # escape a quote within the string - $str=~ s{^"}{'}; - $str=~ s{"$}{'}; - "defined( _first_n { \$_->text $PERL_ALPHA_TEST{$op} $str } 1, \$elt->{'$ST_ELT'}->children( '$tag'))"; } - elsif( $str_test_num && $str_test_num =~ m{string\(\s*($REG_TAG_NAME)\s*\)\s*($REG_COMP)\s*($REG_NUMBER)}) - { my $test= ($2 eq '=') ? '==' : $2; - "defined( _first_n { \$_->text $test $3 } 1, \$elt->{'$ST_ELT'}->children( '$1'))"; - } - elsif( $and_or) { $score->{tests}++; $and_or eq 'and' ? '&&' : '||' ; } - else { $token; } + my $token = $m{token}; + if( defined $m{tstr} ) { _safe_string( $token) } + elsif( defined $m{tregexp} ){ _safe_regexp( $token) } + elsif( $m{tntag} ) { qq{(\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->has_child( '$m{tntag}'))} } + elsif( $m{tatt_op} ) { _att_is_private($m{att}) + ? qq{ (\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->{att}->{'$m{att}'})} + : qq{\$elt->{'$m{att}'}} + } + elsif( $m{tatt_re} ) { _att_is_private($m{att}) + ? qq{ (\$elt->{'$ST_ELT'} && \$elt->{'$ST_ELT'}->{att}->{'$m{att}'} $m{op} $m{re})} + : qq{\$elt->{'$m{att}'} $m{op} $m{re}} + } + elsif( $m{tatt_num} ) { my $op = $m{op} eq '=' ? '==' : $m{op}; + # the context stack stores private atts, set in an other handler + my $context_stack = qq{\$elt\->{'$ST_ELT'}}; + # look for private atts in the context stack, other atts in the plain parse result + my $att_location = _att_is_private($m{att}) ? qq{$context_stack\->{att}} : qq{\$elt}; + my $att= ${att_location} . qq{->{'$m{att}'}}; + my @tests; + # for private atts, check existence of the context stack so we don't autovivify it + push @tests, $context_stack if _att_is_private($m{att}); + # the base test + push @tests, qq{$att $op $m{nb}}; + join ' && ', @tests; + } + # for some reason Devel::Cover flags the following lines as not tested. They are though. + elsif( $m{tbare_att} ) { _att_is_private($m{att}) + ? qq{(\$elt->{'$ST_ELT'} && defined(\$elt->{'$ST_ELT'}->{att}->{'$m{att}'}))} + : qq{defined( \$elt->{'$m{att}'})} + } + elsif( $m{tbare_num_test }&& ($m{tbare_num_test} eq '=') ) + { "==" } # others tests are unchanged + elsif( $m{tbare_test} ) { $PERL_ALPHA_TEST{$m{tbare_test}} } + elsif( $m{tfunc}&& $m{tfunc}=~ m{^string} ) + { "\$elt->{'$ST_ELT'}->text"; } + elsif( $m{tstr_re} ) { my $tag = $m{tag} // ''; + my $op = $m{op}; + my( $regexp)= _safe_regexp( $m{re}); + if( $m{tag} ) { "defined( first { \$_->text $m{op} $regexp } \$elt->{'$ST_ELT'}->_children( '$m{tag}'))" } + else { "\$elt->{'$ST_ELT'}->text $m{op} $regexp" } + } + elsif( $m{tstr_str} ) { my $tag = $m{tag}; + my $op= $PERL_ALPHA_TEST{$m{op}}; + my $str= substr( $m{string}, 1, -1 ); # remove quotes + $str= _safe_string($str); + $str=~ s{(?<=.)'(?=.)}{\\'}g; # escape a quote within the string + $str= qq{'$str'}; + if ( $tag ) { "defined( first { \$_->text $op $str } \$elt->{'$ST_ELT'}->children( '$tag'))"; } + else { "\$elt->{'$ST_ELT'}->text $op $str"; } + } + elsif( $m{tstr_num } ) { $m{tag }//= ''; + my $op = $m{op} eq '=' ? '==' : $m{op}; + if ( $m{tag} ) + { "defined( first { (\$_->text $op $m{nb}) } \$elt->{'$ST_ELT'}->children( '$m{tag}'))"; } + else + { "\$elt->{'$ST_ELT'}->text $op $m{nb}" } + } + elsif( $m{tand_or} ) { $score->{tests}++; $m{tand_or} eq 'and' ? '&&' : '||' ; } + else { $token; } }gexs; } @@ -1828,6 +1842,12 @@ return $regexp; } +# no regexp in there so we can still use %+ in the following code +sub _att_is_private { + my ($att) = @_; + return substr( $att, 0, 1 ) eq '#'; +} + sub setCharHandler { my( $t, $handler)= @_; $t->{twig_char_handler}= $handler; @@ -1946,7 +1966,7 @@ $t->{twig_parsing}=1; $t->{twig_parser}= $p; - if( $weakrefs) { weaken( $t->{twig_parser}); } + weaken( $t->{twig_parser}); # in case they had been created by a previous parse delete $t->{twig_dtd}; @@ -2066,7 +2086,7 @@ # now we can store the tag and atts my $context= { $ST_TAG => $gi, $ST_ELT => $elt, @att}; $context->{$ST_NS}= $ns_decl if $ns_decl; - if( $weakrefs) { weaken( $context->{$ST_ELT}); } + weaken( $context->{$ST_ELT}); push @{$t->{_twig_context_stack}}, $context; $parent->del_twig_current if( $parent); @@ -2110,7 +2130,7 @@ my $id= $elt->id; if( defined $id) { $t->{twig_id_list}->{$id}= $elt; - if( $weakrefs) { weaken( $t->{twig_id_list}->{$id}); } + weaken( $t->{twig_id_list}->{$id}); } # call user handler if need be @@ -2266,7 +2286,7 @@ $t->{twig_root}= $elt; if( $elt) { $elt->{twig}= $t; - if( $weakrefs) { weaken( $elt->{twig}); } + weaken( $elt->{twig}); } return $t; } @@ -4658,9 +4678,6 @@ sub getParentNode { return undef; } sub getChildNodes { my @children= ($_[0]->root); return wantarray ? @children : \@children; } -sub _weakrefs { return $weakrefs; } -sub _set_weakrefs { $weakrefs=shift() || 0; XML::Twig::Elt::set_destroy()if ! $weakrefs; } # for testing purposes - sub _dump { my $t= shift; my $dump=''; @@ -4998,6 +5015,9 @@ ###################################################################### use Carp; +use Scalar::Util qw(weaken looks_like_number); +use List::Util qw(first); + *isa= *UNIVERSAL::isa; my $CDATA_START = "<![CDATA["; @@ -5077,15 +5097,6 @@ *getFirstChild = *_first_child; *getLastChild = *_last_child; - # try using weak references - # test whether we can use weak references - { local $SIG{__DIE__}; - ## no critic (ProhibitStringyEval) - if( eval 'require Scalar::Util' && defined( &Scalar::Util::weaken) ) - { import Scalar::Util qw(weaken); } - elsif( eval 'require WeakRef') - { import WeakRef; } - } } # can be called as XML::Twig::Elt->new( [[$gi, $atts, [@content]]) @@ -5844,37 +5855,54 @@ $cond=~ s{^\s*\[\s*}{}; $cond=~ s{\s*\]\s*$}{}; - $cond=~ s{( ($REG_STRING|$REG_REGEXP) # strings or regexps - |\@($REG_TAG_NAME)(?=\s*(?:[><=!]|!~|=~)) # @att (followed by a comparison operator) - |\@($REG_TAG_NAME) # @att (not followed by a comparison operator) - |=~|!~ # matching operators - |([><]=?|=|!=)(?=\s*[\d+-]) # test before a number - |([><]=?|=|!=) # test, other cases - |($REG_FUNCTION) # no arg functions + $cond=~ s{(?<token> + (?<tstr>$REG_STRING|$REG_REGEXP) # strings or regexps + |\@(?<tatt>$REG_TAG_NAME)(?=\s*(?:[><=!]|!~|=~)) # @att (followed by a comparison operator) + |\@(?<tbare_att>$REG_TAG_NAME) # @att (not followed by a comparison operator) + |=~|!~ # matching operators + |(?<tbare_num_test>[><]=?|=|!=)(?=\s*[\d+-]) # test before a number + |(?<tbare_test>[><]=?|=|!=) # test, other cases # this bit is a mess, but it is the only solution with this half-baked parser - |((?:string|text)\(\s*$REG_TAG_NAME\s*\)\s*$REG_MATCH\s*$REG_REGEXP) # string( child) =~ /regexp/ - |((?:string|text)\(\s*$REG_TAG_NAME\s*\)\s*!?=\s*$REG_VALUE) # string( child) = "value" (or !=) - |((?:string|text)\(\s*$REG_TAG_NAME\s*\)\s*[<>]=?\s*$REG_VALUE) # string( child) > "value" - |(and|or) + |(?<tstr_re>(?:string|text)\(\s*(?<tag>$REG_TAG_NAME?)\s*\)\s*(?<op>$REG_MATCH)\s*(?<re>$REG_REGEXP)) # string(child) =~ /regexp/ + |(?<tstr_num>(?:string|text)\(\s*(?<tag>$REG_NAME?)\s*\)\s*(?<op>$REG_COMP)\s*(?<nb>$REG_NUMBER)) # string(child) = nb (or other test) + |(?<tstr_str>(?:string|text)\(\s*(?<tag>$REG_TAG_NAME?)\s*\)\s*(?<op>!?=)\s*(?<string>$REG_STRING)) # string(child) = "value" (or !=) + |(?<tstring_test>(?:string|text)\(\s*(?<tag>$REG_TAG_NAME)\s*\)\s*(?<op>[<>]=?)\s*(?<string>$REG_STRING)) # string(child) > "value" + |(?<tfunc>$REG_FUNCTION) # no arg functions + |(?<tand_or>and|or) )} - { my( $token, $string, $att, $bare_att, $num_test, $alpha_test, $func, $string_regexp, $string_eq, $string_test, $and_or) - = ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11); - - if( defined $string) { $token } - elsif( $att) { "( \$_[0]->{att} && exists( \$_[0]->{att}->{'$att'}) && \$_[0]->{att}->{'$att'})"; } - elsif( $bare_att) { "(\$_[0]->{att} && defined( \$_[0]->{att}->{'$bare_att'}))"; } - elsif( $num_test && ($num_test eq '=') ) { "==" } # others tests are unchanged - elsif( $alpha_test) { $PERL_ALPHA_TEST{$alpha_test} } - elsif( $func && $func=~ m{^(?:string|text)}) + { + my %m = %+; # save the named captures so further regexp do not overwrite them + if( defined $m{tstr} ) { $m{token} } + elsif( $m{tatteq0} ) { "( \$_[0]->{att} && exists( \$_[0]->{att}->{'$m{tatteq0}'}) \$_[0]->{att}->{'$m{tatteq0}'})"; } + elsif( $m{tatt} ) { "( \$_[0]->{att} && exists( \$_[0]->{att}->{'$m{tatt}'}) && \$_[0]->{att}->{'$m{tatt}'})"; } + elsif( $m{tbare_att} ) { "(\$_[0]->{att} && defined( \$_[0]->{att}->{'$m{tbare_att}'}))"; } + elsif( $m{tbare_num_test} && ($m{tbare_num_test} eq '=') ) { "==" } # others tests are unchanged + elsif( $m{tbare_test} ) { $PERL_ALPHA_TEST{$m{tbare_test}} } + elsif( $m{tfunc} && $m{tfunc}=~ m{^(?:string|text)}) { "\$_[0]->text"; } - elsif( $string_regexp && $string_regexp =~ m{(?:string|text)\(\s*($REG_TAG_NAME)\s*\)\s*($REG_MATCH)\s*($REG_REGEXP)}) - { "(XML::Twig::_first_n { (\$_->gi eq '$1') && (\$_->text $2 $3) } 1, \$_[0]->_children)"; } - elsif( $string_eq && $string_eq =~ m{(?:string|text)\(\s*($REG_TAG_NAME)\s*\)\s*(!?=)\s*($REG_VALUE)}) - {"(XML::Twig::_first_n { (\$_->gi eq '$1') && (\$_->text $PERL_ALPHA_TEST{$2} $3) } 1, \$_[0]->_children)"; } - elsif( $string_test && $string_test =~ m{(?:string|text)\(\s*($REG_TAG_NAME)\s*\)\s*([<>]=?)\s*($REG_VALUE)}) - { "(XML::Twig::_first_n { (\$_->gi eq '$1') && (\$_->text $2 $3) } 1, \$_[0]->_children)"; } - elsif( $and_or) { $and_or eq 'and' ? '&&' : '||' ; } - else { $token; } + elsif( $m{tstr_num}) { my $op = $m{op} eq '=' ? '==' : $m{op}; + if($m{tag}) + { "(first { (\$_->gi eq '$m{tag}') && (\$_->text $op $m{nb}) } \$_[0]->_children)"; } + else + { "(\$_[0]->text $op $m{nb})"; + } + } + elsif( $m{tstr_re} ) { if($m{tag}) + { "(first { (\$_->gi eq '$m{tag}') && (\$_->text $m{op} $m{re}) } \$_[0]->_children)"; } + else + { "(\$_[0]->text $m{op} $m{re} )";} + } + elsif( $m{tstr_str} ){ my $op = $PERL_ALPHA_TEST{$m{op}}; + if($m{tag}) + { "(first { (\$_->gi eq '$m{tag}') && (\$_->text $op $m{string}) } \$_[0]->_children)"; } + else + { "(\$_[0]->text $op $m{string} )"; } + } + + elsif( $m{tstring_test} ) + { "(first { (\$_->gi eq '$m{tag}') && (\$_->text $m{op} $m{string}) } \$m{_}[0]->_children)"; } + elsif( $m{tand_or}) { $m{tand_or }eq 'and' ? '&&' : '||' ; } + else { $m{token}; } }gexs; #warn "[$initial_cond] => [$cond]\n"; return "($cond)"; @@ -5897,7 +5925,7 @@ sub set_parent { $_[0]->{parent}= $_[1]; - if( $XML::Twig::weakrefs) { weaken( $_[0]->{parent}); } + weaken( $_[0]->{parent}); } sub parent @@ -5962,7 +5990,7 @@ sub set_last_child { $_[0]->{'last_child'}= $_[1]; delete $_[0]->{empty}; - if( $XML::Twig::weakrefs) { weaken( $_[0]->{'last_child'}); } + weaken( $_[0]->{'last_child'}); } sub last_child @@ -5977,7 +6005,7 @@ sub set_prev_sibling { $_[0]->{'prev_sibling'}= $_[1]; - if( $XML::Twig::weakrefs) { weaken( $_[0]->{'prev_sibling'}); } + weaken( $_[0]->{'prev_sibling'}); } sub prev_sibling @@ -6145,7 +6173,7 @@ { my( $elt, $id)= @_; my $t= $elt->twig || $elt; $t->{twig_id_list}->{$id}= $elt; - if( $XML::Twig::weakrefs) { weaken( $t->{twig_id_list}->{$id}); } + weaken( $t->{twig_id_list}->{$id}); return $elt; } @@ -6973,13 +7001,8 @@ { $test .= "\$_->text eq $1"; } elsif( $pred =~ s{^string\(\s*\)\s*!=\s*($REG_STRING)\s*}{}o) # string()!="string" pred { $test .= "\$_->text ne $1"; } - if( $pred =~ s{^string\(\s*\)\s*=\s*($REG_NUMBER)\s*}{}o) # string()=<number> pred - { $test .= "\$_->text eq $1"; } - elsif( $pred =~ s{^string\(\s*\)\s*!=\s*($REG_NUMBER)\s*}{}o) # string()!=<number> pred - { $test .= "\$_->text ne $1"; } - elsif( $pred =~ s{^string\(\s*\)\s*(>|<|>=|<=)\s*($REG_NUMBER)\s*}{}o) # string()!=<number> pred - { $test .= "\$_->text $1 $2"; } - + elsif( $pred =~ s{^string\(\s*\)\s*(>|<|>=|<=|!=|=)\s*($REG_NUMBER)\s*}{}o) # string() <comp> <number> pred + { $test .= _gen_nb_comparison( '$_->text', $1, $2); } elsif( $pred =~ s{^string\(\s*\)\s*($REG_MATCH)\s*($REG_REGEXP)\s*}{}o) # string()=~/regex/ pred { my( $match, $regexp)= ($1, $2); $test .= "\$_->text $match $regexp"; @@ -7028,6 +7051,12 @@ } } +sub _gen_nb_comparison { + my ($xml, $op, $nb) = @_; + if ($op eq '=') { $op = '=='; } + return "$xml $op $nb"; +} + sub _croak_and_doublecheck_xpath { my $xpath_expression= shift; my $mess= join( "\n", @_); @@ -7094,7 +7123,7 @@ # save the old links, that'll make it easier for some loops foreach my $link ( qw(parent prev_sibling next_sibling) ) { $elt->{former}->{$link}= $elt->{$link}; - if( $XML::Twig::weakrefs) { weaken( $elt->{former}->{$link}); } + weaken( $elt->{former}->{$link}); } # if we cut the current element then its parent becomes the current elt @@ -7293,7 +7322,7 @@ { $t->{twig_id_list}||={}; foreach my $id (keys %$ids) { $t->{twig_id_list}->{$id}= $ids->{$id}; - if( $XML::Twig::weakrefs) { weaken( $t->{twig_id_list}->{$id}); } + weaken( $t->{twig_id_list}->{$id}); } } return $elt; @@ -7969,7 +7998,7 @@ # save links to the original location, which can be convenient and is used for namespace resolution foreach my $link ( qw(parent prev_sibling next_sibling) ) { $copy->{former}->{$link}= $elt->{$link}; - if( $XML::Twig::weakrefs) { weaken( $copy->{former}->{$link}); } + weaken( $copy->{former}->{$link}); } $copy->set_empty( $elt->is_empty); @@ -7980,30 +8009,9 @@ sub delete { my $elt= shift; $elt->cut; - $elt->DESTROY unless $XML::Twig::weakrefs; return undef; } -sub __destroy - { my $elt= shift; - return if( $XML::Twig::weakrefs); - my $t= shift || $elt->twig; # optional argument, passed in recursive calls - - foreach( @{[$elt->_children]}) { $_->DESTROY( $t); } - - # the id reference needs to be destroyed - # lots of tests to avoid warnings during the cleanup phase - $elt->del_id( $t) if( $ID && $t && defined( $elt->{att}) && exists( $elt->{att}->{$ID})); - if( $elt->{former}) { foreach (keys %{$elt->{former}}) { delete $elt->{former}->{$_}; } delete $elt->{former}; } - foreach (qw( keys %$elt)) { delete $elt->{$_}; } - undef $elt; - } - -BEGIN -{ sub set_destroy { if( $XML::Twig::weakrefs) { undef *DESTROY } else { *DESTROY= *__destroy; } } - set_destroy(); -} - # ignores the element sub ignore { my $elt= shift; @@ -8644,7 +8652,7 @@ } sub xml_text_only - { return join '', map { $_->xml_text if( $_->is_text || $_->is_ent) } $_[0]->_children; } + { return join '', map { $_->is_text || $_->is_ent ? $_->xml_text : '' } $_[0]->_children; } # same as print but except... it does not print but rather returns the string # if the second parameter is set then only the content is returned, not the @@ -8898,7 +8906,7 @@ } sub text_only - { return join '', map { $_->text if( $_->is_text || $_->is_ent) } $_[0]->_children; } + { return join '', map { $_->is_text || $_->is_ent ? $_->text : '' } $_[0]->_children; } sub trimmed_text { my $elt= shift; @@ -9265,6 +9273,13 @@ { $t->{twig_current}= $new_elt; $elt->del_twig_current; $new_elt->set_twig_current; + if ( $t->{twig_in_cdata} || $t->{twig_in_pcdata} ) { + $t->{twig_in_cdata} = 0; + $t->{twig_in_pcdata} = 0; + $t->{twig_current}=$elt->parent; + $new_elt->del_twig_current; + $elt->parent->set_twig_current; + } } if( my $parent= $elt->_parent) @@ -14052,10 +14067,6 @@ The fix is either to upgrade to Perl 5.16 or later (C<perlbrew> is a great tool to manage several installations of perl on the same machine). -An other, NOT RECOMMENDED, way of fixing the problem, is to switch off weak -references by writing C<XML::Twig::_set_weakrefs( 0);> at the top of the code. -This is totally unsupported, and may lead to other problems though. - =item entity handling Due to XML::Parser behaviour, non-base entities in attribute values disappear if diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/speedup.pl new/XML-Twig-3.55/speedup.pl --- old/XML-Twig-3.54/speedup.pl 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/speedup.pl 2025-06-12 10:08:47.000000000 +0200 @@ -49,10 +49,10 @@ s{($elt)->former_($FORMER)}{($1\->{former} && $1\->{former}\->{$2})}g; - s{($elt)->set_(parent|prev_sibling)\(\s*($set_to)\s*\)}{$1\->\{$2\}=$3; if( \$XML::Twig::weakrefs) { weaken( $1\->\{$2\});} }g; + s{($elt)->set_(parent|prev_sibling)\(\s*($set_to)\s*\)}{$1\->\{$2\}=$3; weaken( $1\->\{$2\}); }g; s{($elt)->set_(first_child)\(\s*($set_to)\s*\)}{ $1\->set_not_empty; $1\->\{$2\}=$3; }g; s{($elt)->set_(next_sibling)\(\s*($set_to)\s*\)}{ $1\->\{$2\}=$3; }g; - s{($elt)->set_(last_child)\(\s*($set_to)\s*\)}{ $1\->set_not_empty; $1\->\{$2\}=$3; if( \$XML::Twig::weakrefs) { weaken( $1\->\{$2\});} }g; + s{($elt)->set_(last_child)\(\s*($set_to)\s*\)}{ $1\->set_not_empty; $1\->\{$2\}=$3; weaken( $1\->\{$2\}); }g; s/$var->atts/$1\->{att}/g; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_3_27.t new/XML-Twig-3.55/t/test_3_27.t --- old/XML-Twig-3.54/t/test_3_27.t 2021-09-09 17:19:21.000000000 +0200 +++ new/XML-Twig-3.55/t/test_3_27.t 2026-09-30 20:57:15.000000000 +0200 @@ -11,7 +11,7 @@ use XML::Twig; -my $TMAX = 82; +my $TMAX = 83; print "1..$TMAX\n"; { # test reverse call mode @@ -87,21 +87,22 @@ } { # test updating #att in start_tag_handlers - my ( $b, $e11, $e12 ) = '' x 3; + my ( $b, $e11, $e12, $bb ) = '' x 3; my $t = XML::Twig->new( start_tag_handlers => { a => sub { $_->parent->set_att( '#a' => 1 ); }, }, twig_handlers => { 'e1[@#a]/b' => sub { $b .= $_->id || $_->tag }, 'e1[@#a]' => sub { $e11 .= $_->id || $_->tag }, 'e1[!@#a]' => sub { $e12 .= $_->id || $_->tag }, - 'e1[@#a=1]/b' => sub { $b .= $_->id || $_->tag }, + 'e1[@#a=1]/b' => sub { $bb .= $_->id || $_->tag }, }, ) ->parse( q{<d id="d"><e1 id="e1-1"><a id="a1"/><b id="b1"/></e1><e1 id="e1-2"><c id="c1"/><b id="b2"/></e1></d>}); - is( $b, 'b1b1', 'trigger on e1[@#a]/b' ); + is( $b, 'b1', 'trigger on e1[@#a]/b' ); is( $e11, 'e1-1', 'trigger on e1[@#a]' ); is( $e12, 'e1-2', 'trigger on e1[!@#a]' ); + is( $bb, 'b1', 'trigger on e1[@#a=1]/b' ); } { # numerical tests in handlers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_3_40.t new/XML-Twig-3.55/t/test_3_40.t --- old/XML-Twig-3.54/t/test_3_40.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_3_40.t 2026-10-01 09:31:07.000000000 +0200 @@ -8,16 +8,16 @@ $|=1; my $DEBUG=0; - + use XML::Twig; -my $TMAX=96; +my $TMAX=88; print "1..$TMAX\n"; { my $d="<d><title section='1'>title</title><para>p 1</para> <para>p 2</para></d>"; - is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_spaces => 1, $d)), 1, 'space prevents indentation'); - is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_all_spaces => 1, $d)), 5, 'discard_all_spaces restores indentation'); + is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_spaces => 1, $d)), 1, 'space prevents indentation'); + is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_all_spaces => 1, $d)), 5, 'discard_all_spaces restores indentation'); } sub lf_in_t @@ -46,13 +46,13 @@ my( $trigger, $test_cat, $expected_ids)= @$test; my $handlers= $test_cat =~ m{H} ? { $trigger => sub { $ids.=$_->id; 1; } } : {}; my $t= XML::Twig->new( twig_handlers => $handlers )->parse( $d); - is( $ids, $expected_ids, "(H) trigger with alt: '$trigger'"); + is( $ids, $expected_ids, "(H) trigger with alt: '$trigger'"); my $uniq_ids= join '', sort $expected_ids=~m{(t\d(?:-\d)?)}g; if( $test_cat =~ m{X}) { (my $xpath= "//$trigger")=~ s{\|t}{|//t}g; - is( join( '', map { $_->id } $t->findnodes( $xpath)), $uniq_ids, " (X) path with |: '$trigger'"); + is( join( '', map { $_->id } $t->findnodes( $xpath)), $uniq_ids, " (X) path with |: '$trigger'"); } if( $test_cat =~ m{N}) @@ -76,33 +76,33 @@ is( $got, 'i1i3', 'bare attribute in handler condition'); } -if( $] > 5.008) +if( $] > 5.008 && XML::Twig::_use('LWP') ) { my $doc= q{<!DOCTYPE doc [ <!ELEMENT doc (#PCDATA)><!ENTITY ext SYSTEM "not_there.txt">]><doc>&ext;</doc>}; ok( XML::Twig->parse( expand_external_ents => -1, $doc), 'failsafe expand_external_ents'); } else -{ skip( 1, 'not tested under perl < 5.8'); } - +{ skip( 1, 'not tested under perl < 5.8 or without LWP installed'); } + { my $t=XML::Twig->parse( q{<doc><e><e1>e11</e1><e2>e21</e2></e><e><e1>e12</e1></e></doc>}); is( join( ':', $t->findvalues( [$t->root->children], "./e1")), 'e11:e12', 'findvalues on array'); } -{ my $t=XML::Twig->parse( "<doc/>"); +{ my $t=XML::Twig->parse( "<doc/>"); $t->set_encoding( "UTF-8"); is( $t->sprint, qq{<?xml version="1.0" encoding="UTF-8"?>\n<doc/>}, 'set_encoding without XML declaration'); } -{ my $t=XML::Twig->parse( "<doc/>"); +{ my $t=XML::Twig->parse( "<doc/>"); $t->set_standalone( 1); is( $t->sprint, qq{<?xml version="1.0" standalone="yes"?>\n<doc/>}, 'set_standalone (yes) without XML declaration'); } -{ my $t=XML::Twig->parse( "<doc/>"); +{ my $t=XML::Twig->parse( "<doc/>"); $t->set_standalone( 0); is( $t->sprint, qq{<?xml version="1.0" standalone="no"?>\n<doc/>}, 'set_standalone (no) without XML declaration'); } -{ my $t=XML::Twig->parse( "<doc/>"); +{ my $t=XML::Twig->parse( "<doc/>"); nok( $t->xml_version, 'xml_version with no XML declaration'); $t->set_xml_version( 1.1); is( $t->sprint, qq{<?xml version="1.1"?>\n<doc/>}, 'set_xml_version without XML declaration'); @@ -125,58 +125,6 @@ is( $t->sprint, '<nroot><root/></nroot>', 'wrapping the root'); } -{ -my $t=XML::Twig->new; -XML::Twig::_set_weakrefs(0); -my $doc='<doc>\n <e att="a">text</e><e>text <![CDATA[cdata text]]> more text <e>foo</e>\n more</e></doc>'; -$t->parse( $doc); - -$doc=~ s{\n }{}; # just the first one -is( $t->sprint, $doc, 'parse with no weakrefs'); - -$t->root->insert_new_elt( first_child => x => 'text'); -$doc=~ s{<doc>}{<doc><x>text</x>}; -is( $t->sprint, $doc, 'insert first child with no weakrefs'); - -$t->root->insert_new_elt( last_child => x => 'text'); -$doc=~ s{</doc>}{<x>text</x></doc>}; -is( $t->sprint, $doc, 'insert last child with no weakrefs'); - -$t->root->wrap_in( 'dd'); -$doc=~ s{<doc>}{<dd><doc>}; $doc=~s{</doc>}{</doc></dd>}; -is( $t->sprint, $doc, 'wrap with no weakrefs'); - -$t->root->unwrap; -$doc=~s{</?dd>}{}g; -is( $t->sprint, $doc, 'unwrap with no weakrefs'); - -my $new_e= XML::Twig::Elt->new( ee => { c => 1 }, 'ee text'); -$new_e->replace( $t->root->first_child( 'e')); -$doc=~ s{<e.*?</e>}{<ee c="1">ee text</ee>}; -is( $t->sprint, $doc, 'replace with no weakrefs'); - -XML::Twig::_set_weakrefs(1); - -} - -{ -my $t= XML::Twig->new( no_expand => 1); -XML::Twig::_set_weakrefs(0); -my $doc='<!DOCTYPE d [<!ENTITY foo SYSTEM "foo.xml"><!ENTITY bar SYSTEM "bar.xml">]><d a="foo"> bar &bar; bar<e/><f>&bar;</f><f>&foo; <e/>&bar; bar &foo;</f><e/>&bar; na &foo;<e/></d>'; -$t->parse( $doc); -(my $got= $t->sprint)=~ s{\n}{}g; -is( $got, $doc, 'external entities without weakrefs'); - -XML::Twig::_set_weakrefs(1); -} - -{ - XML::Twig::_set_weakrefs(0); - { my $t= XML::Twig->new; undef $t; } - ok( 1, "DESTROY doesn't crash when weakrefs is off"); - XML::Twig::_set_weakrefs(1); -} - { my $doc= '<d><e a="a" get1="1" id="e1">foo</e><e a="b" id="e2"><e1 id="e11"/>bar</e><e a="b" id="e3"><e2 id="e21"/>bar</e></d>'; my( $got1, $got2); XML::Twig->new( twig_handlers => { e1 => sub { $_->parent->set_att( get1 => 1); }, @@ -194,7 +142,7 @@ { my $t=XML::Twig->parse( '<foo><e/>foo<!-- comment --></foo>'); my $root= $t->root; - ok( $root->closed, 'closed on completely parsed tree'); + ok( $root->closed, 'closed on completely parsed tree'); ok( $root->_extra_data_before_end_tag, '_extra_data_before_end_tag (success)'); nok( $root->first_child->_extra_data_before_end_tag, '_extra_data_before_end_tag (no data)'); } @@ -357,5 +305,5 @@ } { my $s= "foo"; - is( XML::Twig::_to_utf8( 'iso-8859-1', $s), $s, 'trivial test of _to_utf8'); + is( XML::Twig::_to_utf8( 'iso-8859-1', $s), $s, 'trivial test of _to_utf8'); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_3_41.t new/XML-Twig-3.55/t/test_3_41.t --- old/XML-Twig-3.54/t/test_3_41.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_3_41.t 2025-06-12 10:08:47.000000000 +0200 @@ -4,7 +4,7 @@ use warnings; use XML::Twig; -use Test::More tests => 16; +use Test::More tests => 15; { @@ -76,14 +76,6 @@ ok( ! XML::Twig->parse( '<?xml version="1.0" standalone="no"?><d/>')->standalone, 'standalone, no'); { - XML::Twig::_set_weakrefs(0); - my $t= XML::Twig->parse( '<d><e/><e><f/><f/></e><e/></d>'); - $t->root->first_child( 'e')->next_sibling( 'e')->erase; - is( $t->sprint, '<d><e/><f/><f/><e/></d>', 'erase without weakrefs'); - XML::Twig::_set_weakrefs(1) -} - -{ my $doc='<ns1:list xmlns:ns1="http://namespace/CommandService" xmlns:ns2="http://namespace/ShelfService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <commands> <commandId>1</commandId> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_3_44.t new/XML-Twig-3.55/t/test_3_44.t --- old/XML-Twig-3.54/t/test_3_44.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_3_44.t 2025-06-12 10:08:47.000000000 +0200 @@ -4,7 +4,7 @@ use warnings; use XML::Twig; -use Test::More tests => 86; +use Test::More tests => 84; { my $e= XML::Twig::Elt->new( 'foo'); @@ -86,19 +86,6 @@ is( $t->sprint, '<d>&4&3&2&1f</d>', 'pcdata prefix, after a prefix with an asis option'); } -{ my $weakrefs= XML::Twig::_weakrefs(); - XML::Twig::_set_weakrefs(0); - - my $t= XML::Twig->parse( '<d><e>f</e></d>'); - my $e= $t->first_elt( 'e'); - XML::Twig::Elt->new( x => 'g')->replace( $e); - is( $t->sprint, '<d><x>g</x></d>', 'replace non root element without weakrefs'); - XML::Twig::Elt->new( y => 'h')->replace( $t->root); - is( $t->sprint, '<y>h</y>', 'replace root element without weakrefs'); - - XML::Twig::_set_weakrefs( $weakrefs); -} - { my $t= XML::Twig->parse( '<d><p>foo<!--c1--></p><!--c2--><p>bar<!--c3-->baz<!--c4--></p></d>'); my $r= $t->root; is( $r->children_count, 2, '2 p'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_additional.t new/XML-Twig-3.55/t/test_additional.t --- old/XML-Twig-3.54/t/test_additional.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_additional.t 2026-09-30 18:21:55.000000000 +0200 @@ -2274,7 +2274,7 @@ is( $t->sprint, '<doc><p>titi toto</p></doc>', 'split, no match');# test 557 } -{ my $doc= '<?xml version="a.0"?><!DOCTYPE doc SYSTEM "no_dtd" []> <doc att="val"><p att="val">toto &ent; <![CDATA[ toto]]></p></doc>'; +{ my $doc= '<?xml version="1.0"?><!DOCTYPE doc SYSTEM "no_dtd" []> <doc att="val"><p att="val">toto &ent; <![CDATA[ toto]]></p></doc>'; my $t= XML::Twig->new->parse( $doc); my $alt_root= $t->root->copy; is( $alt_root->sprint, $t->root->sprint, 'copy with entity');# test 558 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_bugs_3_18.t new/XML-Twig-3.55/t/test_bugs_3_18.t --- old/XML-Twig-3.54/t/test_bugs_3_18.t 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/t/test_bugs_3_18.t 2025-06-12 10:08:47.000000000 +0200 @@ -12,7 +12,7 @@ use XML::Twig; -my $TMAX=156; +my $TMAX=155; print "1..$TMAX\n"; { @@ -544,7 +544,7 @@ $t->subs_text( qr/(t[aeiou]t[aeiou])/, '&elt( p => $1)'); is( $t->sprint,'<doc><p>toto</p><p>tata</p><p>titi</p><p>tutu</p></doc>' , 'subs_text (use \2)'); } - + { my $doc= q{<doc><!-- comment --><e> toto <!-- comment 2 --></e> <e2 att="val1" att2="val2"><!-- comment --><e> toto <!-- comment 2 --></e></e2> <e>foo <?tg pi?> bar <!-- duh --> baz</e> @@ -560,15 +560,6 @@ is( $copy->sprint, $t->root->sprint, "copy with extra data, and asis"); } -{ my $save= XML::Twig::_weakrefs(); - XML::Twig::_set_weakrefs( 0); - my $t= XML::Twig->new->parse( '<doc><e id="e1"/><e id="e2">foo <f id="oo"/></e></doc>'); - $t->root->first_child->cut->DESTROY; - $t->root->first_child->cut->DESTROY; - is( $t->sprint, '<doc></doc>', 'DESTROY'); - XML::Twig::_set_weakrefs( $save); -} - { # test keep_encoding is( XML::Twig::Elt::_keep_encoding(), 0, "_keep_encoding not initialized"); XML::Twig->new( keep_encoding => 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_kwalitee.t new/XML-Twig-3.55/t/test_kwalitee.t --- old/XML-Twig-3.54/t/test_kwalitee.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_kwalitee.t 2026-10-01 09:46:15.000000000 +0200 @@ -7,7 +7,7 @@ eval { require Test::More; Test::More->import(); }; if( $@) { print "1..1\nok 1\n"; warn "need test::More installed for this test\n"; exit; } -eval { require Test::Kwalitee; Test::Kwalitee->import() }; +eval { require Test::Kwalitee; Test::Kwalitee::kwalitee_ok( qw(-no_symlinks) ); done_testing(); }; plan( skip_all => 'Test::Kwalitee not installed; skipping' ) if $@; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_memory.t new/XML-Twig-3.55/t/test_memory.t --- old/XML-Twig-3.54/t/test_memory.t 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/t/test_memory.t 2025-06-12 10:08:47.000000000 +0200 @@ -22,12 +22,6 @@ exit; } -if ( !XML::Twig::_weakrefs() ) { - print "1..1\nok 1\n"; - warn "skipping: weaken not available\n"; - exit; -} - my $long_test = $ARGV[0] && $ARGV[0] eq '-L'; my $conf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/test_xml_split.t new/XML-Twig-3.55/t/test_xml_split.t --- old/XML-Twig-3.54/t/test_xml_split.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/test_xml_split.t 2025-06-12 10:08:47.000000000 +0200 @@ -10,14 +10,14 @@ my $devnull = File::Spec->devnull; my $DEBUG=0; -my $extra_flags= $Devel::Cover::VERSION ? '-MDevel::Cover -Ilib' : '-Ilib'; +my $build_lib = File::Spec->catfile( 'blib', 'lib'); + +my $extra_flags= $Devel::Cover::VERSION ? "-MDevel::Cover -I$build_lib" : "-I$build_lib"; # be cautious: run this only on systems I have tested it on my %os_ok=( linux => 1, solaris => 1, darwin => 1, MSWin32 => 1); if( !$os_ok{$^O}) { print "1..1\nok 1\n"; warn "skipping, test runs only on some OSs\n"; exit; } -if( $] < 5.006) { print "1..1\nok 1\n"; warn "skipping, xml_merge runs only on perl 5.6 and later\n"; exit; } - print "1..59\n"; my $perl= $Config{perlpath}; @@ -107,8 +107,8 @@ $merge_opts ||= ''; $base_nb++; my $verbifdebug = $DEBUG ? '-v' : ''; - my $expected_base= File::Spec->catfile( "$test_dir", "test_xml_split_expected-$base_nb"); - my $base= File::Spec->catfile( "$test_dir", "test_xml_split-$base_nb"); + my $expected_base= File::Spec->catfile( "$test_dir", "test_xml_split_expected-$base_nb"); + my $base= File::Spec->catfile( "$test_dir", "test_xml_split-$base_nb"); systemq( "$perl $xml_split $verbifdebug -b $base $split_opts $file"); ok( same_files( $expected_base, $base), "xml_split $split_opts $test_file"); @@ -117,7 +117,7 @@ system "$perl $xml_merge $verbifdebug -o $merged $merge_opts $base-00.xml"; system "$perl $xml_pp -i $merged"; ok( same_file( $merged, $file), "xml_merge $merge_opts $test_file ($merged $base-00.xml"); - + unlink( glob( "$base*")) unless( $DEBUG); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/t/zz_dump_config.t new/XML-Twig-3.55/t/zz_dump_config.t --- old/XML-Twig-3.54/t/zz_dump_config.t 2016-06-21 12:50:27.000000000 +0200 +++ new/XML-Twig-3.55/t/zz_dump_config.t 2025-06-12 20:22:40.000000000 +0200 @@ -38,20 +38,21 @@ { warn format_warn( 'expat', '<no version information found>'); } } -print "\n"; - -# must-have -warn "Strongly Recommended\n"; warn version( Scalar::Util, 'for improved memory management'); if( $ok) { unless( defined( &Scalar::Util::weaken)) { warn format_warn( '', 'NOT USED, weaken not available in this version'); - warn version( WeakRef); + warn version( WeakRef); } } else { warn version( WeakRef, 'for improved memory management'); } +print "\n"; + + +# must-have +warn "Strongly Recommended\n"; # encoding warn version( Encode, 'for encoding conversions'); unless( $ok) { warn version( Text::Iconv, 'for encoding conversions'); } @@ -62,7 +63,7 @@ # optional warn "Modules providing additional features\n"; warn version( XML::XPathEngine, 'to use XML::Twig::XPath'); -warn version( XML::XPath, 'to use XML::Twig::XPath if Tree::XPathEngine not available'); +warn version( XML::XPath, 'to use XML::Twig::XPath if XML::XPathEngine not available'); warn version( LWP, 'for the parseurl method'); warn version( HTML::TreeBuilder, 'to use parse_html and parsefile_html'); warn version( HTML::Entities::Numbered, 'to allow parsing of HTML containing named entities'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/tools/xml_merge/xml_merge new/XML-Twig-3.55/tools/xml_merge/xml_merge --- old/XML-Twig-3.54/tools/xml_merge/xml_merge 2025-06-11 08:48:17.000000000 +0200 +++ new/XML-Twig-3.55/tools/xml_merge/xml_merge 2026-04-08 21:35:14.000000000 +0200 @@ -1,5 +1,4 @@ #!/usr/bin/perl -w -# $Id: /xmltwig/trunk/tools/xml_merge/xml_merge 12 2007-04-22T06:04:54.627880Z mrodrigu $ use strict; use XML::Twig; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/tools/xml_pp/xml_pp new/XML-Twig-3.55/tools/xml_pp/xml_pp --- old/XML-Twig-3.54/tools/xml_pp/xml_pp 2016-11-22 15:31:20.000000000 +0100 +++ new/XML-Twig-3.55/tools/xml_pp/xml_pp 2026-04-08 21:34:19.000000000 +0200 @@ -1,5 +1,4 @@ #!/usr/bin/perl -w -# $Id: /xmltwig/trunk/tools/xml_pp/xml_pp 32 2008-01-18T13:11:52.128782Z mrodrigu $ use strict; use XML::Twig; @@ -45,7 +44,7 @@ my $tempfile; if( $opt{in_place}) { (undef, $tempfile)= tempfile( DIR => dirname( $file)) or die "cannot create tempfile for $file: $!\n" ; - open( PP_OUTPUT, ">$tempfile") or die "cannot create tempfile $tempfile: $!"; + open( PP_OUTPUT, '>', $tempfile) or die "cannot create tempfile $tempfile: $!"; select PP_OUTPUT; } $t= $t->safe_parsefile( $file); @@ -138,7 +137,7 @@ # get the list of files (one per line) from a file sub files_from { my $file= shift; - open( FILES, "<$file") or die "cannot open file $file: $!"; + open( FILES, '<', $file) or die "cannot open file $file: $!"; my @files; while( <FILES>) { chomp; push @files, $_; } close FILES; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XML-Twig-3.54/tools/xml_split/xml_split new/XML-Twig-3.55/tools/xml_split/xml_split --- old/XML-Twig-3.54/tools/xml_split/xml_split 2016-11-22 15:31:20.000000000 +0100 +++ new/XML-Twig-3.55/tools/xml_split/xml_split 2026-04-08 21:35:18.000000000 +0200 @@ -1,5 +1,4 @@ #!/usr/bin/perl -w -# $Id: /xmltwig/trunk/tools/xml_split/xml_split 17 2007-06-04T11:57:10.366292Z mrodrigu $ use strict; use XML::Twig; ++++++ _scmsync.obsinfo ++++++ mtime: 1790882012 commit: da963ac5d02ac6f2526a3f87a62b49e4ed613578e31139c12150fe7bbf023777 url: https://src.opensuse.org/perl/perl-XML-Twig revision: da963ac5d02ac6f2526a3f87a62b49e4ed613578e31139c12150fe7bbf023777 projectscmsync: https://src.opensuse.org/perl/_ObsPrj ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-10-01 21:13:32.000000000 +0200 @@ -0,0 +1 @@ +.osc
