Subject: | Issue with erase method against an Elt |
I suspect there is a bug with the erase method in the following code snippet (lines 3814-3818):
else
{ # elt was the last child
$elt->{parent}->set_last_child( $elt->{next_sibling});
}
}
The elt being erased is the last child, therefore elt->{next_sibling} is set to undef. This is causing the following problems (those I have seen):
1) Use of uninitialized value in numeric eq (==) at line 3901 (paste_after method):
$parent->set_last_child( $elt) if( $parent->{last_child}== $ref);
Obviously occurs because $parent->{last_child} has been set to undef during erase against the previous last element;
2) A new element not being pasted during paste_last_element method:
sub paste_last_child
{ my( $elt, $ref)= @_;
my( $parent, $prev_sibling, $next_sibling );
$parent= $ref;
$prev_sibling= $ref->{last_child};
delete $ref->{empty} if( $ref->is_empty);
$elt->set_parent( $parent);
$parent->set_last_child( $elt);
$parent->{first_child}= $elt unless( $parent->{first_child});
$elt->set_prev_sibling( $prev_sibling);
$prev_sibling->{next_sibling}= $elt if( $prev_sibling);
$elt->{next_sibling}= undef;
}
As you can see, $prev_sibling is being assigned $ref->{last_child}, which is undef. Which means the following is not functioning as expected, resulting in the element being orphaned:
$elt->set_prev_sibling( $prev_sibling);
$prev_sibling->{next_sibling}= $elt if( $prev_sibling);
To reproduce this problem, create an XML document with a parent that has multiple children. Delete the last child and then try to add it back as the last child.
Possible solution:
I suspect that if you change the $elt line in the erase method:
{ # elt was the last child
$elt->{parent}->set_last_child( $elt->{next_sibling});
}
to:
{ # elt was the last child
$elt->{parent}->set_last_child( $elt->{prev_sibling});
}
this will correct it