Subject: | [PATCH] Fix bad markstack handling |
See the attached patch. If you are using git, you should be able to feed this straight to ‘git am’. If not, you can copy the commit message from the top of the file.
BTW, this bug causes RDF::Trine to fail its tests under perl 5.19.6 and up. See also <https://rt.perl.org/Ticket/Display.html?id=120626>.
Subject: | patch.text |
From: Father Chrysostomos <sprout@cpan.org>
Fix markstack handling in BOOT
The BOOT section of an XS module is itself an XSUB body, which gets an
implicit dXSARGS when compiled. dXSARGS implied POPMARK, which pops
the markstack, which keeps track of how many arguments are in the cur-
rent list, and where they begin. If we call the XSUB body generated
from another BOOT section, we end up popping two marks, one of which
does not belong to us, corrupting the perl mark stack, and result-
ing in this:
$ perl5.19.9 -e 'for(1) { for (1,0) { require XML::LibXML } }'
Invalid version format (non-numeric data) at /usr/local/lib/perl5/5.19.9/darwin-2level/DynaLoader.pm line 217.
BEGIN failed--compilation aborted at /usr/local/lib/perl5/site_perl/5.19.9/darwin-2level/XML/LibXML.pm line 154.
Compilation failed in require at -e line 1.
A change to perl (v5.19.6-22-gebdc880) just happens to change the way
things are arranged, such that this bug pops its head up.
diff -Nurp XML-LibXML-2.0108-D6JTfj-orig/LibXML.xs XML-LibXML-2.0108-D6JTfj/LibXML.xs
--- XML-LibXML-2.0108-D6JTfj-orig/LibXML.xs 2013-10-25 02:48:26.000000000 -0700
+++ XML-LibXML-2.0108-D6JTfj/LibXML.xs 2014-01-30 22:19:30.000000000 -0800
@@ -1486,6 +1486,10 @@ PROTOTYPES: DISABLE
BOOT:
/* Load Devel first, so debug_memory can
be called before any allocation. */
+ PL_markstack_ptr++; /* a bit hacky, but boot_blahblah_Devel, being an
+ XSUB body, will try to pop once more the mark
+ we have just (implicitly) popped, this boot
+ sector also being an XSUB body */
boot_XML__LibXML__Devel(aTHX_ cv);
LIBXML_TEST_VERSION
xmlInitParser();
diff -Nurp XML-LibXML-2.0108-D6JTfj-orig/MANIFEST XML-LibXML-2.0108-D6JTfj/MANIFEST
--- XML-LibXML-2.0108-D6JTfj-orig/MANIFEST 2013-12-17 01:09:22.000000000 -0800
+++ XML-LibXML-2.0108-D6JTfj/MANIFEST 2014-01-30 22:03:38.000000000 -0800
@@ -178,6 +178,7 @@ t/72destruction.t
t/80registryleak.t
t/90threads.t
t/91unique_key.t
+t/92stack.t
t/data/callbacks_returning_undef.xml
t/lib/Collector.pm
t/lib/Counter.pm
diff -Nurp XML-LibXML-2.0108-D6JTfj-orig/t/92stack.t XML-LibXML-2.0108-D6JTfj/t/92stack.t
--- XML-LibXML-2.0108-D6JTfj-orig/t/92stack.t 1969-12-31 16:00:00.000000000 -0800
+++ XML-LibXML-2.0108-D6JTfj/t/92stack.t 2014-01-30 22:06:31.000000000 -0800
@@ -0,0 +1,17 @@
+# -*- cperl -*-
+# $Id$
+
+##
+# This test checks that the XS code handles the perl stack correctly
+# when the module loads. This failed in 5.19.6+.
+
+use Test::More tests => 1;
+
+for (1) {
+ for (1,0) {
+ require XML::LibXML;
+ }
+}
+
+# If we get this far, then all is fine.
+pass("Loading XML::LibXML works inside multiple foreach loops");