diff --git a/src/xercesc/internal/IGXMLScanner2.cpp b/src/xercesc/internal/IGXMLScanner2.cpp index e56be0197c4b3440c10f4dcdfbfaca2550fbc2fc..29cb7b7ca83186a3b7deb9ed6e3e2636a2d91125 100644 --- a/src/xercesc/internal/IGXMLScanner2.cpp +++ b/src/xercesc/internal/IGXMLScanner2.cpp @@ -1613,10 +1613,6 @@ void IGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) // walk through the list again to deal with "xsi:...." if (fDoSchema && fSeeXsi) { - // Schema Xsi Type yyyy (e.g. xsi:type="yyyyy") - XMLBufBid bbXsi(&fBufMgr); - XMLBuffer& fXsiType = bbXsi.getBuffer(); - for (XMLSize_t index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" @@ -1632,7 +1628,7 @@ void IGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) } // if schema URI has been seen, scan for the schema location and uri - // and resolve the schema grammar; or scan for schema type + // and resolve the schema grammar if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { const XMLCh* valuePtr = curPair->getValue(); @@ -1642,71 +1638,97 @@ void IGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) parseSchemaLocation(valuePtr); else if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCATION)) resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString); + } + } - if ((!fValidator || !fValidator->handlesSchema()) && - (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE) || - XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL))) - { - // If we are in the DTD mode, try to switch to the Schema - // mode. For that we need to find any XML Schema grammar - // that we can switch to. Such a grammar can only come - // from the cache (if it came from the schemaLocation - // attribute, we would be in the Schema mode already). - // - XMLGrammarPool* pool = fGrammarResolver->getGrammarPool (); - RefHashTableOfEnumerator<Grammar> i = pool->getGrammarEnumerator (); - - while (i.hasMoreElements ()) - { - Grammar& gr (i.nextElement ()); - - if (gr.getGrammarType () == Grammar::SchemaGrammarType) - { - switchGrammar (gr.getTargetNamespace ()); - break; - } - } - } + // do it another time, as xsi:type and xsi:nill only work if the schema grammar has been already + // loaded (JIRA XERCESC-1937) + for (XMLSize_t index = 0; index < attCount; index++) + { + const KVStringPair* curPair = fRawAttrList->elementAt(index); + const XMLCh* rawPtr = curPair->getKey(); + const XMLCh* prefPtr = XMLUni::fgZeroLenString; + int colonInd = fRawAttrColonList[index]; + + if (colonInd != -1) { + + fURIBuf.set(rawPtr, colonInd); + prefPtr = fURIBuf.getRawBuffer(); + } + + // scan for schema type + if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { + + const XMLCh* valuePtr = curPair->getValue(); + const XMLCh* suffPtr = &rawPtr[colonInd + 1]; - if( fValidator && fValidator->handlesSchema() ) + if(XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE) || + XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)) { - if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) + if (!fValidator || !fValidator->handlesSchema()) { - // normalize the attribute according to schema whitespace facet - DatatypeValidator* tempDV = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_QNAME); - ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, valuePtr, fXsiType, true); + // If we are in the DTD mode, try to switch to the Schema + // mode. For that we need to find any XML Schema grammar + // that we can switch to. Such a grammar can only come + // from the cache (if it came from the schemaLocation + // attribute, we would be in the Schema mode already). + // + XMLGrammarPool* pool = fGrammarResolver->getGrammarPool (); + RefHashTableOfEnumerator<Grammar> i = pool->getGrammarEnumerator (); + + while (i.hasMoreElements ()) + { + Grammar& gr (i.nextElement ()); + + if (gr.getGrammarType () == Grammar::SchemaGrammarType) + { + switchGrammar (gr.getTargetNamespace ()); + break; + } + } } - else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)) + + if( fValidator && fValidator->handlesSchema() ) { - // normalize the attribute according to schema whitespace facet - XMLBuffer& fXsiNil = fBufMgr.bidOnBuffer(); - DatatypeValidator* tempDV = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_BOOLEAN); - ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, valuePtr, fXsiNil, true); - if(XMLString::equals(fXsiNil.getRawBuffer(), SchemaSymbols::fgATTVAL_TRUE)) - ((SchemaValidator*)fValidator)->setNillable(true); - else if(XMLString::equals(fXsiNil.getRawBuffer(), SchemaSymbols::fgATTVAL_FALSE)) - ((SchemaValidator*)fValidator)->setNillable(false); - else - emitError(XMLErrs::InvalidAttValue, fXsiNil.getRawBuffer(), valuePtr); - fBufMgr.releaseBuffer(fXsiNil); + if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) + { + XMLBufBid bbXsi(&fBufMgr); + XMLBuffer& fXsiType = bbXsi.getBuffer(); + + // normalize the attribute according to schema whitespace facet + DatatypeValidator* tempDV = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_QNAME); + ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, valuePtr, fXsiType, true); + if (!fXsiType.isEmpty()) { + int colonPos = -1; + unsigned int uriId = resolveQName ( + fXsiType.getRawBuffer() + , fPrefixBuf + , ElemStack::Mode_Element + , colonPos + ); + ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId); + } + } + else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)) + { + // normalize the attribute according to schema whitespace facet + XMLBuffer& fXsiNil = fBufMgr.bidOnBuffer(); + DatatypeValidator* tempDV = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_BOOLEAN); + ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, valuePtr, fXsiNil, true); + if(XMLString::equals(fXsiNil.getRawBuffer(), SchemaSymbols::fgATTVAL_TRUE)) + ((SchemaValidator*)fValidator)->setNillable(true); + else if(XMLString::equals(fXsiNil.getRawBuffer(), SchemaSymbols::fgATTVAL_FALSE)) + ((SchemaValidator*)fValidator)->setNillable(false); + else + emitError(XMLErrs::InvalidAttValue, fXsiNil.getRawBuffer(), valuePtr); + fBufMgr.releaseBuffer(fXsiNil); + } } } } } - - if (fValidator && fValidator->handlesSchema()) { - if (!fXsiType.isEmpty()) { - int colonPos = -1; - unsigned int uriId = resolveQName ( - fXsiType.getRawBuffer() - , fPrefixBuf - , ElemStack::Mode_Element - , colonPos - ); - ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId); - } - } } + } void IGXMLScanner::parseSchemaLocation(const XMLCh* const schemaLocationStr, bool ignoreLoadSchema) diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp index 3c4a065ef5f75a2b09124de2707c10329e4d65e0..f16414e8eb3e82dbaa0c968ea2823c9ba861a31e 100644 --- a/src/xercesc/internal/SGXMLScanner.cpp +++ b/src/xercesc/internal/SGXMLScanner.cpp @@ -3459,10 +3459,6 @@ void SGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) // walk through the list again to deal with "xsi:...." if (fSeeXsi) { - // Schema Xsi Type yyyy (e.g. xsi:type="yyyyy") - XMLBufBid bbXsi(&fBufMgr); - XMLBuffer& fXsiType = bbXsi.getBuffer(); - for (XMLSize_t index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" @@ -3481,7 +3477,7 @@ void SGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) } // if schema URI has been seen, scan for the schema location and uri - // and resolve the schema grammar; or scan for schema type + // and resolve the schema grammar if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { const XMLCh* valuePtr = curPair->getValue(); @@ -3491,14 +3487,54 @@ void SGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) parseSchemaLocation(valuePtr); else if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCATION)) resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString); + } + } + + // do it another time, as xsi:type and xsi:nill only work if the schema grammar has been already + // loaded (JIRA XERCESC-1937) + if (fValidator && fValidator->handlesSchema()) + { + for (XMLSize_t index = 0; index < attCount; index++) + { + // each attribute has the prefix:suffix="value" + const KVStringPair* curPair = fRawAttrList->elementAt(index); + const XMLCh* rawPtr = curPair->getKey(); + const XMLCh* prefPtr; + + int colonInd = fRawAttrColonList[index]; + + if (colonInd != -1) { + fURIBuf.set(rawPtr, colonInd); + prefPtr = fURIBuf.getRawBuffer(); + } + else { + prefPtr = XMLUni::fgZeroLenString; + } + + // scan for schema type + if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { + + const XMLCh* valuePtr = curPair->getValue(); + const XMLCh* suffPtr = &rawPtr[colonInd + 1]; - if( fValidator && fValidator->handlesSchema() ) - { if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) { + XMLBufBid bbXsi(&fBufMgr); + XMLBuffer& fXsiType = bbXsi.getBuffer(); + // normalize the attribute according to schema whitespace facet DatatypeValidator* tempDV = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_QNAME); ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, valuePtr, fXsiType, true); + if (!fXsiType.isEmpty()) { + int colonPos = -1; + unsigned int uriId = resolveQName ( + fXsiType.getRawBuffer() + , fPrefixBuf + , ElemStack::Mode_Element + , colonPos + ); + ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId); + } } else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)) { @@ -3517,19 +3553,6 @@ void SGXMLScanner::scanRawAttrListforNameSpaces(XMLSize_t attCount) } } } - - if (fValidator && fValidator->handlesSchema()) { - if (!fXsiType.isEmpty()) { - int colonPos = -1; - unsigned int uriId = resolveQName ( - fXsiType.getRawBuffer() - , fPrefixBuf - , ElemStack::Mode_Element - , colonPos - ); - ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId); - } - } } } diff --git a/src/xercesc/sax2/SAX2XMLReader.hpp b/src/xercesc/sax2/SAX2XMLReader.hpp index 09e0982121ddf9b7a7822234af4c63a39782d805..b50fadb272516c546a7fd3153d0fc41cf60f7fbd 100644 --- a/src/xercesc/sax2/SAX2XMLReader.hpp +++ b/src/xercesc/sax2/SAX2XMLReader.hpp @@ -257,7 +257,10 @@ public: * <br>(See the SAX2 Programming Guide for detail description). * * <br>http://apache.org/xml/properties/schema/external-schemaLocation - * <br>http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation. + * <br>http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation + * <br>http://apache.org/xml/properties/security-manager + * <br>http://apache.org/xml/properties/low-water-mark + * <br>http://apache.org/xml/properties/scannerName * * It takes a void pointer as the property value. Application is required to initialize this void * pointer to a correct type. See the SAX2 Programming Guide diff --git a/tests/src/DOM/DOMTest/DTest.cpp b/tests/src/DOM/DOMTest/DTest.cpp index f73164091e011f30c2554186f9eea675c78b322a..7b3be4e929d273b816d9fd915b94546423deaf7d 100644 --- a/tests/src/DOM/DOMTest/DTest.cpp +++ b/tests/src/DOM/DOMTest/DTest.cpp @@ -40,6 +40,7 @@ #include <xercesc/util/OutOfMemoryException.hpp> #include <xercesc/framework/MemBufInputSource.hpp> #include <xercesc/validators/common/CMStateSet.hpp> +#include <xercesc/util/regx/Match.hpp> #define UNUSED(x) { if(x!=0){} } @@ -5498,6 +5499,22 @@ bool DOMTest::testRegex() { TEST_VALID_SCHEMA_REGEX("-0 +3989 -90.76754,+9E77, -0.3e+9", "(((\\+|\\-)?(0|[1-9][0-9]*)?(\\.[0-9]*)?((E|e)(\\+|\\-)?[0-9]+)?)?( )?(,)?( )?)*", __LINE__); + try + { + Match match; + RegularExpression p("([\\-\\(]?\\d{1,3}([, ]\\d{3})+\\.\\d+[\\)]?|[\\-\\(]?\\d+\\.\\d+[\\)]?).*"); + if(!p.matches("13.13", &match) || match.getStartPos(0)!=0 || match.getEndPos(0)!=5) + { + fprintf(stderr, "Regular expression test failed at line %i\n", __LINE__); + OK = false; + } + } + catch(XMLException& ) + { + fprintf(stderr, "Regular expression test failed at line %i\n", __LINE__); + OK = false; + } + delete hugeString; return OK; diff --git a/tests/src/XSTSHarness/regression/XERCESC-1937/test.xml b/tests/src/XSTSHarness/regression/XERCESC-1937/test.xml new file mode 100644 index 0000000000000000000000000000000000000000..986116c9b73dcefa2be0179e02a9ade0dba68f88 --- /dev/null +++ b/tests/src/XSTSHarness/regression/XERCESC-1937/test.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<p xsi:type="Person" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="test.xsd"> + <name>John Doe</name> +</p> + diff --git a/tests/src/XSTSHarness/regression/XERCESC-1937/test.xsd b/tests/src/XSTSHarness/regression/XERCESC-1937/test.xsd new file mode 100644 index 0000000000000000000000000000000000000000..24b5b5578716426d531d325555b39afa93f25a85 --- /dev/null +++ b/tests/src/XSTSHarness/regression/XERCESC-1937/test.xsd @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:complexType name="Person"> + <xsd:sequence> + <xsd:element name="name"/> + </xsd:sequence> + </xsd:complexType> +</xsd:schema> + diff --git a/tests/src/XSTSHarness/regression/Xerces.testSet b/tests/src/XSTSHarness/regression/Xerces.testSet index d176582fa4f2601fa4a68fc63d426053e1112294..beb9616a95a943d90d260d1f4726d5e3ce676957 100644 --- a/tests/src/XSTSHarness/regression/Xerces.testSet +++ b/tests/src/XSTSHarness/regression/Xerces.testSet @@ -810,4 +810,20 @@ <current status="accepted" date="2009-10-28"/> </schemaTest> </testGroup> + <testGroup name="XERCESC-1937"> + <annotation> + <documentation>xsi:type is not applied to root element</documentation> + </annotation> + <documentationReference xlink:href="https://issues.apache.org/jira/browse/XERCESC-1937"/> + <schemaTest name="XERCESC-1937-1"> + <schemaDocument xlink:href="./XERCESC-1937/test.xsd"/> + <expected validity="valid"/> + <current status="accepted" date="2010-08-09"/> + </schemaTest> + <instanceTest name="XERCESC-1937-2"> + <instanceDocument xlink:href="./XERCESC-1937/test.xml"/> + <expected validity="valid"/> + <current status="accepted" date="2010-08-09"/> + </instanceTest> + </testGroup> </testSet>