Gisle Aas <[EMAIL PROTECTED]> writes:
> William Leeke <[EMAIL PROTECTED]> writes:
>
> > Has anybody else had this problem?
>
> Oops! It looks like I forgot to test HTML-Tree with the new magic
> parser deallocation code. The problem is that magic is not copied on
> assigment, which means that this code (from HTML::TreeBuilder->new):
>
> {
> my $other_self = HTML::Parser->new();
> %$self = (%$self, %$other_self); # copy fields
> # Yes, multiple inheritance is messy. Kids, don't try this at home.
> bless $other_self, "HTML::TreeBuilder::_hideyhole";
> # whack it out of the HTML::Parser class, to avoid the destructor
> }
>
> doesn't work any more. The IV-pointer is copied, but the internal
> parser state is then killed when $other_self goes out of scope and the
> reblessing has no effect.
>
> I am not sure what the best cure is. I see two options now:
>
> 1) Make a $self->HTML::Parser::init() that can be called to
> set up the HTML::Parser part of the object. Trouble is that
> this is not automatically v2.2x compatible.
>
> 2) Make _hparser_xs_state be a reference to the magic IV-pointer.
> This give one more level to dereferencing, but should make
> attribute copying ok again.
This is a patch that implements option 2). If you apply it, then
HTML-Tree should work again. This is probably also the fix that will
go into 3.02.
Regards,
Gisle
Index: Parser.xs
===================================================================
RCS file: /home/cvs/aas/perl/mods/html-parser/Parser.xs,v
retrieving revision 2.82
diff -u -p -u -r2.82 Parser.xs
--- Parser.xs 1999/12/17 14:11:40 2.82
+++ Parser.xs 1999/12/21 07:21:51
@@ -111,8 +111,12 @@ get_pstate_hv(SV* sv)
croak("Not a reference to a hash");
hv = (HV*)sv;
svp = hv_fetch(hv, "_hparser_xs_state", 17, 0);
- if (svp)
- return get_pstate_iv(*svp);
+ if (svp) {
+ if (SvROK(*svp))
+ return get_pstate_iv(SvRV(*svp));
+ else
+ croak("_hparser_xs_state element is not a reference");
+ }
croak("Can't find '_hparser_xs_state' element in HTML::Parser hash");
return 0;
}
@@ -181,7 +185,7 @@ _alloc_pstate(self)
mg->mg_virtual = &vtbl_free_pstate;
SvREADONLY_on(sv);
- hv_store(hv, "_hparser_xs_state", 17, sv, 0);
+ hv_store(hv, "_hparser_xs_state", 17, newRV_noinc(sv), 0);
SV*
parse(self, chunk)
Regards,
Gisle