Discussion:
[Expat-bugs] [ expat-Bugs-1515266 ] missing check of stopped parser in doContent() 'for' loop
SourceForge.net
2012-03-03 19:36:51 UTC
Permalink
Bugs item #1515266, was opened at 2006-06-30 11:04
Message generated for change (Settings changed) made by kwaclaw
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=110127&aid=1515266&group_id=10127

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: Test Required
Status: Closed
Resolution: Fixed
Priority: 5
Private: No
Submitted By: Brett Cannon (bcannon)
Assigned to: Fred L. Drake, Jr. (fdrake)
Summary: missing check of stopped parser in doContent() 'for' loop

Initial Comment:
In Expat 2.0.0, in expat.c:doConvert() there is a 'for'
loop for the XML_TOK_DATA_CHARS case. There is
unfortunately no check in that loop whether the parser
was stopped during that call because of an error.

This was discovered in Python
(Lib/test/crashers/xml_parsers.py) because pyexpat,
upon error where there is no error return code like
with characterDataHandlers, sets all handlers to 0,
sets parsingStatus to XML_FINISHED, and sets errorCode.
This leads to a segfault if the 'for' loop goes around
again because parser->m_characterDataHandler is set to 0.

A simple check if the parser is stopped fixes the
problem. I have attached a simple patch that just
breaks out of the loop and lets execution fall through
to the bottom of the 'switch' statement. I don't know
if returning errorCode directly would be better or if
checking for XML_SUSPENDED is also desirable.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2009-01-17 08:09

Message:
Comment for Fred:
So, do we need to address this last comment - i.e. that Python is
supposedly broken with release 2.0.1?

Karl

----------------------------------------------------------------------

Comment By: David Leverton (dleverton)
Date: 2008-05-24 16:50

Message:
Logged In: YES
user_id=2011415
Originator: NO
Python compatibility still needs testing.
This does indeed break Python: when it clears the handler, it sets the
variable containing the Python-side handler to NULL, and then assumes that
said variable is non-null when expat calls the old handler.

(The vanilla Python distribution uses a bundled copy of expat from before
this change was made, which is probably why no-one's complained until now,
but some Linux distros like to use the system copy instead of the bundled
one.)

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-11-25 09:41

Message:
Logged In: YES
user_id=290026
Originator: NO

Is anyone testing CVS for this solution?

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-10 12:02

Message:
Logged In: YES
user_id=290026

Applied the patch preserving default handler failover.
See xmlparse.c rev. 1.158. Docs updated as well.
Python compatibility still needs testing.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-06 10:19

Message:
Logged In: YES
user_id=290026

I am attaching a patch to current CVS that preserves the
default handler failover logic by saving the character data
handler to a local variable instead of moving the NULL check
into the inner for loop (file "localCharDataHandlerPatch.diff").

The drawback: Even if the handler is cleared, it will be
called back on as long as the inner for loop is active.

Could be a problem for Python, if it cannot deal with a few
more call-backs despite clearing the handlers.

----------------------------------------------------------------------

Comment By: Brett Cannon (bcannon)
Date: 2006-07-06 10:03

Message:
Logged In: YES
user_id=357491

Yes, I'm listening, Fred. =)

If you look at PEP 356
(http://www.python.org/dev/peps/pep-0356/) it seems like b2
is due on July 12 and rc1 August 1. So there is still time
to get whatever change/fix needed to Python's wrapper before
we hit final release.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-06 05:56

Message:
Logged In: YES
user_id=290026

One way to preserver the old default handler logic would be
this:

Revert back to the original code, but save the character
data handler into a local variable for the duration of the
inner for loop. This would prevent the segfault, but would
enforce the call-backs in the loop to go on until the loop
terminates, even if the character data handler was cleared.

I personally like this solution, but the question is how
Python could handle it if there were more call-backs even
after the handlers were cleared.

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-07-05 22:15

Message:
Logged In: YES
user_id=3066

Python (on the trunk) is no longer quite as sensitive to the
Expat implementation for this, so that's not a source of
time pressure to come up with the final fix for this.

Reducing priority back to "Medium"

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-07-05 20:23

Message:
Logged In: YES
user_id=3066

The tests now pass, but agree that the lack of falling back
to the default handler is undesirable. As noted, I'm not
sure how much we want to worry about this in code, though,
rather than through documentation.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-05 19:55

Message:
Logged In: YES
user_id=290026

The bug is quite obvious when you look at it.
When the character data handler is cleared, the for loop
will do nothing forever. Please check again with xmlparse.c
rev. 1.157.

However this quick fix is not quite satisfying. There is one
piece of logic that becomes ill-fitted now: the "fail-over"
to the default handler does not work as expected anymore, so
I'll have some more thinking to do.


----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-07-05 19:38

Message:
Logged In: YES
user_id=3066

The tests no longer complete, but take up all the CPU the
system will let them have. Hallmarks of an infinite loop,
if you ask me. :-)

Are you able to run the tests on Windows? I don't know if a
MSVC++ target was ever built for them, and don't have access
to a Windows development machine most of the time.

One thing that can be done is to document that the character
data handler can't be removed (though it can be replaced),
during parsing, except from some non-character data (and
non-decoding-related) handler. Then the Python bindings can
use an alternate approach, replacing the character handler
with a completely no-op handler until it can be safely
removed completely.

Brett, are you still paying attention? I can make the
needed changes to the Python bindings to isolate those from
some of the changes in Expat, hopefully no later than
sometime this weekend. Not sure what the release schedule
is, though.

Karl, I'm generally inclined to make Expat as safe from
segfaults as possible, so I'd like things to "just work" in
even some of the oddball scenarios that exception-handling
wrappers built to support scripting languages might present,
though I don't object to making them go through a bit of
extra work. I know our main audience is very
performance-sensitive, so I don't want to pay too high a
cost on that front. It might be worth taking the discussion
of alternatives to the mailing list, but I vaguely recall
that we've done that before.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-05 06:26

Message:
Logged In: YES
user_id=290026

Corrected Summary.

----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-05 06:14

Message:
Logged In: YES
user_id=290026

Applied the patch for bug # 1515600 which solves this issue
as well. Removed the check for XML_FINISHED/XML_SUSPENDED.
We could discuss special treatment of XML_FINISHED, but if
one is clearing all handlers anyway, then special treatment
of XML_FINISHED is not necessary.

For Fred: I have not re-run the test cases. Please do so and
close the issue if successful.



----------------------------------------------------------------------

Comment By: Karl Waclawek (kwaclaw)
Date: 2006-07-04 06:37

Message:
Logged In: YES
user_id=290026

I am re-opening this issue because in the case of a
suspended parser, breaking out of the inner loop in
XML_TOK_DATA_CHARS means that character call-backs are
missed when resuming the parser. We should let the inner
loop finish reporting all characters.

The documentation already states that after calling
XML_StopParser() there may still be a few call-backs that
would otherwise be missed, so this would not be new
behaviour, but consistent with existing behaviour.

The solution to the problem described is the same as
suggested for bug # 1515600 (Segfault after removing
character data handler). Just put the NULL check for the
character data handler inside the internal loop.

Btw, the same problem exists in the doCdataSection()
function. I'll attach a patch suggestion to bug # 1515600.

We might decide to treat XML_FINISHED different from
XML_SUSPENDED such that no other call-backs will happen, but
in that case we need to review all the other places where
this would need to be done as well (and update the
documentation, of course).

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-07-01 08:32

Message:
Logged In: YES
user_id=3066

Confirmed that the suspend behavior parallels the abort
behavior Brett's patch fixed; fixed and added a regression
test in lib/xmlparse.c 1.155 and tests/runtests.c 1.66.

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-07-01 08:02

Message:
Logged In: YES
user_id=3066

Added a regression test in tests/runtests.c revision 1.65.

Closing this report.

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-06-30 21:00

Message:
Logged In: YES
user_id=3066

That seems fine, but can be done faster within the Expat
implementation. I've committed the simplified patch as
lib/xmlparse.c revision 1.154.

I'll have a test case committed tomorrow as well. Leaving
this report open for now since I need to finish up the test
case.

----------------------------------------------------------------------

Comment By: Fred L. Drake, Jr. (fdrake)
Date: 2006-06-30 11:40

Message:
Logged In: YES
user_id=3066

The Python folks need this dealt with before Python 2.5, so
I'll try and take a look at it this weekend if no one beats
me to it.

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=110127&aid=1515266&group_id=10127
Loading...