Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-XML-LibXML for openSUSE:Factory 
checked in at 2026-06-09 14:14:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-XML-LibXML (Old)
 and      /work/SRC/openSUSE:Factory/.perl-XML-LibXML.new.2375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-XML-LibXML"

Tue Jun  9 14:14:00 2026 rev:65 rq:1357941 version:2.0213

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-XML-LibXML/perl-XML-LibXML.changes  
2026-05-24 19:35:02.669781611 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-XML-LibXML.new.2375/perl-XML-LibXML.changes    
    2026-06-09 14:14:17.693652366 +0200
@@ -1,0 +2,43 @@
+Fri May 22 08:17:33 UTC 2026 - Tina Müller <[email protected]>
+
+- updated to 2.0213
+   see /usr/share/doc/packages/perl-XML-LibXML/Changes
+
+  2.0213  2026-05-21
+      [SECURITY / BUG FIXES]
+      - Revert PR #143 per the libxml2 author's request. PR #143 added a
+        URL-scheme filter inside LibXML_load_external_entity and removed
+        the EXTERNAL_ENTITY_LOADER_FUNC == NULL guards on the five
+        Schema/RelaxNG NONET swap sites, on the premise that
+        no_network on one parser should override a user-installed global
+        externalEntityLoader. Nick Wellnhofer clarified that this
+        contradicts upstream intent: XML_PARSE_NONET only polices
+        libxml2's default loader; a user who installs a global loader is
+        explicitly opting out of that policy, and the http/https/ftp
+        allowlist was never a real security boundary. Reverted in full;
+        PR #138's lifecycle/memory-safety fixes are kept.
+          - GH #168
+      [BUG FIXES]
+      - Fix latent SEGV in _externalEntityLoader. The XS code returned
+        &PL_sv_undef as RETVAL when no previous global loader existed.
+        Because xsubpp auto-mortalizes SV* RETVAL, each call mortalized
+        the PL_sv_undef singleton, eventually driving its refcount
+        negative and producing "Attempt to free unreferenced scalar"
+        followed by SEGV under repeated invocation. Now returns
+        newSV(0) so RETVAL is always a fresh refcount-1 SV safe to
+        mortalize. The bug shipped in 2.0212 with PR #138's lifecycle
+        fixes; this is a single-line correction to that code path.
+      [MAINTENANCE]
+      - Add t/49global_extent_with_no_network.t, 17 subtests locking in
+        the entity-loader contract restored by the GH #168 revert: a
+        user-installed global loader takes precedence over no_network
+        across plain XML parse, RelaxNG, and XML Schema, while
+        no_network without any loader still blocks via libxml2's
+        default loader.
+      - Document the entity-loader contract in CLAUDE.md
+        ("Entity loaders, no_network, and XML_PARSE_NONET") plus a
+        "Verifying audit-flagged security findings" checklist to keep
+        pattern-matched "security fixes" like PR #143 from shipping
+        again.
+
+-------------------------------------------------------------------

Old:
----
  XML-LibXML-2.0212.tar.gz

New:
----
  XML-LibXML-2.0213.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-XML-LibXML.spec ++++++
--- /var/tmp/diff_new_pack.tjFGws/_old  2026-06-09 14:14:18.749696778 +0200
+++ /var/tmp/diff_new_pack.tjFGws/_new  2026-06-09 14:14:18.753696946 +0200
@@ -18,7 +18,7 @@
 
 %define cpan_name XML-LibXML
 Name:           perl-XML-LibXML
-Version:        2.0212
+Version:        2.0213
 Release:        0
 License:        Artistic-1.0 OR GPL-1.0-or-later
 Summary:        Interface to Gnome libxml2 xml parsing and DOM library

++++++ XML-LibXML-2.0212.tar.gz -> XML-LibXML-2.0213.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/Changes 
new/XML-LibXML-2.0213/Changes
--- old/XML-LibXML-2.0212/Changes       2026-05-20 03:54:22.000000000 +0200
+++ new/XML-LibXML-2.0213/Changes       2026-05-21 17:32:47.000000000 +0200
@@ -1,5 +1,45 @@
 Revision history for Perl extension XML::LibXML
 
+2.0213  2026-05-21
+
+    [SECURITY / BUG FIXES]
+    - Revert PR #143 per the libxml2 author's request. PR #143 added a
+      URL-scheme filter inside LibXML_load_external_entity and removed
+      the EXTERNAL_ENTITY_LOADER_FUNC == NULL guards on the five
+      Schema/RelaxNG NONET swap sites, on the premise that
+      no_network on one parser should override a user-installed global
+      externalEntityLoader. Nick Wellnhofer clarified that this
+      contradicts upstream intent: XML_PARSE_NONET only polices
+      libxml2's default loader; a user who installs a global loader is
+      explicitly opting out of that policy, and the http/https/ftp
+      allowlist was never a real security boundary. Reverted in full;
+      PR #138's lifecycle/memory-safety fixes are kept.
+        - GH #168
+
+    [BUG FIXES]
+    - Fix latent SEGV in _externalEntityLoader. The XS code returned
+      &PL_sv_undef as RETVAL when no previous global loader existed.
+      Because xsubpp auto-mortalizes SV* RETVAL, each call mortalized
+      the PL_sv_undef singleton, eventually driving its refcount
+      negative and producing "Attempt to free unreferenced scalar"
+      followed by SEGV under repeated invocation. Now returns
+      newSV(0) so RETVAL is always a fresh refcount-1 SV safe to
+      mortalize. The bug shipped in 2.0212 with PR #138's lifecycle
+      fixes; this is a single-line correction to that code path.
+
+    [MAINTENANCE]
+    - Add t/49global_extent_with_no_network.t, 17 subtests locking in
+      the entity-loader contract restored by the GH #168 revert: a
+      user-installed global loader takes precedence over no_network
+      across plain XML parse, RelaxNG, and XML Schema, while
+      no_network without any loader still blocks via libxml2's
+      default loader.
+    - Document the entity-loader contract in CLAUDE.md
+      ("Entity loaders, no_network, and XML_PARSE_NONET") plus a
+      "Verifying audit-flagged security findings" checklist to keep
+      pattern-matched "security fixes" like PR #143 from shipping
+      again.
+
 2.0212  2026-05-19
 
     [BUG FIXES]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/LibXML.pm 
new/XML-LibXML-2.0213/LibXML.pm
--- old/XML-LibXML-2.0212/LibXML.pm     2026-05-20 03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/LibXML.pm     2026-05-21 17:36:48.000000000 +0200
@@ -30,7 +30,7 @@
 use IO::Handle; # for FH reads called as methods
 
 BEGIN {
-$VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+$VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 our $ABI_VERSION = 2;
 require Exporter;
 use XSLoader ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/LibXML.pod 
new/XML-LibXML-2.0213/LibXML.pod
--- old/XML-LibXML-2.0212/LibXML.pod    2026-05-20 03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/LibXML.pod    2026-05-21 17:37:09.000000000 +0200
@@ -507,7 +507,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/LibXML.xs 
new/XML-LibXML-2.0213/LibXML.xs
--- old/XML-LibXML-2.0212/LibXML.xs     2026-05-19 21:48:41.000000000 +0200
+++ new/XML-LibXML-2.0213/LibXML.xs     2026-05-20 19:20:14.000000000 +0200
@@ -156,22 +156,6 @@
 /* global external entity loader */
 SV *EXTERNAL_ENTITY_LOADER_FUNC = (SV *)NULL;
 
-static int
-LibXML_is_network_uri(const char *URL)
-{
-    if (URL == NULL)
-    {
-        return 0;
-    }
-    if (xmlStrncmp(BAD_CAST URL, BAD_CAST "http://";, 7) == 0 ||
-        xmlStrncmp(BAD_CAST URL, BAD_CAST "https://";, 8) == 0 ||
-        xmlStrncmp(BAD_CAST URL, BAD_CAST "ftp://";, 6) == 0)
-    {
-        return 1;
-    }
-    return 0;
-}
-
 SV* PROXY_NODE_REGISTRY_MUTEX = NULL;
 
 /* ****************************************************************
@@ -819,6 +803,10 @@
     return 1;
 }
 
+/* Dispatcher for user-installed Perl entity loaders (per-parser
+ * "ext_ent_handler" or process-global externalEntityLoader()). DO NOT add
+ * URL filtering or no_network checks here -- the user's callback is the
+ * policy authority. See CLAUDE.md "Entity loaders" and GH #168/#133/#143. */
 xmlParserInputPtr
 LibXML_load_external_entity(
         const char * URL,
@@ -838,15 +826,6 @@
         return xmlNewInputFromFile(ctxt, URL);
     }
 
-    if (ctxt != NULL && (ctxt->options & XML_PARSE_NONET) &&
-        LibXML_is_network_uri(URL))
-    {
-        xmlGenericError(xmlGenericErrorContext,
-            "Attempt to load network entity %s\n",
-            URL != NULL ? URL : "(null)");
-        return NULL;
-    }
-
     if (URL == NULL) {
         URL = "";
     }
@@ -988,6 +967,9 @@
             if (ctxt) ctxt->linenumbers = 0;
         }
 
+       /* If a user installed a process-global loader via 
externalEntityLoader(),
+        * leave it alone -- they're the policy authority. See CLAUDE.md
+        * "Entity loaders". */
        if(EXTERNAL_ENTITY_LOADER_FUNC == NULL)
        {
             item = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
@@ -2826,9 +2808,13 @@
         SV* loader
     CODE:
         {
+            /* Always return a fresh refcount-1 SV: xsubpp auto-mortalizes
+             * RETVAL for SV*, and mortalizing the &PL_sv_undef singleton on
+             * every call eventually drives its refcount negative (SEGV under
+             * repeated invocation). Use newSV(0) for "no previous handler". */
             RETVAL = EXTERNAL_ENTITY_LOADER_FUNC
                 ? newSVsv(EXTERNAL_ENTITY_LOADER_FUNC)
-                : &PL_sv_undef;
+                : newSV(0);
 
             if (SvOK(loader))
             {
@@ -7401,14 +7387,16 @@
                                   saved_error );
 #endif
 
-        if ( parser_options & XML_PARSE_NONET ) {
+        /* EXTERNAL_ENTITY_LOADER_FUNC == NULL guard preserves a user-installed
+         * global loader. See CLAUDE.md "Entity loaders" and GH #168. */
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) ) {
             old_ext_ent_loader = xmlGetExternalEntityLoader();
             xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
         }
 
         RETVAL = xmlRelaxNGParse( rngctxt );
 
-        if ( parser_options & XML_PARSE_NONET )
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) )
             xmlSetExternalEntityLoader( 
(xmlExternalEntityLoader)old_ext_ent_loader );
 
         xmlRelaxNGFreeParserCtxt( rngctxt );
@@ -7450,14 +7438,16 @@
                                   saved_error );
 #endif
 
-        if ( parser_options & XML_PARSE_NONET ) {
+        /* EXTERNAL_ENTITY_LOADER_FUNC == NULL guard preserves a user-installed
+         * global loader. See CLAUDE.md "Entity loaders" and GH #168. */
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) ) {
             old_ext_ent_loader = xmlGetExternalEntityLoader();
             xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
         }
 
         RETVAL = xmlRelaxNGParse( rngctxt );
 
-        if ( parser_options & XML_PARSE_NONET )
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) )
             xmlSetExternalEntityLoader( 
(xmlExternalEntityLoader)old_ext_ent_loader );
 
         xmlRelaxNGFreeParserCtxt( rngctxt );
@@ -7492,14 +7482,16 @@
                                   saved_error );
 #endif
 
-        if ( parser_options & XML_PARSE_NONET ) {
+        /* EXTERNAL_ENTITY_LOADER_FUNC == NULL guard preserves a user-installed
+         * global loader. See CLAUDE.md "Entity loaders" and GH #168. */
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) ) {
             old_ext_ent_loader = xmlGetExternalEntityLoader();
             xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
         }
 
         RETVAL = xmlRelaxNGParse( rngctxt );
 
-        if ( parser_options & XML_PARSE_NONET )
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) )
             xmlSetExternalEntityLoader( 
(xmlExternalEntityLoader)old_ext_ent_loader );
 
         xmlRelaxNGFreeParserCtxt( rngctxt );
@@ -7591,14 +7583,16 @@
                                   
(xmlSchemaValidityWarningFunc)LibXML_error_handler_ctx,
                                   saved_error );
 
-        if ( parser_options & XML_PARSE_NONET ) {
+        /* EXTERNAL_ENTITY_LOADER_FUNC == NULL guard preserves a user-installed
+         * global loader. See CLAUDE.md "Entity loaders" and GH #168. */
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) ) {
             old_ext_ent_loader = xmlGetExternalEntityLoader();
             xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
         }
 
         RETVAL = xmlSchemaParse( rngctxt );
 
-        if ( parser_options & XML_PARSE_NONET )
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) )
             xmlSetExternalEntityLoader( 
(xmlExternalEntityLoader)old_ext_ent_loader );
 
         xmlSchemaFreeParserCtxt( rngctxt );
@@ -7641,14 +7635,16 @@
                                   
(xmlSchemaValidityWarningFunc)LibXML_error_handler_ctx,
                                   saved_error );
 
-        if ( parser_options & XML_PARSE_NONET ) {
+        /* EXTERNAL_ENTITY_LOADER_FUNC == NULL guard preserves a user-installed
+         * global loader. See CLAUDE.md "Entity loaders" and GH #168. */
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) ) {
             old_ext_ent_loader = xmlGetExternalEntityLoader();
             xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
         }
 
         RETVAL = xmlSchemaParse( rngctxt );
 
-        if ( parser_options & XML_PARSE_NONET )
+        if ( EXTERNAL_ENTITY_LOADER_FUNC == NULL && (parser_options & 
XML_PARSE_NONET) )
             xmlSetExternalEntityLoader( 
(xmlExternalEntityLoader)old_ext_ent_loader );
 
         xmlSchemaFreeParserCtxt( rngctxt );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/MANIFEST 
new/XML-LibXML-2.0213/MANIFEST
--- old/XML-LibXML-2.0212/MANIFEST      2026-05-20 03:59:12.000000000 +0200
+++ new/XML-LibXML-2.0213/MANIFEST      2026-05-21 17:50:56.000000000 +0200
@@ -177,12 +177,12 @@
 t/48importing_nodes_IDs_rt_69520.t
 t/49_load_html.t
 t/49callbacks_returning_undef.t
-t/49global_ext_nonet.t
 t/49global_extent.t
 t/49global_extent_after_no_network.t
 t/49global_extent_lifecycle.t
 t/49global_extent_private.t
 t/49global_extent_reset.t
+t/49global_extent_with_no_network.t
 t/50devel.t
 t/51_parse_html_string_rt87089.t
 t/60error_prev_chain.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/META.json 
new/XML-LibXML-2.0213/META.json
--- old/XML-LibXML-2.0212/META.json     2026-05-20 03:59:12.000000000 +0200
+++ new/XML-LibXML-2.0213/META.json     2026-05-21 17:50:56.000000000 +0200
@@ -99,6 +99,6 @@
          "web" : "https://github.com/cpan-authors/XML-LibXML";
       }
    },
-   "version" : "2.0212",
+   "version" : "2.0213",
    "x_serialization_backend" : "JSON::PP version 4.16"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/META.yml 
new/XML-LibXML-2.0213/META.yml
--- old/XML-LibXML-2.0212/META.yml      2026-05-20 03:59:12.000000000 +0200
+++ new/XML-LibXML-2.0213/META.yml      2026-05-21 17:50:56.000000000 +0200
@@ -69,5 +69,5 @@
 resources:
   bugtracker: https://github.com/cpan-authors/XML-LibXML/issues
   repository: https://github.com/cpan-authors/XML-LibXML.git
-version: '2.0212'
+version: '2.0213'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.020'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/docs/libxml.dbk 
new/XML-LibXML-2.0213/docs/libxml.dbk
--- old/XML-LibXML-2.0212/docs/libxml.dbk       2026-05-20 03:55:20.000000000 
+0200
+++ new/XML-LibXML-2.0213/docs/libxml.dbk       2026-05-21 17:37:09.000000000 
+0200
@@ -22,7 +22,7 @@
         </authorgroup>
 
 
-        <edition>2.0212</edition>
+        <edition>2.0213</edition>
         <copyright>
             <year>2001-2007</year>
             <holder>AxKit.com Ltd</holder>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Attr.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Attr.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Attr.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Attr.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -121,7 +121,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/AttributeHash.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/AttributeHash.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/AttributeHash.pm       2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/AttributeHash.pm       2026-05-21 
17:36:48.000000000 +0200
@@ -6,7 +6,7 @@
 use Tie::Hash;
 our @ISA = qw/Tie::Hash/;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 BEGIN
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Boolean.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Boolean.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Boolean.pm     2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Boolean.pm     2026-05-21 
17:36:48.000000000 +0200
@@ -14,7 +14,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use overload
         '""' => \&value,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/CDATASection.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/CDATASection.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/CDATASection.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/CDATASection.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -45,7 +45,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Comment.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Comment.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Comment.pod    2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Comment.pod    2026-05-21 
17:37:09.000000000 +0200
@@ -46,7 +46,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Common.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Common.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Common.pm      2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Common.pm      2026-05-21 
17:36:48.000000000 +0200
@@ -22,7 +22,7 @@
 
 our @ISA = qw(Exporter);
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use XML::LibXML qw(:libxml);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Common.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Common.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Common.pod     2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Common.pod     2026-05-21 
17:37:09.000000000 +0200
@@ -116,7 +116,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/DOM.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/DOM.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/DOM.pod        2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/DOM.pod        2026-05-21 
17:37:09.000000000 +0200
@@ -129,7 +129,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Devel.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Devel.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Devel.pm       2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Devel.pm       2026-05-21 
17:36:48.000000000 +0200
@@ -11,7 +11,7 @@
 
 use XML::LibXML;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use 5.008_000;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Document.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Document.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Document.pod   2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Document.pod   2026-05-21 
17:37:09.000000000 +0200
@@ -686,7 +686,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/XML-LibXML-2.0212/lib/XML/LibXML/DocumentFragment.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/DocumentFragment.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/DocumentFragment.pod   2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/DocumentFragment.pod   2026-05-21 
17:37:09.000000000 +0200
@@ -27,7 +27,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Dtd.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Dtd.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Dtd.pod        2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Dtd.pod        2026-05-21 
17:37:09.000000000 +0200
@@ -89,7 +89,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Element.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Element.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Element.pod    2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Element.pod    2026-05-21 
17:37:09.000000000 +0200
@@ -382,7 +382,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/ErrNo.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/ErrNo.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/ErrNo.pm       2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/ErrNo.pm       2026-05-21 
17:36:48.000000000 +0200
@@ -13,7 +13,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use constant ERR_OK                               => 0;
 use constant ERR_INTERNAL_ERROR                   => 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/ErrNo.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/ErrNo.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/ErrNo.pod      2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/ErrNo.pod      2026-05-21 
17:37:09.000000000 +0200
@@ -17,7 +17,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Error.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Error.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Error.pm       2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Error.pm       2026-05-21 
17:36:48.000000000 +0200
@@ -27,7 +27,7 @@
   fallback => 1;
 
 our $WARNINGS = 0; # 0: suppress, 1: report via warn, 2: report via die
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use constant XML_ERR_NONE            => 0;
 use constant XML_ERR_WARNING         => 1; # A simple warning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Error.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Error.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Error.pod      2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Error.pod      2026-05-21 
17:37:09.000000000 +0200
@@ -244,7 +244,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/InputCallback.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/InputCallback.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/InputCallback.pod      2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/InputCallback.pod      2026-05-21 
17:37:09.000000000 +0200
@@ -280,7 +280,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Literal.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Literal.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Literal.pm     2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Literal.pm     2026-05-21 
17:36:48.000000000 +0200
@@ -15,7 +15,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use overload
                '""' => \&value,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/NamedNodeMap.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/NamedNodeMap.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/NamedNodeMap.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/NamedNodeMap.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -98,7 +98,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Namespace.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Namespace.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Namespace.pod  2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Namespace.pod  2026-05-21 
17:37:09.000000000 +0200
@@ -141,7 +141,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Node.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Node.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Node.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Node.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -768,7 +768,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/NodeList.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/NodeList.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/NodeList.pm    2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/NodeList.pm    2026-05-21 
17:36:48.000000000 +0200
@@ -16,7 +16,7 @@
 use XML::LibXML::Literal;
 use XML::LibXML::Number;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use overload
         '""' => \&to_literal,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Number.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Number.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Number.pm      2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Number.pm      2026-05-21 
17:36:48.000000000 +0200
@@ -13,7 +13,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use overload
         '""' => \&value,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/PI.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/PI.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/PI.pod 2026-05-20 03:55:21.000000000 
+0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/PI.pod 2026-05-21 17:37:09.000000000 
+0200
@@ -74,7 +74,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Parser.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Parser.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Parser.pod     2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Parser.pod     2026-05-21 
17:37:09.000000000 +0200
@@ -988,7 +988,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Pattern.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Pattern.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Pattern.pod    2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Pattern.pod    2026-05-21 
17:37:09.000000000 +0200
@@ -94,7 +94,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Reader.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/Reader.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Reader.pm      2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Reader.pm      2026-05-21 
17:36:48.000000000 +0200
@@ -13,7 +13,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use 5.008_000;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Reader.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Reader.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Reader.pod     2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Reader.pod     2026-05-21 
17:37:09.000000000 +0200
@@ -657,7 +657,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/RegExp.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/RegExp.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/RegExp.pod     2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/RegExp.pod     2026-05-21 
17:37:09.000000000 +0200
@@ -58,7 +58,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/RelaxNG.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/RelaxNG.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/RelaxNG.pod    2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/RelaxNG.pod    2026-05-21 
17:37:09.000000000 +0200
@@ -73,7 +73,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Builder.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Builder.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Builder.pm 2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Builder.pm 2026-05-21 
17:36:48.000000000 +0200
@@ -19,7 +19,7 @@
   return $XML::LibXML::__threads_shared ? 0 : 1;
 }
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 sub new {
     my $class = shift;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Builder.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Builder.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Builder.pod        2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Builder.pod        2026-05-21 
17:37:09.000000000 +0200
@@ -38,7 +38,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Generator.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Generator.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Generator.pm       2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Generator.pm       2026-05-21 
17:36:48.000000000 +0200
@@ -14,7 +14,7 @@
 
 use XML::LibXML;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 sub CLONE_SKIP {
   return $XML::LibXML::__threads_shared ? 0 : 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Parser.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Parser.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX/Parser.pm  2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX/Parser.pm  2026-05-21 
17:36:48.000000000 +0200
@@ -17,7 +17,7 @@
 use XML::SAX::Base;
 use XML::SAX::DocumentLocator;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 our @ISA = ('XML::SAX::Base');
 
 sub CLONE_SKIP {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX.pm 2026-05-20 03:54:40.000000000 
+0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX.pm 2026-05-21 17:36:48.000000000 
+0200
@@ -12,7 +12,7 @@
 use strict;
 use warnings;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use XML::LibXML;
 use XML::SAX::Base;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/SAX.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/SAX.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/SAX.pod        2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/SAX.pod        2026-05-21 
17:37:09.000000000 +0200
@@ -47,7 +47,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Schema.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Schema.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Schema.pod     2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Schema.pod     2026-05-21 
17:37:09.000000000 +0200
@@ -69,7 +69,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/Text.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/Text.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/Text.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/Text.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -170,7 +170,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/XPathContext.pm 
new/XML-LibXML-2.0213/lib/XML/LibXML/XPathContext.pm
--- old/XML-LibXML-2.0212/lib/XML/LibXML/XPathContext.pm        2026-05-20 
03:54:40.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/XPathContext.pm        2026-05-21 
17:36:48.000000000 +0200
@@ -16,7 +16,7 @@
 use XML::LibXML;
 use XML::LibXML::NodeList;
 
-our $VERSION = "2.0212"; # VERSION TEMPLATE: DO NOT CHANGE
+our $VERSION = "2.0213"; # VERSION TEMPLATE: DO NOT CHANGE
 
 # should LibXML XPath data types be used for simple objects
 # when passing parameters to extension functions (default: no)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/XPathContext.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/XPathContext.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/XPathContext.pod       2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/XPathContext.pod       2026-05-21 
17:37:09.000000000 +0200
@@ -362,7 +362,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/lib/XML/LibXML/XPathExpression.pod 
new/XML-LibXML-2.0213/lib/XML/LibXML/XPathExpression.pod
--- old/XML-LibXML-2.0212/lib/XML/LibXML/XPathExpression.pod    2026-05-20 
03:55:21.000000000 +0200
+++ new/XML-LibXML-2.0213/lib/XML/LibXML/XPathExpression.pod    2026-05-21 
17:37:09.000000000 +0200
@@ -52,7 +52,7 @@
 
 =head1 VERSION
 
-2.0212
+2.0213
 
 =head1 COPYRIGHT
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/XML-LibXML-2.0212/t/49global_ext_nonet.t 
new/XML-LibXML-2.0213/t/49global_ext_nonet.t
--- old/XML-LibXML-2.0212/t/49global_ext_nonet.t        2026-05-07 
15:29:37.000000000 +0200
+++ new/XML-LibXML-2.0213/t/49global_ext_nonet.t        1970-01-01 
01:00:00.000000000 +0100
@@ -1,176 +0,0 @@
-use strict;
-use warnings;
-
-use Test::More;
-use XML::LibXML;
-
-if (XML::LibXML::LIBXML_VERSION() < 20627) {
-    plan skip_all => "skipping for libxml2 < 2.6.27";
-}
-else {
-    plan tests => 7;
-}
-
-my @loader_urls;
-
-sub tracking_loader {
-    push @loader_urls, $_[0];
-    return "ENTITY_CONTENT";
-}
-
-sub other_loader {
-    push @loader_urls, "other:" . $_[0];
-    return "OTHER_CONTENT";
-}
-
-# Set global entity loader
-XML::LibXML::externalEntityLoader(\&tracking_loader);
-
-# TEST
-# Sanity: global loader works for non-network entities
-{
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "file:///dev/null">
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    ok(defined $doc, "Global loader works for non-network entities");
-}
-
-# TEST
-# XML_PARSE_NONET blocks HTTP entities (libxml2 enforces this)
-{
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        no_network => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "http://example.com/entity.xml";>
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    my @net_calls = grep { /^https?:|^ftp:/ } @loader_urls;
-    is(scalar @net_calls, 0,
-       "no_network prevents global entity loader from receiving HTTP URLs");
-}
-
-# TEST
-# XML_PARSE_NONET blocks HTTPS entities
-{
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        no_network => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "https://example.com/entity.xml";>
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    my @net_calls = grep { /^https?:|^ftp:/ } @loader_urls;
-    is(scalar @net_calls, 0,
-       "no_network prevents global entity loader from receiving HTTPS URLs");
-}
-
-# TEST
-# XML_PARSE_NONET blocks FTP entities
-{
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        no_network => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "ftp://example.com/entity.xml";>
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    my @net_calls = grep { /^https?:|^ftp:/ } @loader_urls;
-    is(scalar @net_calls, 0,
-       "no_network prevents global entity loader from receiving FTP URLs");
-}
-
-# TEST
-# Without no_network, global loader should still receive network URLs
-{
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "http://example.com/entity.xml";>
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    my @net_calls = grep { /^https?:/ } @loader_urls;
-    ok(scalar @net_calls > 0,
-       "Without no_network, global loader receives network URLs normally");
-}
-
-# TEST
-# Global entity loader can be replaced
-{
-    XML::LibXML::externalEntityLoader(\&other_loader);
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "file:///dev/null">
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    my @other_calls = grep { /^other:/ } @loader_urls;
-    ok(scalar @other_calls > 0,
-       "Global entity loader can be updated to a new callback");
-}
-
-# TEST
-# Global entity loader can be cleared
-{
-    XML::LibXML::externalEntityLoader(undef);
-    @loader_urls = ();
-    my $parser = XML::LibXML->new({
-        expand_entities => 1,
-        load_ext_dtd => 1,
-    });
-    my $xml = <<'EOF';
-<?xml version="1.0"?>
-<!DOCTYPE foo [
-<!ENTITY a SYSTEM "file:///dev/null">
-]>
-<root>&a;</root>
-EOF
-    my $doc = eval { $parser->parse_string($xml) };
-    is(scalar @loader_urls, 0,
-       "After clearing global loader, callbacks are no longer invoked");
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/XML-LibXML-2.0212/t/49global_extent_with_no_network.t 
new/XML-LibXML-2.0213/t/49global_extent_with_no_network.t
--- old/XML-LibXML-2.0212/t/49global_extent_with_no_network.t   1970-01-01 
01:00:00.000000000 +0100
+++ new/XML-LibXML-2.0213/t/49global_extent_with_no_network.t   2026-05-20 
19:20:14.000000000 +0200
@@ -0,0 +1,482 @@
+use strict;
+use warnings;
+
+# Contract enforced here (see CLAUDE.md "Entity loaders"):
+#   externalEntityLoader(\&cb) is an explicit opt-out of libxml2's network
+#   policy. Once installed, the callback receives every external-entity URL,
+#   including network URLs, *regardless* of no_network on the parser.
+#
+# This file locks that contract in across:
+#   - plain XML parsing (DTD entity references)
+#   - RelaxNG parsing (<include href="http://..."/>)
+#   - XML Schema parsing (<xs:import schemaLocation="http://..."/>)
+#
+# and the inverse: when no loader is installed, no_network still blocks
+# network URLs through libxml2's default loader.
+#
+# Regression target: GH #143 (reverted), which both filtered URLs inside
+# LibXML_load_external_entity and removed the EXTERNAL_ENTITY_LOADER_FUNC
+# guards on the 5 Schema/RelaxNG NONET swap sites.
+
+use Test::More;
+use XML::LibXML;
+
+if (XML::LibXML::LIBXML_VERSION() < 20627) {
+    plan skip_all => "skipping for libxml2 < 2.6.27";
+}
+else {
+    plan tests => 17;
+}
+
+# Always tear down between subtests so process-global state never leaks.
+sub _reset_global_loader {
+    XML::LibXML::externalEntityLoader(undef);
+}
+
+# ---------------------------------------------------------------------------
+# Plain-parse XML fixtures
+# ---------------------------------------------------------------------------
+
+my $xml_http = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY a SYSTEM "http:///invalid-url-http";>
+]>
+<root>&a;</root>
+EOF
+
+my $xml_https = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY a SYSTEM "https:///invalid-url-https";>
+]>
+<root>&a;</root>
+EOF
+
+my $xml_ftp = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY a SYSTEM "ftp:///invalid-url-ftp";>
+]>
+<root>&a;</root>
+EOF
+
+my $xml_mixed_schemes = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY g SYSTEM "gopher://example.invalid/g";>
+<!ENTITY d SYSTEM "dict://example.invalid/d">
+<!ENTITY x SYSTEM "xmpp://example.invalid/x">
+]>
+<root><a>&g;</a><b>&d;</b><c>&x;</c></root>
+EOF
+
+my $xml_multi = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY a SYSTEM "http:///url-a";>
+<!ENTITY b SYSTEM "https:///url-b";>
+<!ENTITY c SYSTEM "ftp:///url-c";>
+]>
+<root><x>&a;</x><y>&b;</y><z>&c;</z></root>
+EOF
+
+my $xml_public = <<'EOF';
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY p PUBLIC "//public/id" "http:///system-url";>
+]>
+<root>&p;</root>
+EOF
+
+# ---------------------------------------------------------------------------
+# 1. http:// entity reaches the global loader when no_network is set
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives http:// URL despite no_network" => sub {
+    plan tests => 3;
+    my $got_url;
+    XML::LibXML::externalEntityLoader(sub {
+        my ($url, $id) = @_;
+        $got_url = $url;
+        return "<!-- loaded -->";
+    });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    my $doc;
+    my $err = do { local $@; eval { $doc = $parser->parse_string($xml_http) }; 
$@ };
+    is($err, '', "no error when loader handles the URL");
+    is($got_url, 'http:///invalid-url-http', "loader received the http URL");
+    like($doc && $doc->toString(), qr/loaded/, "loader content was 
substituted");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 2. https:// entity reaches the global loader when no_network is set
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives https:// URL despite no_network" => sub {
+    plan tests => 2;
+    my $got_url;
+    XML::LibXML::externalEntityLoader(sub { $got_url = $_[0]; return "<!-- ok 
-->" });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $parser->parse_string($xml_https) };
+    is($@, '', "no error");
+    is($got_url, 'https:///invalid-url-https', "loader received the https 
URL");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 3. ftp:// entity reaches the global loader when no_network is set
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives ftp:// URL despite no_network" => sub {
+    plan tests => 2;
+    my $got_url;
+    XML::LibXML::externalEntityLoader(sub { $got_url = $_[0]; return "<!-- ok 
-->" });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $parser->parse_string($xml_ftp) };
+    is($@, '', "no error");
+    is($got_url, 'ftp:///invalid-url-ftp', "loader received the ftp URL");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 4. Schemes outside http/https/ftp also reach the loader (no scheme allowlist
+#    should exist anywhere in the dispatch path).
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives non-http schemes too" => sub {
+    plan tests => 4;
+    my @urls;
+    XML::LibXML::externalEntityLoader(sub { push @urls, $_[0]; return "<!-- ok 
-->" });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $parser->parse_string($xml_mixed_schemes) };
+    is($@, '', "no error");
+    ok((grep { $_ eq 'gopher://example.invalid/g' } @urls), "gopher URL 
reached loader");
+    ok((grep { $_ eq 'dict://example.invalid/d' }   @urls), "dict URL reached 
loader");
+    ok((grep { $_ eq 'xmpp://example.invalid/x' }   @urls), "xmpp URL reached 
loader");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 5. All entity URLs in a single document reach the loader.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives every entity URL in one document" => sub {
+    plan tests => 5;
+    my @urls;
+    XML::LibXML::externalEntityLoader(sub {
+        push @urls, $_[0];
+        my $tag = $_[0];
+        $tag =~ s{[^A-Za-z0-9]+}{_}g;
+        return "<v>$tag</v>";
+    });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    my $doc;
+    eval { $doc = $parser->parse_string($xml_multi) };
+    is($@, '', "no error");
+    is(scalar(@urls), 3, "loader called once per external entity");
+    ok((grep { $_ eq 'http:///url-a'  } @urls), "url-a reached loader");
+    ok((grep { $_ eq 'https:///url-b' } @urls), "url-b reached loader");
+    ok((grep { $_ eq 'ftp:///url-c'   } @urls), "url-c reached loader");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 6. PUBLIC identifiers are passed alongside the SYSTEM URL.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader receives PUBLIC id with no_network" => sub {
+    plan tests => 3;
+    my ($url, $pubid);
+    XML::LibXML::externalEntityLoader(sub {
+        ($url, $pubid) = @_;
+        return "<!-- ok -->";
+    });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $parser->parse_string($xml_public) };
+    is($@, '', "no error");
+    is($url,   'http:///system-url', "loader received the SYSTEM URL");
+    is($pubid, '//public/id',        "loader received the PUBLIC identifier");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 7. Loader exceptions propagate.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "loader croak propagates through libxml2 with no_network" => sub {
+    plan tests => 2;
+    XML::LibXML::externalEntityLoader(sub { die "loader-boom\n" });
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    my $doc;
+    eval { $doc = $parser->parse_string($xml_http) };
+    ok($@, "parse failed");
+    is($doc, undef, "doc not produced");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 8. Per-parser ext_ent_handler still receives network URLs under no_network.
+#    (The contract applies to per-parser handlers too: ext_ent_handler is also
+#    an explicit opt-in by the user.)
+# ---------------------------------------------------------------------------
+# TEST
+subtest "per-parser ext_ent_handler receives http URL under no_network" => sub 
{
+    plan tests => 2;
+    my $got_url;
+    my $parser = XML::LibXML->new({
+        expand_entities => 1,
+        no_network      => 1,
+        ext_ent_handler => sub { $got_url = $_[0]; return "<!-- ok -->" },
+    });
+    eval { $parser->parse_string($xml_http) };
+    is($@, '', "no error");
+    is($got_url, 'http:///invalid-url-http', "per-parser handler received the 
http URL");
+    # no global loader was set, so nothing to reset
+};
+
+# ---------------------------------------------------------------------------
+# 9. Global loader overrides per-parser handler when both are set + no_network.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "global loader takes precedence over ext_ent_handler under no_network" 
=> sub {
+    plan tests => 3;
+    my ($global_called, $private_called) = (0, 0);
+    XML::LibXML::externalEntityLoader(sub { $global_called++; return "<g/>" });
+    my $parser = XML::LibXML->new({
+        expand_entities => 1,
+        no_network      => 1,
+        ext_ent_handler => sub { $private_called++; return "<p/>" },
+    });
+    my $doc;
+    eval { $doc = $parser->parse_string($xml_http) };
+    is($@, '', "no error");
+    is($global_called,  1, "global loader was invoked");
+    is($private_called, 0, "per-parser handler was not invoked");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 10. After clearing the global loader, no_network blocks network URLs again.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "no_network blocks network URLs once the global loader is cleared" => 
sub {
+    plan tests => 3;
+    # Install, parse, clear.
+    XML::LibXML::externalEntityLoader(sub { return "<!-- ok -->" });
+    my $p1 = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $p1->parse_string($xml_http) };
+    is($@, '', "global loader handled the URL while installed");
+
+    _reset_global_loader();
+
+    my $p2 = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    my $doc;
+    eval { $doc = $p2->parse_string($xml_http) };
+    ok($@,            "no_network now blocks the network entity");
+    is($doc, undef,  "doc not produced after clearing the loader");
+};
+
+# ---------------------------------------------------------------------------
+# 11. set -> clear -> set cycle, each phase under no_network.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "set/clear/set cycle preserves the contract on each phase" => sub {
+    plan tests => 5;
+    my $calls = 0;
+    XML::LibXML::externalEntityLoader(sub { $calls++; return "<!-- ok -->" });
+
+    my $p_a = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $p_a->parse_string($xml_http) };
+    is($@,     '', "phase 1: loader installed - parse OK");
+    is($calls, 1,  "phase 1: loader invoked once");
+
+    _reset_global_loader();
+    my $p_b = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $p_b->parse_string($xml_http) };
+    ok($@, "phase 2: loader cleared - parse fails");
+
+    XML::LibXML::externalEntityLoader(sub { $calls++; return "<!-- ok again 
-->" });
+    my $p_c = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    eval { $p_c->parse_string($xml_http) };
+    is($@,     '', "phase 3: loader reinstalled - parse OK");
+    is($calls, 2,  "phase 3: loader invoked again");
+
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 12. Baseline regression check: no_network without any loader still blocks.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "no_network + no loader still blocks network URLs (default-loader 
path)" => sub {
+    plan tests => 2;
+    _reset_global_loader();   # paranoia in case a prior test leaked
+    my $parser = XML::LibXML->new({ expand_entities => 1, no_network => 1 });
+    my $doc;
+    eval { $doc = $parser->parse_string($xml_http) };
+    ok($@,           "parse fails with no_network and no callback");
+    is($doc, undef, "no doc produced");
+};
+
+# ---------------------------------------------------------------------------
+# Schema / RelaxNG fixtures.
+# Use string=> so the only entity load is the http:// include/import — that's
+# the path the EXTERNAL_ENTITY_LOADER_FUNC guard at the 5 NONET swap sites in
+# LibXML.xs protects.
+# ---------------------------------------------------------------------------
+my $rng_with_http_include = <<'EOF';
+<?xml version="1.0" encoding="iso-8859-1"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0";>
+  <include href="http://example.invalid/inner.rng"/>
+  <start><ref name="root"/></start>
+</grammar>
+EOF
+
+my $rng_included = <<'EOF';
+<?xml version="1.0" encoding="iso-8859-1"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0";>
+  <define name="root">
+    <element name="root"><text/></element>
+  </define>
+</grammar>
+EOF
+
+my $xsd_with_http_import = <<'EOF';
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+            xmlns:ext="http://example.invalid/ns";>
+  <xsd:import namespace="http://example.invalid/ns";
+              schemaLocation="http://example.invalid/inner.xsd"/>
+  <xsd:element name="root" type="xsd:string"/>
+</xsd:schema>
+EOF
+
+my $xsd_imported = <<'EOF';
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+            targetNamespace="http://example.invalid/ns";>
+  <xsd:element name="ext" type="xsd:string"/>
+</xsd:schema>
+EOF
+
+# ---------------------------------------------------------------------------
+# 13. RelaxNG: no_network + no loader - the http include is blocked.
+#     Regression check that we didn't break the default-loader path.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "RelaxNG no_network + no loader blocks http include" => sub {
+    plan tests => 2;
+    _reset_global_loader();
+    my $rng = eval {
+        XML::LibXML::RelaxNG->new(string => $rng_with_http_include, no_network 
=> 1)
+    };
+    ok($@,           "RelaxNG parse failed");
+    is($rng, undef, "no RelaxNG produced");
+};
+
+# ---------------------------------------------------------------------------
+# 14. RelaxNG: no_network + global loader - the http include reaches the 
loader.
+#     This is the test that locks in the EXTERNAL_ENTITY_LOADER_FUNC guard at
+#     the 2 RelaxNG NONET swap sites in LibXML.xs.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "RelaxNG no_network + global loader: include URL reaches loader" => 
sub {
+    plan tests => 3;
+    my @urls;
+    XML::LibXML::externalEntityLoader(sub {
+        my ($url) = @_;
+        push @urls, $url;
+        return $rng_included if $url eq 'http://example.invalid/inner.rng';
+        return "";
+    });
+    my $rng = eval {
+        XML::LibXML::RelaxNG->new(string => $rng_with_http_include, no_network 
=> 1)
+    };
+    is($@, '', "RelaxNG parse succeeded with global loader");
+    ok(defined $rng, "RelaxNG object created");
+    ok((grep { $_ eq 'http://example.invalid/inner.rng' } @urls),
+        "loader received the http include URL during RelaxNG parsing");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 15. Schema: no_network + no loader - the http import is blocked.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "Schema no_network + no loader blocks http import" => sub {
+    plan tests => 2;
+    _reset_global_loader();
+    my $xsd = eval {
+        XML::LibXML::Schema->new(string => $xsd_with_http_import, no_network 
=> 1)
+    };
+    ok($@,           "Schema parse failed");
+    is($xsd, undef, "no Schema produced");
+};
+
+# ---------------------------------------------------------------------------
+# 16. Schema: no_network + global loader - the http import reaches the loader.
+#     Locks in the EXTERNAL_ENTITY_LOADER_FUNC guard at the 3 Schema NONET swap
+#     sites in LibXML.xs.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "Schema no_network + global loader: import URL reaches loader" => sub {
+    plan tests => 3;
+    my @urls;
+    XML::LibXML::externalEntityLoader(sub {
+        my ($url) = @_;
+        push @urls, $url;
+        return $xsd_imported if $url eq 'http://example.invalid/inner.xsd';
+        return "";
+    });
+    my $xsd = eval {
+        XML::LibXML::Schema->new(string => $xsd_with_http_import, no_network 
=> 1)
+    };
+    is($@, '', "Schema parse succeeded with global loader");
+    ok(defined $xsd, "Schema object created");
+    ok((grep { $_ eq 'http://example.invalid/inner.xsd' } @urls),
+        "loader received the http import URL during Schema parsing");
+    _reset_global_loader();
+};
+
+# ---------------------------------------------------------------------------
+# 17. Schema/RelaxNG cleanup symmetry: after clearing the global loader,
+#     no_network blocks Schema/RelaxNG network imports again. Proves the
+#     NONET-swap restore path still works once the guard is no longer engaged.
+# ---------------------------------------------------------------------------
+# TEST
+subtest "after clearing global loader, Schema/RelaxNG no_network blocks again" 
=> sub {
+    plan tests => 4;
+
+    XML::LibXML::externalEntityLoader(sub { return $rng_included });
+    my $ok_rng = eval {
+        XML::LibXML::RelaxNG->new(string => $rng_with_http_include, no_network 
=> 1)
+    };
+    ok(defined $ok_rng, "RelaxNG built while loader was installed");
+
+    _reset_global_loader();
+
+    my $bad_rng = eval {
+        XML::LibXML::RelaxNG->new(string => $rng_with_http_include, no_network 
=> 1)
+    };
+    ok(!defined $bad_rng, "RelaxNG blocked after loader cleared");
+
+    XML::LibXML::externalEntityLoader(sub { return $xsd_imported });
+    my $ok_xsd = eval {
+        XML::LibXML::Schema->new(string => $xsd_with_http_import, no_network 
=> 1)
+    };
+    ok(defined $ok_xsd, "Schema built while loader was installed");
+
+    _reset_global_loader();
+
+    my $bad_xsd = eval {
+        XML::LibXML::Schema->new(string => $xsd_with_http_import, no_network 
=> 1)
+    };
+    ok(!defined $bad_xsd, "Schema blocked after loader cleared");
+};
+
+END {
+    # Final paranoia: never leave a global loader installed after this file.
+    eval { XML::LibXML::externalEntityLoader(undef) };
+}

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.tjFGws/_old  2026-06-09 14:14:19.189715283 +0200
+++ /var/tmp/diff_new_pack.tjFGws/_new  2026-06-09 14:14:19.193715451 +0200
@@ -1,6 +1,6 @@
-mtime: 1779378655
-commit: ab3bce54a52301e19c9a290738defa99ac442ee91561140c70fa8a3984e778fd
+mtime: 1780787946
+commit: 0bbd5cd0878d12dd8d73e4bf42e942b02a5c20280c57327708e5203c4046dafc
 url: https://src.opensuse.org/perl/perl-XML-LibXML
-revision: ab3bce54a52301e19c9a290738defa99ac442ee91561140c70fa8a3984e778fd
+revision: 0bbd5cd0878d12dd8d73e4bf42e942b02a5c20280c57327708e5203c4046dafc
 projectscmsync: https://src.opensuse.org/perl/_ObsPrj
 

++++++ build.specials.obscpio ++++++

++++++ 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-06-07 01:19:06.000000000 +0200
@@ -0,0 +1 @@
+.osc

Reply via email to