Subject: | [PATCH] Protect active parser from being freed. |
This is a follow-up to <http://www.nntp.perl.org/group/perl.libwww/;msgid=7A27BD12-BA67-40B7-9052-334CCE2C14DA@cpan.org>, from 6 years ago, but this time with a patch!
If you try to free the parser from a callback, it crashes, because pstate gets freed while things in the parser are still referring to it.
Subject: | open_TtcpFITu.txt |
diff -Nurp a/MANIFEST b/MANIFEST
--- ./MANIFEST 2016-01-19 09:41:33.000000000 -0800
+++ /Users/sprout/perl/hpbug/HTML-Parser-3.72-4YaB9L/MANIFEST 2016-06-03 06:24:18.000000000 -0700
@@ -43,6 +43,7 @@ t/entities.t Test encoding/decoding of
t/entities2.t Test _decode_entities()
t/filter-methods.t Test ignore_tags, ignore_elements methods.
t/filter.t Test HTML::Filter
+t/free.t Test freeing of active parser
t/handler-eof.t Test invocation of $p->eof in handlers
t/handler.t Test $p->handler method
t/headparser-http.t Test HTML::HeadParser
diff -Nurp ./Parser.xs /Users/sprout/perl/hpbug/HTML-Parser-3.72-4YaB9L/Parser.xs
--- ./Parser.xs 2016-01-19 07:18:18.000000000 -0800
+++ /Users/sprout/perl/hpbug/HTML-Parser-3.72-4YaB9L/Parser.xs 2016-06-03 06:26:37.000000000 -0700
@@ -377,6 +377,7 @@ parse(self, chunk)
PREINIT:
PSTATE* p_state = get_pstate_hv(aTHX_ self);
PPCODE:
+ (void)sv_2mortal(SvREFCNT_inc(SvRV(self)));
if (p_state->parsing)
croak("Parse loop not allowed");
p_state->parsing = 1;
diff -Nurp ./t/free.t /Users/sprout/perl/hpbug/HTML-Parser-3.72-4YaB9L/t/free.t
--- ./t/free.t 1969-12-31 16:00:00.000000000 -0800
+++ /Users/sprout/perl/hpbug/HTML-Parser-3.72-4YaB9L/t/free.t 2016-06-03 06:24:54.000000000 -0700
@@ -0,0 +1,14 @@
+#!perl -w
+
+use Test::More tests => 1;
+
+use HTML::Parser;
+$p = new HTML::Parser(
+ start_h => [sub {
+ undef $p;
+ }],
+);
+
+$p->parse(q(<foo>));
+
+pass;