[mingw-xerces-c: 2/13] Initial import (#523224)

Kalev Lember kalev at fedoraproject.org
Wed Mar 7 18:20:10 UTC 2012


commit f5e58dc5d6ec4a76d9759897b9c8367a861790ae
Author: Antti Andreimann <anttix at fedoraproject.org>
Date:   Wed Dec 16 13:51:14 2009 +0000

    Initial import (#523224)

 .cvsignore                         |    1 +
 import.log                         |    1 +
 mingw32-xerces-c.spec              |   76 +++++
 sources                            |    1 +
 xerces-c-3.0.1-CVE-2009-1885.patch |  648 ++++++++++++++++++++++++++++++++++++
 5 files changed, 727 insertions(+), 0 deletions(-)
---
diff --git a/.cvsignore b/.cvsignore
index e69de29..31deda4 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -0,0 +1 @@
+xerces-c-3.0.1.tar.gz
diff --git a/import.log b/import.log
new file mode 100644
index 0000000..3ebd858
--- /dev/null
+++ b/import.log
@@ -0,0 +1 @@
+mingw32-xerces-c-3_0_1-1_fc12:HEAD:mingw32-xerces-c-3.0.1-1.fc12.src.rpm:1260971296
diff --git a/mingw32-xerces-c.spec b/mingw32-xerces-c.spec
new file mode 100644
index 0000000..181f8ef
--- /dev/null
+++ b/mingw32-xerces-c.spec
@@ -0,0 +1,76 @@
+%global __strip %{_mingw32_strip}
+%global __objdump %{_mingw32_objdump}
+%global _use_internal_dependency_generator 0
+%global __find_requires %{_mingw32_findrequires}
+%global __find_provides %{_mingw32_findprovides}
+%define __debug_install_post %{_mingw32_debug_install_post}
+
+Name:           mingw32-xerces-c
+Version:        3.0.1
+Release:        1%{?dist}
+Summary:        MingGW Windows validating XML parser
+
+Group:          Development/Libraries
+License:        ASL 2.0
+URL:            http://xml.apache.org/xerces-c/
+Source0:        http://www.apache.org/dist/xerces/c/3/sources/xerces-c-%{version}.tar.gz
+Patch0:         xerces-c-3.0.1-CVE-2009-1885.patch
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildArch:      noarch
+
+BuildRequires:  mingw32-filesystem >= 53
+BuildRequires:  mingw32-gcc
+BuildRequires:  mingw32-gcc-c++
+BuildRequires:  mingw32-binutils
+
+Requires:       pkgconfig
+
+%description
+Xerces-C is a validating XML parser written in a portable subset of
+C++. Xerces-C makes it easy to give your application the ability to
+read and write XML data. A shared library is provided for parsing,
+generating, manipulating, and validating XML documents. Xerces-C is
+faithful to the XML 1.0 recommendation and associated standards (DOM
+1.0, DOM 2.0. SAX 1.0, SAX 2.0, Namespaces).
+
+
+%{_mingw32_debug_package}
+
+
+%prep
+%setup -q -n xerces-c-%{version}
+%patch0 -p0 -b .CVE-2009-1885
+
+
+%build
+%{_mingw32_configure} LDFLAGS=-no-undefined \
+    --disable-static \
+    --disable-pretty-make
+make %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+rm -f $RPM_BUILD_ROOT%{_mingw32_bindir}/*.exe
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc LICENSE
+%{_mingw32_includedir}/xercesc/
+%{_mingw32_bindir}/libxerces-c-3-0.dll
+%{_mingw32_libdir}/libxerces-c.dll.a
+%{_mingw32_libdir}/libxerces-c.la
+%{_mingw32_libdir}/pkgconfig/xerces-c.pc
+
+
+%changelog
+* Mon Sep 14 2009 Antti Andreimann <Antti.Andreimann at mail.ee> - 3.0.1-1
+- Initial RPM release.
diff --git a/sources b/sources
index e69de29..dc8501a 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+293c03f59bf8e956020d73f5b122094c  xerces-c-3.0.1.tar.gz
diff --git a/xerces-c-3.0.1-CVE-2009-1885.patch b/xerces-c-3.0.1-CVE-2009-1885.patch
new file mode 100644
index 0000000..7fe05f1
--- /dev/null
+++ b/xerces-c-3.0.1-CVE-2009-1885.patch
@@ -0,0 +1,648 @@
+--- src/xercesc/validators/DTD/DTDScanner.cpp
++++ src/xercesc/validators/DTD/DTDScanner.cpp
+@@ -27,7 +27,9 @@
+ #include <xercesc/util/FlagJanitor.hpp>
+ #include <xercesc/util/Janitor.hpp>
+ #include <xercesc/util/XMLUniDefs.hpp>
++#include <xercesc/util/ValueStackOf.hpp>
+ #include <xercesc/util/UnexpectedEOFException.hpp>
++#include <xercesc/util/OutOfMemoryException.hpp>
+ #include <xercesc/sax/InputSource.hpp>
+ #include <xercesc/framework/XMLDocumentHandler.hpp>
+ #include <xercesc/framework/XMLEntityHandler.hpp>
+@@ -39,7 +41,6 @@
+ #include <xercesc/validators/DTD/DTDEntityDecl.hpp>
+ #include <xercesc/validators/DTD/DocTypeHandler.hpp>
+ #include <xercesc/validators/DTD/DTDScanner.hpp>
+-#include <xercesc/util/OutOfMemoryException.hpp>
+ 
+ XERCES_CPP_NAMESPACE_BEGIN
+ 
+@@ -1041,338 +1042,354 @@
+     // Check for a PE ref here, but don't require spaces
+     checkForPERef(false, true);
+ 
+-    // We have to check entity nesting here
+-    XMLSize_t curReader;
+-
++    ValueStackOf<XMLSize_t>* arrNestedDecl=NULL;
+     //
+     //  We know that the caller just saw an opening parenthesis, so we need
+-    //  to parse until we hit the end of it, recursing for other nested
+-    //  parentheses we see.
++    //  to parse until we hit the end of it; if we find several parenthesis,
++    //  store them in an array to be processed later.
+     //
+     //  We have to check for one up front, since it could be something like
+     //  (((a)*)) etc...
+     //
+     ContentSpecNode* curNode = 0;
+-    if (fReaderMgr->skippedChar(chOpenParen))
++    while(fReaderMgr->skippedChar(chOpenParen))
+     {
+-        curReader = fReaderMgr->getCurrentReaderNum();
++        // to check entity nesting
++        const XMLSize_t curReader = fReaderMgr->getCurrentReaderNum();
++        if(arrNestedDecl==NULL)
++            arrNestedDecl=new (fMemoryManager) ValueStackOf<XMLSize_t>(5, fMemoryManager);
++        arrNestedDecl->push(curReader);
+ 
+-        // Lets call ourself and get back the resulting node
+-        curNode = scanChildren(elemDecl, bufToUse);
++        // Check for a PE ref here, but don't require spaces
++        checkForPERef(false, true);
++    }
+ 
+-        // If that failed, no need to go further, return failure
+-        if (!curNode)
+-            return 0;
++    // We must find a leaf node here, either standalone or nested in the parenthesis
++    if (!fReaderMgr->getName(bufToUse))
++    {
++        fScanner->emitError(XMLErrs::ExpectedElementName);
++        return 0;
++    }
++
++    //
++    //  Create a leaf node for it. If we can find the element id for
++    //  this element, then use it. Else, we have to fault in an element
++    //  decl, marked as created because of being in a content model.
++    //
++    XMLElementDecl* decl = fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bufToUse.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
++    if (!decl)
++    {
++        decl = new (fGrammarPoolMemoryManager) DTDElementDecl
++        (
++            bufToUse.getRawBuffer()
++            , fEmptyNamespaceId
++            , DTDElementDecl::Any
++            , fGrammarPoolMemoryManager
++        );
++        decl->setCreateReason(XMLElementDecl::InContentModel);
++        decl->setExternalElemDeclaration(isReadingExternalEntity());
++        fDTDGrammar->putElemDecl(decl);
++    }
++    curNode = new (fGrammarPoolMemoryManager) ContentSpecNode
++    (
++        decl->getElementName()
++        , fGrammarPoolMemoryManager
++    );
++
++    // Check for a PE ref here, but don't require spaces
++    const bool gotSpaces = checkForPERef(false, true);
+ 
+-        if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getValidationScheme() == XMLScanner::Val_Always)
+-            fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE);
++    // Check for a repetition character after the leaf
++    XMLCh repCh = fReaderMgr->peekNextChar();
++    ContentSpecNode* tmpNode = makeRepNode(repCh, curNode, fGrammarPoolMemoryManager);
++    if (tmpNode != curNode)
++    {
++        if (gotSpaces)
++        {
++            if (fScanner->emitErrorWillThrowException(XMLErrs::UnexpectedWhitespace))
++            {
++                delete tmpNode;
++            }
++            fScanner->emitError(XMLErrs::UnexpectedWhitespace);
++        }
++        fReaderMgr->getNextChar();
++        curNode = tmpNode;
+     }
+-     else
++
++    while(arrNestedDecl==NULL || !arrNestedDecl->empty())
+     {
+-        // Not a nested paren, so it must be a leaf node
+-        if (!fReaderMgr->getName(bufToUse))
++        // Check for a PE ref here, but don't require spaces
++        checkForPERef(false, true);
++
++        //
++        //  Ok, the next character tells us what kind of content this particular
++        //  model this particular parentesized section is. Its either a choice if
++        //  we see ',', a sequence if we see '|', or a single leaf node if we see
++        //  a closing paren.
++        //
++        const XMLCh opCh = fReaderMgr->peekNextChar();
++
++        if ((opCh != chComma)
++        &&  (opCh != chPipe)
++        &&  (opCh != chCloseParen))
+         {
+-            fScanner->emitError(XMLErrs::ExpectedElementName);
++            // Not a legal char, so delete our node and return failure
++            delete curNode;
++            fScanner->emitError(XMLErrs::ExpectedSeqChoiceLeaf);
+             return 0;
+         }
+ 
+         //
+-        //  Create a leaf node for it. If we can find the element id for
+-        //  this element, then use it. Else, we have to fault in an element
+-        //  decl, marked as created because of being in a content model.
++        //  Create the head node of the correct type. We need this to remember
++        //  the top of the local tree. If it was a single subexpr, then just
++        //  set the head node to the current node. For the others, we'll build
++        //  the tree off the second child as we move across.
+         //
+-        XMLElementDecl* decl = fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bufToUse.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
+-        if (!decl)
++        ContentSpecNode* headNode = 0;
++        ContentSpecNode::NodeTypes curType = ContentSpecNode::UnknownType;
++        if (opCh == chComma)
+         {
+-            decl = new (fGrammarPoolMemoryManager) DTDElementDecl
++            curType = ContentSpecNode::Sequence;
++            headNode = new (fGrammarPoolMemoryManager) ContentSpecNode
+             (
+-                bufToUse.getRawBuffer()
+-                , fEmptyNamespaceId
+-                , DTDElementDecl::Any
++                curType
++                , curNode
++                , 0
++                , true
++                , true
+                 , fGrammarPoolMemoryManager
+             );
+-            decl->setCreateReason(XMLElementDecl::InContentModel);
+-            decl->setExternalElemDeclaration(isReadingExternalEntity());
+-            fDTDGrammar->putElemDecl(decl);
++            curNode = headNode;
+         }
+-        curNode = new (fGrammarPoolMemoryManager) ContentSpecNode
+-        (
+-            decl->getElementName()
+-            , fGrammarPoolMemoryManager
+-        );
+-
+-        // Check for a PE ref here, but don't require spaces
+-        const bool gotSpaces = checkForPERef(false, true);
+-
+-        // Check for a repetition character after the leaf
+-        const XMLCh repCh = fReaderMgr->peekNextChar();
+-        ContentSpecNode* tmpNode = makeRepNode(repCh, curNode, fGrammarPoolMemoryManager);
+-        if (tmpNode != curNode)
++         else if (opCh == chPipe)
+         {
+-            if (gotSpaces)
+-            {
+-                if (fScanner->emitErrorWillThrowException(XMLErrs::UnexpectedWhitespace))
+-                {
+-                    delete tmpNode;
+-                }
+-                fScanner->emitError(XMLErrs::UnexpectedWhitespace);
+-            }
++            curType = ContentSpecNode::Choice;
++            headNode = new (fGrammarPoolMemoryManager) ContentSpecNode
++            (
++                curType
++                , curNode
++                , 0
++                , true
++                , true
++                , fGrammarPoolMemoryManager
++            );
++            curNode = headNode;
++        }
++         else
++        {
++            headNode = curNode;
+             fReaderMgr->getNextChar();
+-            curNode = tmpNode;
+         }
+-    }
+-
+-    // Check for a PE ref here, but don't require spaces
+-    checkForPERef(false, true);
+-
+-    //
+-    //  Ok, the next character tells us what kind of content this particular
+-    //  model this particular parentesized section is. Its either a choice if
+-    //  we see ',', a sequence if we see '|', or a single leaf node if we see
+-    //  a closing paren.
+-    //
+-    const XMLCh opCh = fReaderMgr->peekNextChar();
+-
+-    if ((opCh != chComma)
+-    &&  (opCh != chPipe)
+-    &&  (opCh != chCloseParen))
+-    {
+-        // Not a legal char, so delete our node and return failure
+-        delete curNode;
+-        fScanner->emitError(XMLErrs::ExpectedSeqChoiceLeaf);
+-        return 0;
+-    }
+-
+-    //
+-    //  Create the head node of the correct type. We need this to remember
+-    //  the top of the local tree. If it was a single subexpr, then just
+-    //  set the head node to the current node. For the others, we'll build
+-    //  the tree off the second child as we move across.
+-    //
+-    ContentSpecNode* headNode = 0;
+-    ContentSpecNode::NodeTypes curType = ContentSpecNode::UnknownType;
+-    if (opCh == chComma)
+-    {
+-        curType = ContentSpecNode::Sequence;
+-        headNode = new (fGrammarPoolMemoryManager) ContentSpecNode
+-        (
+-            curType
+-            , curNode
+-            , 0
+-            , true
+-            , true
+-            , fGrammarPoolMemoryManager
+-        );
+-        curNode = headNode;
+-    }
+-     else if (opCh == chPipe)
+-    {
+-        curType = ContentSpecNode::Choice;
+-        headNode = new (fGrammarPoolMemoryManager) ContentSpecNode
+-        (
+-            curType
+-            , curNode
+-            , 0
+-            , true
+-            , true
+-            , fGrammarPoolMemoryManager
+-        );
+-        curNode = headNode;
+-    }
+-     else
+-    {
+-        headNode = curNode;
+-        fReaderMgr->getNextChar();
+-    }
+ 
+-    //
+-    //  If it was a sequence or choice, we just loop until we get to the
+-    //  end of our section, adding each new leaf or sub expression to the
+-    //  right child of the current node, and making that new node the current
+-    //  node.
+-    //
+-    if ((opCh == chComma) || (opCh == chPipe))
+-    {
+-        ContentSpecNode* lastNode = 0;
+-        while (true)
++        //
++        //  If it was a sequence or choice, we just loop until we get to the
++        //  end of our section, adding each new leaf or sub expression to the
++        //  right child of the current node, and making that new node the current
++        //  node.
++        //
++        if ((opCh == chComma) || (opCh == chPipe))
+         {
+-            //
+-            //  The next thing must either be another | or , character followed
+-            //  by another leaf or subexpression, or a closing parenthesis, or a
+-            //  PE ref.
+-            //
+-            if (fReaderMgr->lookingAtChar(chPercent))
+-            {
+-                checkForPERef(false, true);
+-            }
+-             else if (fReaderMgr->skippedSpace())
+-            {
+-                // Just skip whitespace
+-                fReaderMgr->skipPastSpaces();
+-            }
+-             else if (fReaderMgr->skippedChar(chCloseParen))
++            ContentSpecNode* lastNode = 0;
++            while (true)
+             {
+                 //
+-                //  We've hit the end of this section, so break out. But, we
+-                //  need to see if we left a partial sequence of choice node
+-                //  without a second node. If so, we have to undo that and
+-                //  put its left child into the right node of the previous
+-                //  node.
++                //  The next thing must either be another | or , character followed
++                //  by another leaf or subexpression, or a closing parenthesis, or a
++                //  PE ref.
+                 //
+-                if ((curNode->getType() == ContentSpecNode::Choice)
+-                ||  (curNode->getType() == ContentSpecNode::Sequence))
++                if (fReaderMgr->lookingAtChar(chPercent))
++                {
++                    checkForPERef(false, true);
++                }
++                 else if (fReaderMgr->skippedSpace())
++                {
++                    // Just skip whitespace
++                    fReaderMgr->skipPastSpaces();
++                }
++                 else if (fReaderMgr->skippedChar(chCloseParen))
+                 {
+-                    if (!curNode->getSecond())
++                    //
++                    //  We've hit the end of this section, so break out. But, we
++                    //  need to see if we left a partial sequence of choice node
++                    //  without a second node. If so, we have to undo that and
++                    //  put its left child into the right node of the previous
++                    //  node.
++                    //
++                    if ((curNode->getType() == ContentSpecNode::Choice)
++                    ||  (curNode->getType() == ContentSpecNode::Sequence))
+                     {
+-                        ContentSpecNode* saveFirst = curNode->orphanFirst();
+-                        lastNode->setSecond(saveFirst);
+-                        curNode = lastNode;
++                        if (!curNode->getSecond())
++                        {
++                            ContentSpecNode* saveFirst = curNode->orphanFirst();
++                            lastNode->setSecond(saveFirst);
++                            curNode = lastNode;
++                        }
+                     }
++                    break;
+                 }
+-                break;
+-            }
+-             else if (fReaderMgr->skippedChar(opCh))
+-            {
+-                // Check for a PE ref here, but don't require spaces
+-                checkForPERef(false, true);
+-
+-                if (fReaderMgr->skippedChar(chOpenParen))
++                 else if (fReaderMgr->skippedChar(opCh))
+                 {
+-                    curReader = fReaderMgr->getCurrentReaderNum();
++                    // Check for a PE ref here, but don't require spaces
++                    checkForPERef(false, true);
+ 
+-                    // Recurse to handle this new guy
+-                    ContentSpecNode* subNode;
+-                    try {
+-                        subNode = scanChildren(elemDecl, bufToUse);
+-                    }
+-                    catch (const XMLErrs::Codes)
++                    if (fReaderMgr->skippedChar(chOpenParen))
+                     {
+-                        delete headNode;
+-                        throw;
+-                    }
++                        const XMLSize_t curReader = fReaderMgr->getCurrentReaderNum();
+ 
+-                    // If it failed, we are done, clean up here and return failure
+-                    if (!subNode)
+-                    {
+-                        delete headNode;
+-                        return 0;
++                        // Recurse to handle this new guy
++                        ContentSpecNode* subNode;
++                        try {
++                            subNode = scanChildren(elemDecl, bufToUse);
++                        }
++                        catch (const XMLErrs::Codes)
++                        {
++                            delete headNode;
++                            throw;
++                        }
++
++                        // If it failed, we are done, clean up here and return failure
++                        if (!subNode)
++                        {
++                            delete headNode;
++                            return 0;
++                        }
++
++                        if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getValidationScheme() == XMLScanner::Val_Always)
++                            fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE);
++
++                        // Else patch it in and make it the new current
++                        ContentSpecNode* newCur = new (fGrammarPoolMemoryManager) ContentSpecNode
++                        (
++                            curType
++                            , subNode
++                            , 0
++                            , true
++                            , true
++                            , fGrammarPoolMemoryManager
++                        );
++                        curNode->setSecond(newCur);
++                        lastNode = curNode;
++                        curNode = newCur;
+                     }
++                     else
++                    {
++                        //
++                        //  Got to be a leaf node, so get a name. If we cannot get
++                        //  one, then clean up and get outa here.
++                        //
++                        if (!fReaderMgr->getName(bufToUse))
++                        {
++                            delete headNode;
++                            fScanner->emitError(XMLErrs::ExpectedElementName);
++                            return 0;
++                        }
++
++                        //
++                        //  Create a leaf node for it. If we can find the element
++                        //  id for this element, then use it. Else, we have to
++                        //  fault in an element decl, marked as created because
++                        //  of being in a content model.
++                        //
++                        XMLElementDecl* decl = fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bufToUse.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
++                        if (!decl)
++                        {
++                            decl = new (fGrammarPoolMemoryManager) DTDElementDecl
++                            (
++                                bufToUse.getRawBuffer()
++                                , fEmptyNamespaceId
++                                , DTDElementDecl::Any
++                                , fGrammarPoolMemoryManager
++                            );
++                            decl->setCreateReason(XMLElementDecl::InContentModel);
++                            decl->setExternalElemDeclaration(isReadingExternalEntity());
++                            fDTDGrammar->putElemDecl(decl);
++                        }
+ 
+-                    if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getValidationScheme() == XMLScanner::Val_Always)
+-                        fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE);
++                        ContentSpecNode* tmpLeaf = new (fGrammarPoolMemoryManager) ContentSpecNode
++                        (
++                            decl->getElementName()
++                            , fGrammarPoolMemoryManager
++                        );
+ 
+-                    // Else patch it in and make it the new current
+-                    ContentSpecNode* newCur = new (fGrammarPoolMemoryManager) ContentSpecNode
+-                    (
+-                        curType
+-                        , subNode
+-                        , 0
+-                        , true
+-                        , true
+-                        , fGrammarPoolMemoryManager
+-                    );
+-                    curNode->setSecond(newCur);
+-                    lastNode = curNode;
+-                    curNode = newCur;
++                        // Check for a repetition character after the leaf
++                        const XMLCh repCh = fReaderMgr->peekNextChar();
++                        ContentSpecNode* tmpLeaf2 = makeRepNode(repCh, tmpLeaf, fGrammarPoolMemoryManager);
++                        if (tmpLeaf != tmpLeaf2)
++                            fReaderMgr->getNextChar();
++
++                        //
++                        //  Create a new sequence or choice node, with the leaf
++                        //  (or rep surrounding it) we just got as its first node.
++                        //  Make the new node the second node of the current node,
++                        //  and then make it the current node.
++                        //
++                        ContentSpecNode* newCur = new (fGrammarPoolMemoryManager) ContentSpecNode
++                        (
++                            curType
++                            , tmpLeaf2
++                            , 0
++                            , true
++                            , true
++                            , fGrammarPoolMemoryManager
++                        );
++                        curNode->setSecond(newCur);
++                        lastNode = curNode;
++                        curNode = newCur;
++                    }
+                 }
+                  else
+                 {
+-                    //
+-                    //  Got to be a leaf node, so get a name. If we cannot get
+-                    //  one, then clean up and get outa here.
+-                    //
+-                    if (!fReaderMgr->getName(bufToUse))
++                    // Cannot be valid
++                    delete headNode;  // emitError may do a throw so need to clean-up first
++                    if (opCh == chComma)
+                     {
+-                        delete headNode;
+-                        fScanner->emitError(XMLErrs::ExpectedElementName);
+-                        return 0;
++                        fScanner->emitError(XMLErrs::ExpectedChoiceOrCloseParen);
+                     }
+-
+-                    //
+-                    //  Create a leaf node for it. If we can find the element
+-                    //  id for this element, then use it. Else, we have to
+-                    //  fault in an element decl, marked as created because
+-                    //  of being in a content model.
+-                    //
+-                    XMLElementDecl* decl = fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bufToUse.getRawBuffer(), Grammar::TOP_LEVEL_SCOPE);
+-                    if (!decl)
++                     else
+                     {
+-                        decl = new (fGrammarPoolMemoryManager) DTDElementDecl
++                        fScanner->emitError
+                         (
+-                            bufToUse.getRawBuffer()
+-                            , fEmptyNamespaceId
+-                            , DTDElementDecl::Any
+-                            , fGrammarPoolMemoryManager
++                            XMLErrs::ExpectedSeqOrCloseParen
++                            , elemDecl.getFullName()
+                         );
+-                        decl->setCreateReason(XMLElementDecl::InContentModel);
+-                        decl->setExternalElemDeclaration(isReadingExternalEntity());
+-                        fDTDGrammar->putElemDecl(decl);
+-                    }
++                    }                
++                    return 0;
++                }
++            }
++        }
+ 
+-                    ContentSpecNode* tmpLeaf = new (fGrammarPoolMemoryManager) ContentSpecNode
+-                    (
+-                        decl->getElementName()
+-                        , fGrammarPoolMemoryManager
+-                    );
++        //
++        //  We saw the terminating parenthesis so lets check for any repetition
++        //  character, and create a node for that, making the head node the child
++        //  of it.
++        //
++        const XMLCh repCh = fReaderMgr->peekNextChar();
++        curNode = makeRepNode(repCh, headNode, fGrammarPoolMemoryManager);
++        if (curNode != headNode)
++            fReaderMgr->getNextChar();
++
++        // prepare for recursion
++        if(arrNestedDecl==NULL)
++            break;
++        else
++        {
++            // If that failed, no need to go further, return failure
++            if (!curNode)
++                return 0;
+ 
+-                    // Check for a repetition character after the leaf
+-                    const XMLCh repCh = fReaderMgr->peekNextChar();
+-                    ContentSpecNode* tmpLeaf2 = makeRepNode(repCh, tmpLeaf, fGrammarPoolMemoryManager);
+-                    if (tmpLeaf != tmpLeaf2)
+-                        fReaderMgr->getNextChar();
++            const XMLSize_t curReader = arrNestedDecl->pop();
++            if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getValidationScheme() == XMLScanner::Val_Always)
++                fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE);
+ 
+-                    //
+-                    //  Create a new sequence or choice node, with the leaf
+-                    //  (or rep surrounding it) we just got as its first node.
+-                    //  Make the new node the second node of the current node,
+-                    //  and then make it the current node.
+-                    //
+-                    ContentSpecNode* newCur = new (fGrammarPoolMemoryManager) ContentSpecNode
+-                    (
+-                        curType
+-                        , tmpLeaf2
+-                        , 0
+-                        , true
+-                        , true
+-                        , fGrammarPoolMemoryManager
+-                    );
+-                    curNode->setSecond(newCur);
+-                    lastNode = curNode;
+-                    curNode = newCur;
+-                }
+-            }
+-             else
++            if(arrNestedDecl->empty())
+             {
+-                // Cannot be valid
+-                delete headNode;  // emitError may do a throw so need to clean-up first
+-                if (opCh == chComma)
+-                {
+-                    fScanner->emitError(XMLErrs::ExpectedChoiceOrCloseParen);
+-                }
+-                 else
+-                {
+-                    fScanner->emitError
+-                    (
+-                        XMLErrs::ExpectedSeqOrCloseParen
+-                        , elemDecl.getFullName()
+-                    );
+-                }                
+-                return 0;
++                delete arrNestedDecl;
++                arrNestedDecl=NULL;
+             }
+         }
+     }
+ 
+-    //
+-    //  We saw the terminating parenthesis so lets check for any repetition
+-    //  character, and create a node for that, making the head node the child
+-    //  of it.
+-    //
+-    XMLCh repCh = fReaderMgr->peekNextChar();
+-    ContentSpecNode* retNode = makeRepNode(repCh, headNode, fGrammarPoolMemoryManager);
+-    if (retNode != headNode)
+-        fReaderMgr->getNextChar();
+-
+-    return retNode;
++    return curNode;
+ }
+ 
+ 


More information about the scm-commits mailing list