From 49d8e39f9a42ff1963c5df0f6e9ed903d66f2eb0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 11 Feb 2011 17:18:30 +0200 Subject: Fix recursive polymorphic parsing in C++/Parser New test: cxx/parser/polyrecur. --- libxsde/xsde/cxx/parser/context.hxx | 18 ++++++++++++++++++ libxsde/xsde/cxx/parser/expat/document.cxx | 26 ++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'libxsde') diff --git a/libxsde/xsde/cxx/parser/context.hxx b/libxsde/xsde/cxx/parser/context.hxx index cd68631..f3e49e0 100644 --- a/libxsde/xsde/cxx/parser/context.hxx +++ b/libxsde/xsde/cxx/parser/context.hxx @@ -142,6 +142,18 @@ namespace xsde void start_wildcard_content (); + parser_base* + nested_parser () const + { + return nested_parser_; + } + + void + nested_parser (parser_base* p) + { + nested_parser_ = p; + } + void reset (XML_Parser); @@ -154,6 +166,12 @@ namespace xsde public: parser_state current_; + private: + // Nested parser when transitioning from outer to inner or from + // inner to outer parsers. + // + parser_base* nested_parser_; + protected: XML_Parser xml_parser_; diff --git a/libxsde/xsde/cxx/parser/expat/document.cxx b/libxsde/xsde/cxx/parser/expat/document.cxx index 2ebde82..3afca7b 100644 --- a/libxsde/xsde/cxx/parser/expat/document.cxx +++ b/libxsde/xsde/cxx/parser/expat/document.cxx @@ -875,14 +875,30 @@ namespace xsde else if (cur.parser_) { // The "normal" case: call _start_element which will - // call pre() and _pre_impl() (which will push the - // new parser). + // call pre() and set the nested parser. We then call + // _pre_impl on that (which will push the new parser). // + + context_.nested_parser (0); + #ifdef XSDE_POLYMORPHIC cur.parser_->_start_element (ns, name, type); #else cur.parser_->_start_element (ns, name); #endif + +#if defined(XSDE_PARSER_VALIDATION) || !defined(XSDE_EXCEPTIONS) + if (context_.error_type ()) + { + XML_StopParser (xml_parser_, false); + return; + } +#endif + if (parser_base* p = context_.nested_parser ()) + p->_pre_impl (context_); + else + if (!cur.any_) + cur.depth_++; // Ignoring. } else { @@ -1073,7 +1089,7 @@ namespace xsde // The "normal" case: call _post to pop the parser and then // call _end_element on the "outer" parser which calls post(). // - parser_base* p = cur.parser_; + context_.nested_parser (cur.parser_); cur.parser_->_post_impl (); #if defined(XSDE_PARSER_VALIDATION) || !defined(XSDE_EXCEPTIONS) @@ -1091,7 +1107,7 @@ namespace xsde { // End of the root element. post() is called by the user. // - end_root_element (ns, name, p); + end_root_element (ns, name, context_.nested_parser ()); } } else @@ -1113,6 +1129,8 @@ namespace xsde } else { + context_.nested_parser (0); + if (cur.any_) { // Handling content matched by a wildcard. -- cgit v1.1