I have a simple patch adding function XML::LibXML::externalEntityLoader
for setting a global entity loader handler for whole app.
Unlike existing functionality (ext_ent_handler parser option), this
entity loader handler works also for libXSLT processing (in
import,include and document()) and others libraries using
xml*ExternalEntityLoader() functions for processing external entities.
Subject: | perl-XML LibXML+global_entity_loader-0.2.diff |
diff -ur XML-LibXML-1.75/LibXML.pm XML-LibXML-1.75-new/LibXML.pm
--- XML-LibXML-1.75/LibXML.pm 2011-06-24 18:56:47.000000000 +0200
+++ XML-LibXML-1.75-new/LibXML.pm 2011-06-28 21:47:58.000000000 +0200
@@ -443,6 +443,12 @@
# callback functions #
#-------------------------------------------------------------------------#
+use Data::Dumper;
+sub externalEntityLoader(&)
+{
+ return _externalEntityLoader($_[0]);
+}
+
sub input_callbacks {
my $self = shift;
my $icbclass = shift;
diff -ur XML-LibXML-1.75/LibXML.xs XML-LibXML-1.75-new/LibXML.xs
--- XML-LibXML-1.75/LibXML.xs 2011-06-24 18:38:46.000000000 +0200
+++ XML-LibXML-1.75-new/LibXML.xs 2011-06-28 21:47:58.000000000 +0200
@@ -146,6 +146,9 @@
/* this should keep the default */
static xmlExternalEntityLoader LibXML_old_ext_ent_loader = NULL;
+/* global external entity loader */
+SV *EXTERNAL_ENTITY_LOADER_FUNC = (SV *)NULL;
+
SV* PROXY_NODE_REGISTRY_MUTEX = NULL;
/* ****************************************************************
@@ -778,8 +781,7 @@
const char * ID,
xmlParserCtxtPtr ctxt)
{
- SV * self;
- HV * real_obj;
+
SV ** func;
int count;
SV * results;
@@ -787,7 +789,8 @@
const char * results_pv;
xmlParserInputBufferPtr input_buf;
- if (ctxt->_private == NULL) {
+ if (ctxt->_private == NULL
+ && EXTERNAL_ENTITY_LOADER_FUNC == NULL) {
return xmlNewInputFromFile(ctxt, URL);
}
@@ -798,11 +801,22 @@
ID = "";
}
- self = (SV *)ctxt->_private;
- real_obj = (HV *)SvRV(self);
- func = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
+ /* fetch entity loader function */
+ if(EXTERNAL_ENTITY_LOADER_FUNC != NULL)
+ {
+ func = &EXTERNAL_ENTITY_LOADER_FUNC;
+ }
+ else
+ {
+ SV * self;
+ HV * real_obj;
+
+ self = (SV *)ctxt->_private;
+ real_obj = (HV *)SvRV(self);
+ func = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
+ }
- if (func != NULL && SvTRUE(*func)) {
+ if (func != NULL && SvTRUE(*func)) {
dTHX;
dSP;
@@ -899,18 +913,21 @@
if (ctxt) ctxt->linenumbers = 0;
}
- item = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
- if ( item != NULL && SvTRUE(*item)) {
- LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader();
- xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_load_external_entity );
- }
- else {
- if (parserOptions & XML_PARSE_NONET) {
- LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader();
- xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
- }
- /* LibXML_old_ext_ent_loader = NULL; */
- }
+ if(LibXML_old_ext_ent_loader == NULL)
+ {
+ item = hv_fetch(real_obj, "ext_ent_handler", 15, 0);
+ if (item != NULL && SvTRUE(*item)) {
+ LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader();
+ xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_load_external_entity );
+ }
+ else {
+ if (parserOptions & XML_PARSE_NONET) {
+ LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader();
+ xmlSetExternalEntityLoader( xmlNoNetExternalEntityLoader );
+ }
+ /* LibXML_old_ext_ent_loader = NULL; */
+ }
+ }
}
return real_obj;
@@ -921,7 +938,8 @@
#ifndef WITH_SERRORS
xmlGetWarningsDefaultValue = 0;
#endif
- if (LibXML_old_ext_ent_loader != NULL ) {
+ if (EXTERNAL_ENTITY_LOADER_FUNC == NULL
+ && LibXML_old_ext_ent_loader != NULL) {
xmlSetExternalEntityLoader( (xmlExternalEntityLoader)LibXML_old_ext_ent_loader );
}
}
@@ -2642,6 +2660,27 @@
OUTPUT:
RETVAL
+SV*
+_externalEntityLoader( loader )
+ SV* loader
+ CODE:
+ {
+ RETVAL = EXTERNAL_ENTITY_LOADER_FUNC;
+ if(EXTERNAL_ENTITY_LOADER_FUNC == NULL)
+ EXTERNAL_ENTITY_LOADER_FUNC = newSVsv(loader);
+/*
+ else
+ SvSetSv(EXTERNAL_ENTITY_LOADER_FUNC, loader);
+*/
+
+ if (LibXML_old_ext_ent_loader == NULL ) {
+ LibXML_old_ext_ent_loader = xmlGetExternalEntityLoader();
+ xmlSetExternalEntityLoader((xmlExternalEntityLoader)LibXML_load_external_entity);
+ }
+ }
+ OUTPUT:
+ RETVAL
+
MODULE = XML::LibXML PACKAGE = XML::LibXML::HashTable
xmlHashTablePtr
@@ -9401,4 +9440,3 @@
#endif
OUTPUT:
RETVAL
-
diff -ur XML-LibXML-1.75/lib/XML/LibXML/Parser.pod XML-LibXML-1.75-new/lib/XML/LibXML/Parser.pod
--- XML-LibXML-1.75/lib/XML/LibXML/Parser.pod 2011-06-24 18:57:22.000000000 +0200
+++ XML-LibXML-1.75-new/lib/XML/LibXML/Parser.pod 2011-06-28 22:15:57.000000000 +0200
@@ -71,6 +71,11 @@
$parser->load_catalog( $catalog_file );
+ # Global external entity loader (similar to ext_ent_handler option
+ # but this works really globally, also in XML::LibXSLT include etc..)
+
+ XML::LibXML::externalEntityLoader(&my_loader);
+
=head1 PARSING
A XML document is read into a data structure such as a DOM tree by a piece of