Subject: | Input callbacks registered twice |
XML::LibXSLT registers input callbacks a second time after XML::LibXML
already registered them. So the match callback is called a twice if it
returns false. Attached is a patch with a fix and a test case.
Subject: | double-callback.diff |
diff --git a/LibXSLT.pm b/LibXSLT.pm
index de5b1d4..945b42d 100644
--- a/LibXSLT.pm
+++ b/LibXSLT.pm
@@ -227,7 +227,6 @@ sub _init_callbacks{
$icb->register_callbacks( [$mcb, $ocb, $rcb, $ccb] );
}
- $self->lib_init_callbacks();
$icb->init_callbacks();
}
@@ -431,7 +430,6 @@ sub _init_callbacks {
if ( defined $mcb and defined $ocb and defined $rcb and defined $ccb ) {
$icb->register_callbacks( [$mcb, $ocb, $rcb, $ccb] );
}
- $self->XML::LibXSLT::lib_init_callbacks();
$icb->init_callbacks();
my $scb = $self->{XML_LIBXSLT_SECPREFS};
diff --git a/LibXSLT.xs b/LibXSLT.xs
index d79b83a..460af03 100644
--- a/LibXSLT.xs
+++ b/LibXSLT.xs
@@ -447,186 +447,6 @@ FINISH:
int
-LibXSLT_input_match(char const * filename)
-{
- int results;
- int count;
- SV * res;
-
- results = 0;
-
- {
- dTHX;
- dSP;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv((char*)filename, 0)));
- PUTBACK;
-
- count = call_pv("XML::LibXML::InputCallback::_callback_match",
- G_SCALAR | G_EVAL);
-
- SPAGAIN;
-
- if (count != 1) {
- croak("match callback must return a single value");
- }
-
- if (SvTRUE(ERRSV)) {
- (void) POPs ;
- croak("input match callback died: %s", SvPV_nolen(ERRSV));
- }
-
- res = POPs;
-
- if (SvTRUE(res)) {
- results = 1;
- }
-
- PUTBACK;
- FREETMPS;
- LEAVE;
- }
- return results;
-}
-
-void *
-LibXSLT_input_open(char const * filename)
-{
- SV * results;
- int count;
-
- dTHX;
- dSP;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv((char*)filename, 0)));
- PUTBACK;
-
- count = call_pv("XML::LibXML::InputCallback::_callback_open",
- G_SCALAR | G_EVAL);
-
- SPAGAIN;
-
- if (count != 1) {
- croak("open callback must return a single value");
- }
-
- if (SvTRUE(ERRSV)) {
- (void) POPs ;
- croak("input callback died: %s", SvPV_nolen(ERRSV));
- }
-
- results = POPs;
-
- SvREFCNT_inc(results);
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return (void *)results;
-}
-
-int
-LibXSLT_input_read(void * context, char * buffer, int len)
-{
- STRLEN res_len;
- const char * output;
- SV * ctxt;
-
- res_len = 0;
- ctxt = (SV *)context;
-
- {
- int count;
-
- dTHX;
- dSP;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- EXTEND(SP, 2);
- PUSHs(ctxt);
- PUSHs(sv_2mortal(newSViv(len)));
- PUTBACK;
-
- count = call_pv("XML::LibXML::InputCallback::_callback_read",
- G_SCALAR | G_EVAL);
-
- SPAGAIN;
-
- if (count != 1) {
- croak("read callback must return a single value");
- }
-
- if (SvTRUE(ERRSV)) {
- (void) POPs ;
- croak("read callback died: %s", SvPV_nolen(ERRSV));
- }
-
- output = POPp;
- if (output != NULL) {
- res_len = strlen(output);
- if (res_len) {
- strncpy(buffer, output, res_len);
- }
- else {
- buffer[0] = 0;
- }
- }
-
- PUTBACK;
- FREETMPS;
- LEAVE;
- }
- return res_len;
-}
-
-void
-LibXSLT_input_close(void * context)
-{
- SV * ctxt;
-
- ctxt = (SV *)context;
-
- {
- dTHX;
- dSP;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- EXTEND(SP, 1);
- PUSHs(ctxt);
- PUTBACK;
-
- call_pv("XML::LibXML::InputCallback::_callback_close",
- G_SCALAR | G_EVAL | G_DISCARD);
-
- SvREFCNT_dec(ctxt);
-
- if (SvTRUE(ERRSV)) {
- croak("close callback died: %s", SvPV_nolen(ERRSV));
- }
-
- FREETMPS;
- LEAVE;
- }
-}
-
-int
LibXSLT_security_check(xsltSecurityOption option,
xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
@@ -934,24 +754,6 @@ _parse_stylesheet_file(self, filename)
RETVAL
void
-lib_init_callbacks( self )
- SV * self
- CODE:
- PERL_UNUSED_VAR(self);
- xmlRegisterInputCallbacks((xmlInputMatchCallback) LibXSLT_input_match,
- (xmlInputOpenCallback) LibXSLT_input_open,
- (xmlInputReadCallback) LibXSLT_input_read,
- (xmlInputCloseCallback) LibXSLT_input_close);
-
-void
-lib_cleanup_callbacks( self )
- SV * self
- CODE:
- PERL_UNUSED_VAR(self);
- xmlCleanupInputCallbacks();
- xmlRegisterDefaultInputCallbacks();
-
-void
INIT_THREAD_SUPPORT()
CODE:
if (x_PROXY_NODE_REGISTRY_MUTEX != NULL) {
diff --git a/t/03input.t b/t/03input.t
index 4664ebe..d972730 100644
--- a/t/03input.t
+++ b/t/03input.t
@@ -1,5 +1,5 @@
use Test;
-BEGIN { plan tests => 25 }
+BEGIN { plan tests => 26 }
use XML::LibXSLT;
use XML::LibXML 1.59;
@@ -29,6 +29,7 @@ my $stylsheetstring = <<'EOT';
<body>
<h1><xsl:apply-templates/></h1>
<p>foo: <xsl:apply-templates select="document('foo.xml')/*" /></p>
+ <p>foo: <xsl:apply-templates select="document('example/1.xml')/foo" /></p>
</body>
</html>
</xsl:template>
@@ -44,7 +45,9 @@ $icb->register_callbacks( [ \&match_cb, \&open_cb,
\&read_cb, \&close_cb ] );
$xslt->input_callbacks($icb);
-
+
+our $no_match_count = 0;
+
my $stylesheet = $xslt->parse_stylesheet($parser->parse_string($stylsheetstring));
print "# stylesheet\n";
ok($stylesheet);
@@ -61,6 +64,9 @@ my $output = $stylesheet->output_string($results);
print "# output\n";
ok($output);
+print "# no match count\n";
+ok($no_match_count == 1);
+
# test a dying close callback
# callbacks can only be registered as a callback group
$stylesheet->match_callback( \&match_cb );
@@ -172,6 +178,7 @@ sub match_cb {
ok(1);
return 1;
}
+ ++$no_match_count if $uri eq "example/1.xml";
return 0;
}