mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
65ffce9728
To avoid copying in the common case, expat points directly into the (internal) input buffer for strings referenced from the tag stack. When expat unwinds back to the caller, it attempts to call storeRawNames() to walk the tag stack and copy any such strings into persistent memory before the caller potentially invokes XML_Parse() again and shuffles the input buffer, thereby invalidating these references. Unfortunately, it doesn't do it in all the right places. Because different parsing states set |processor| to different callbacks (so that parsing can resume in the right context), there are a number of non-obvious entry points. In this case, the input stream was chunked so that parsing paused in middle of processing an internal entity [1], so |processor| was set to internalEntityProcessor(), which invokes doContent() but does not call storeRawNames(). The doContent() call then parsed some nested tags from the entity. Tags within an entity are generally required to be balanced, but a host callback returned an error code to interrupt parsing midway through. This caused Expat to return to the caller with a tag stack still referencing the input buffer, which got clobbered in the next call to XML_Parse, causing a tag mismatch on the next close tag. Conceptually, this optimization should be managed by doContent(), and I believe the only reason that isn't the case is that doContent() has so many return paths (and we don't have RAII in C). We can fix this by wrapping doContent() in a helper. [1] &certerror.expiredCert.whatCanYouDoAboutIt2; Differential Revision: https://phabricator.services.mozilla.com/D134878 |
||
---|---|---|
.. | ||
lib | ||
COPYING | ||
expat_config_moz.h | ||
expat_config_rlbox.h | ||
expat_config.h | ||
moz.build | ||
rlbox_expat_types.h | ||
rlbox_expat.h |