diff --git a/xerces-c--CVE-2009-1885.diff b/xerces-c-3.0.1-CVE-2009-1885.patch similarity index 95% rename from xerces-c--CVE-2009-1885.diff rename to xerces-c-3.0.1-CVE-2009-1885.patch index e2fff00..7fe05f1 100644 --- a/xerces-c--CVE-2009-1885.diff +++ b/xerces-c-3.0.1-CVE-2009-1885.patch @@ -1,5 +1,5 @@ ---- src/xercesc/validators/DTD/DTDScanner.cpp 2007-08-28 22:43:25.000000000 +0400 -+++ src/xercesc/validators/DTD/DTDScanner.cpp 2009-08-06 17:21:40.086497628 +0400 +--- src/xercesc/validators/DTD/DTDScanner.cpp ++++ src/xercesc/validators/DTD/DTDScanner.cpp @@ -27,7 +27,9 @@ #include #include @@ -18,12 +18,12 @@ XERCES_CPP_NAMESPACE_BEGIN -@@ -1046,338 +1047,356 @@ +@@ -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 -- unsigned int curReader; +- XMLSize_t curReader; - + ValueStackOf* arrNestedDecl=NULL; // @@ -41,58 +41,28 @@ + while(fReaderMgr->skippedChar(chOpenParen)) { - curReader = fReaderMgr->getCurrentReaderNum(); -- -- // Lets call ourself and get back the resulting node -- curNode = scanChildren(elemDecl, bufToUse); + // to check entity nesting + const XMLSize_t curReader = fReaderMgr->getCurrentReaderNum(); + if(arrNestedDecl==NULL) + arrNestedDecl=new (fMemoryManager) ValueStackOf(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; -- -- if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getDoValidation()) -- fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE); -+ // Check for a PE ref here, but don't require spaces -+ checkForPERef(false, true); - } -- else + // We must find a leaf node here, either standalone or nested in the parenthesis + if (!fReaderMgr->getName(bufToUse)) - { -- // Not a nested paren, so it must be a leaf node -- if (!fReaderMgr->getName(bufToUse)) -- { -- fScanner->emitError(XMLErrs::ExpectedElementName); -- return 0; -- } ++ { + 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 ++ + // + // 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 @@ -102,13 +72,12 @@ + if (!decl) + { + decl = new (fGrammarPoolMemoryManager) DTDElementDecl - ( -- decl->getElementName() ++ ( + bufToUse.getRawBuffer() + , fEmptyNamespaceId + , DTDElementDecl::Any - , fGrammarPoolMemoryManager - ); ++ , fGrammarPoolMemoryManager ++ ); + decl->setCreateReason(XMLElementDecl::InContentModel); + decl->setExternalElemDeclaration(isReadingExternalEntity()); + fDTDGrammar->putElemDecl(decl); @@ -118,48 +87,136 @@ + decl->getElementName() + , fGrammarPoolMemoryManager + ); - -- // Check for a PE ref here, but don't require spaces -- const bool gotSpaces = checkForPERef(false, true); ++ + // 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) +- 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)) - { +- { - if (fScanner->emitErrorWillThrowException(XMLErrs::UnexpectedWhitespace)) - { - delete tmpNode; - } - fScanner->emitError(XMLErrs::UnexpectedWhitespace); -+ delete tmpNode; - } -- fReaderMgr->getNextChar(); +- } ++ curType = ContentSpecNode::Choice; ++ headNode = new (fGrammarPoolMemoryManager) ContentSpecNode ++ ( ++ curType ++ , curNode ++ , 0 ++ , true ++ , true ++ , fGrammarPoolMemoryManager ++ ); ++ curNode = headNode; ++ } ++ else ++ { ++ headNode = curNode; + fReaderMgr->getNextChar(); - curNode = tmpNode; -+ fScanner->emitError(XMLErrs::UnexpectedWhitespace); } -+ fReaderMgr->getNextChar(); -+ curNode = tmpNode; - } - +- } +- - // Check for a PE ref here, but don't require spaces - checkForPERef(false, true); -+ while(arrNestedDecl==NULL || !arrNestedDecl->empty()) -+ { -+ // 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 @@ -177,24 +234,7 @@ - fScanner->emitError(XMLErrs::ExpectedSeqChoiceLeaf); - return 0; - } -+ // -+ // 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 @@ -236,47 +276,6 @@ - headNode = curNode; - fReaderMgr->getNextChar(); - } -+ // -+ // 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 @@ -327,8 +326,7 @@ - if ((curNode->getType() == ContentSpecNode::Choice) - || (curNode->getType() == ContentSpecNode::Sequence)) + if (fReaderMgr->lookingAtChar(chPercent)) - { -- if (!curNode->getSecond()) ++ { + checkForPERef(false, true); + } + else if (fReaderMgr->skippedSpace()) @@ -337,7 +335,8 @@ + 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 @@ -368,7 +367,7 @@ - checkForPERef(false, true); - - if (fReaderMgr->skippedChar(chOpenParen)) -+ else if (fReaderMgr->skippedChar(opCh)) ++ else if (fReaderMgr->skippedChar(opCh)) { - curReader = fReaderMgr->getCurrentReaderNum(); + // Check for a PE ref here, but don't require spaces @@ -427,7 +426,7 @@ + lastNode = curNode; + curNode = newCur; } -+ else ++ else + { + // + // Got to be a leaf node, so get a name. If we cannot get @@ -439,9 +438,7 @@ + fScanner->emitError(XMLErrs::ExpectedElementName); + return 0; + } - -- if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getDoValidation()) -- fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE); ++ + // + // Create a leaf node for it. If we can find the element + // id for this element, then use it. Else, we have to @@ -463,6 +460,14 @@ + 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 - ( @@ -476,12 +481,6 @@ - curNode->setSecond(newCur); - lastNode = curNode; - curNode = newCur; -+ ContentSpecNode* tmpLeaf = new (fGrammarPoolMemoryManager) ContentSpecNode -+ ( -+ decl->getElementName() -+ , fGrammarPoolMemoryManager -+ ); -+ + // Check for a repetition character after the leaf + const XMLCh repCh = fReaderMgr->peekNextChar(); + ContentSpecNode* tmpLeaf2 = makeRepNode(repCh, tmpLeaf, fGrammarPoolMemoryManager); @@ -545,9 +544,9 @@ + XMLErrs::ExpectedSeqOrCloseParen + , elemDecl.getFullName() ); - decl->setCreateReason(XMLElementDecl::InContentModel); - decl->setExternalElemDeclaration(isReadingExternalEntity()); - fDTDGrammar->putElemDecl(decl); +- decl->setCreateReason(XMLElementDecl::InContentModel); +- decl->setExternalElemDeclaration(isReadingExternalEntity()); +- fDTDGrammar->putElemDecl(decl); - } + } + return 0; @@ -569,12 +568,7 @@ + curNode = makeRepNode(repCh, headNode, fGrammarPoolMemoryManager); + if (curNode != headNode) + fReaderMgr->getNextChar(); - -- // Check for a repetition character after the leaf -- const XMLCh repCh = fReaderMgr->peekNextChar(); -- ContentSpecNode* tmpLeaf2 = makeRepNode(repCh, tmpLeaf, fGrammarPoolMemoryManager); -- if (tmpLeaf != tmpLeaf2) -- fReaderMgr->getNextChar(); ++ + // prepare for recursion + if(arrNestedDecl==NULL) + break; @@ -584,6 +578,15 @@ + 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. @@ -605,10 +608,6 @@ - } - } - else -+ const XMLSize_t curReader = arrNestedDecl->pop(); -+ if (curReader != fReaderMgr->getCurrentReaderNum() && fScanner->getValidationScheme() == XMLScanner::Val_Always) -+ fScanner->getValidator()->emitError(XMLValid::PartialMarkupInPE); -+ + if(arrNestedDecl->empty()) { - // Cannot be valid diff --git a/xerces-c.spec b/xerces-c.spec index a636904..7654750 100644 --- a/xerces-c.spec +++ b/xerces-c.spec @@ -1,14 +1,15 @@ Summary: Validating XML Parser Name: xerces-c Version: 3.0.1 -Release: 15%{?dist} +Release: 16%{?dist} License: ASL 2.0 Group: System Environment/Libraries URL: http://xml.apache.org/xerces-c/ Source0: http://archive.apache.org/dist/xml/xerces-c/Xerces-C_3_0_1/sources/xerces-c-3.0.1.tar.gz +Patch0: xerces-c-3.0.1-CVE-2009-1885.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: dos2unix sed +BuildRequires: dos2unix %description Xerces-C is a validating XML parser written in a portable @@ -44,111 +45,62 @@ 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. -#%package samples -#Summary: Sample applications using Xerces-C++ -#Group: Applications/Text -#Requires: %{name} = %{version}-devel-%{release} - -#%description samples -#Sample applications using Xerces-C++. - - %prep %setup -q -%{__perl} -pi.orig -e 's|(PREFIX.)/lib\b|$1/%{_lib}|g' ./configure ./Makefile.in +%patch0 -p0 -b .CVE-2009-1885 +# Copy samples before build to avoid including built binaries in -doc package +mkdir -p _docs +cp -a samples/ _docs/ %build -%configure -make +%configure --disable-static --disable-pretty-make +make %{?_smp_mflags} %install -%{__rm} -rf $RPM_BUILD_ROOT -%{__make} install DESTDIR="$RPM_BUILD_ROOT" -# get rid of files not allowed in a doc rpm -# correct errors in line endings and encoding +rm -rf $RPM_BUILD_ROOT +make install DESTDIR="$RPM_BUILD_ROOT" +# Correct errors in encoding iconv -f iso8859-1 -t utf-8 CREDITS > CREDITS.tmp && mv -f CREDITS.tmp CREDITS +# Correct errors in line endings pushd doc; dos2unix -U *.xml; popd -pushd samples -rm -rf .libs _libs -rm -f *.o -rm -f src/*/*.o -rm -f *.lo -rm -f *.tab.c -rm -rf src/*/.deps -rm -rf src/*/.dirstamp -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f Makefile -rm -f CreateDOMDocument -rm -f DOMCount -rm -f DOMPrint -rm -f EnumVal -rm -f MemParse -rm -f PParse -rm -f PSVIWriter -rm -f Redirect -rm -f SAX2Count -rm -f SAX2Print -rm -f SAXCount -rm -f SAXPrint -rm -f SCMPrint -rm -f SEnumVal -rm -f StdInParse -rm -f XInclude -popd - +# Remove unwanted binaries +rm -rf $RPM_BUILD_ROOT%{_bindir} +# Remove .la files +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %clean -%{__rm} -rf $RPM_BUILD_ROOT +rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc LICENSE %{_libdir}/libxerces-c-3.*.so -%exclude %{_libdir}/libxerces-c.a -%exclude %{_libdir}/libxerces-c.la -%exclude %{_bindir}/CreateDOMDocument -%exclude %{_bindir}/DOMCount -%exclude %{_bindir}/DOMPrint -%exclude %{_bindir}/EnumVal -%exclude %{_bindir}/MemParse -%exclude %{_bindir}/PParse -%exclude %{_bindir}/PSVIWriter -%exclude %{_bindir}/Redirect -%exclude %{_bindir}/SAX2Count -%exclude %{_bindir}/SAX2Print -%exclude %{_bindir}/SAXCount -%exclude %{_bindir}/SAXPrint -%exclude %{_bindir}/SCMPrint -%exclude %{_bindir}/SEnumVal -%exclude %{_bindir}/StdInParse -%exclude %{_bindir}/XInclude - %files devel %defattr(-,root,root,-) %{_libdir}/libxerces-c.so %{_libdir}/pkgconfig/xerces-c.pc %{_includedir}/xercesc/ -%exclude %{_libdir}/libxerces-c.a -%exclude %{_libdir}/libxerces-c.la %files doc %defattr(-,root,root,-) -%doc README LICENSE NOTICE CREDITS doc samples - -#%files samples -#%defattr(-,root,root,-) -#%{_datadir}/%{name}/samples +%doc README LICENSE NOTICE CREDITS doc _docs/* %changelog +* Sun Feb 07 2010 Kalev Lember 3.0.1-16 +- Reintroduce a patch for CVE-2009-1885 +- Don't build static library +- Use parallel make +- Spec file clean up + * Thu Feb 4 2010 Jonathan Robie 3.0.1-15 - Corrected .spec file +- Corrected .spec file * Wed Feb 3 2010 Jonathan Robie 3.0.1-1 - Move to Xerces 3.0.1. +- Move to Xerces 3.0.1. * Thu Aug 6 2009 Peter Lemenkov 2.8.0-5 - Fix CVE-2009-1885