Ian Miller <[EMAIL PROTECTED]> writes:

> On Wed, Jun 28, 2000 at 10:46:29AM +0200, Gisle Aas screived:
> > 
> > > sub text {
> > >     my ($self, $text) = @_;
> > >     
> > >     print STDERR "$text\n----- END CHUNK -----\n";
> > >     @_ = split(/\W/, $text); ## this causes the segfault
> > > }
> > 
> > By the assignment to @_ you are clobbering $self and other stuff.  Why
> > don't you use your own lexical array??? :-)
> 
> Sorry, I culled that program from something bigger and only used @_ on the 
> spur of the moment, to stop -w giving a warning about a useless split! 
> It was my belief at the time that it was the split command itself that 
> was causing the segmentation fault [now known to be untrue].
> 
> (Ironically, it turns out that -w doesn't give a warning when split
> is the last command in a method anyway, as it is then the return value!)

I was wrong about the assignment to @_.  It does not clobber the stuff
inside @_.  Sorry.  That was my fast&wrong conclution when I saw that
$self got undefined and that the problem got fixed in my reduced
test case by making a mortal copy of the reference.  Unfortunately I
forgot to check again against your full test case.

> > ...but HTML::Parser was stupid enough to send the same reference to
> > all calls.  That meant that the next handler invoked got your
> > clobbered $self as its argument and eventually perl got confused
> > during global destruction.  This patch make sure that we copy the
> > reference for each callback invocation.  That should cure the problem.
> 
> I think I understand... however, this is apparently *not* the cause of
> the problem. I have applied the patch, and the segmentation fault still 
> occurs at the @_ assignment!
> 
> Furthermore, a segmentation fault even occurs for assignment to a lexical!
> e.g.
>        sub text {
>            my ($self, $text) = @_;
>            
>            print STDERR "$text\n----- END CHUNK -----\n";
>            my @blahblah = split(/\W/, $text); ## this causes the segfault
>        }
> 
> And... if you reverse the order of the print and assignment lines, then 
> you get a `bus error' instead of a segmentation fault! Very, very strange...

There was one more bug.  When we call flush_pending_text() something
might happen that change the stack pointer cached by dSP declared at
the start of the report_event() routine, so we need to refresh it.  I
also added a few more mortal copies to make sure you can't try assign
to perl's internal constants by assignment to $_[$n] inside a handler.

If you apply this patch on top of the previous one, all your bugs
should be fixed (I hope)!  I'll think I wait a day or two before
pushing this as HTML-Parser-3.10 :-)

Regards,
Gisle


Index: hparser.c
===================================================================
RCS file: /home/cvs/aas/perl/mods/html-parser/hparser.c,v
retrieving revision 2.43
retrieving revision 2.44
diff -u -p -u -r2.43 -r2.44
--- hparser.c   2000/06/28 08:34:31     2.43
+++ hparser.c   2000/06/28 11:35:05     2.44
@@ -1,4 +1,4 @@
-/* $Id: hparser.c,v 2.43 2000/06/28 08:34:31 gisle Exp $
+/* $Id: hparser.c,v 2.44 2000/06/28 11:35:05 gisle Exp $
  *
  * Copyright 1999-2000, Gisle Aas
  * Copyright 1999-2000, Michael A. Chase
@@ -149,6 +149,7 @@ report_event(PSTATE* p_state,
     if (SvOK(p_state->pend_text)) {
       if (p_state->is_cdata != p_state->pend_text_is_cdata) {
        flush_pending_text(p_state, self);
+       SPAGAIN;
        goto INIT_PEND_TEXT;
       }
     }
@@ -163,6 +164,7 @@ report_event(PSTATE* p_state,
   }
   else if (p_state->pend_text && SvOK(p_state->pend_text)) {
     flush_pending_text(p_state, self);
+    SPAGAIN;
   }
 
   h = &p_state->handlers[event];
@@ -345,7 +347,7 @@ report_event(PSTATE* p_state,
       break;
 
     case ARG_UNDEF:
-      arg = &PL_sv_undef;
+      arg = sv_mortalcopy(&PL_sv_undef);
       break;
       
     default:
@@ -354,7 +356,7 @@ report_event(PSTATE* p_state,
     }
 
     if (!arg)
-      arg = &PL_sv_undef;
+      arg = sv_mortalcopy(&PL_sv_undef);
 
     if (array) {
       /* have to fix mortality here or

Reply via email to