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

Report information
The Basics
Id:
60313
Status:
resolved
Priority:
Low/Low
Queue:

People
Owner:
Nobody in particular
Requestors:
NWELLNHOF [...] cpan.org
Cc:
AdminCc:

BugTracker
Severity:
(no value)
Broken in:
(no value)
Fixed in:
1.89



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; }
Fixed in 1.89.


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.