From e3213d7464410034386c7c34d634da3cadf2c1bb Mon Sep 17 00:00:00 2001
From: Khaled Noaman <knoaman@apache.org>
Date: Thu, 7 Jun 2001 19:08:35 +0000
Subject: [PATCH] Fix in validator reuse for 'xsi:nill' and faulted in
 attributes.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@172746 13f79535-47bb-0310-9956-ffa450edef68
---
 src/internal/XMLScanner.cpp  |  36 +++++------
 src/internal/XMLScanner2.cpp | 112 +++++++++++++++++------------------
 2 files changed, 69 insertions(+), 79 deletions(-)

diff --git a/src/internal/XMLScanner.cpp b/src/internal/XMLScanner.cpp
index ae32b04b8..f437b3208 100644
--- a/src/internal/XMLScanner.cpp
+++ b/src/internal/XMLScanner.cpp
@@ -2344,10 +2344,9 @@ bool XMLScanner::scanStartTag(bool& gotData)
                 //
                 if (fValidate)
                 {
-                   // This is to tell the reuse Validator that this attribute was
-                   // faulted-in, was not an attribute in the attdef originally
-                    if(!fReuseGrammar)
-                       attDef->setCreateReason(XMLAttDef::JustFaultIn);
+                    // This is to tell the Validator that this attribute was
+                    // faulted-in, was not an attribute in the attdef originally
+                    attDef->setCreateReason(XMLAttDef::JustFaultIn);
 
                     fValidator->emitError
                     (
@@ -2359,22 +2358,17 @@ bool XMLScanner::scanStartTag(bool& gotData)
             }
             else
             {
-               // If we are reusing validator and this attribute was faulted-in,
-               // then emit an error
-               if (fValidate)
-               {
-                  if (fReuseGrammar && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
-                  {
-                      //reset the CreateReason to avoid redundant error
-                      attDef->setCreateReason(XMLAttDef::NoReason);
-
-                      fValidator->emitError
-                      (
-                          XMLValid::AttNotDefinedForElement
-                          , fAttNameBuf.getRawBuffer()
-                          , elemDecl->getFullName()
-                      );
-                   }
+                // If this attribute was faulted-in and first occurence,
+                // then emit an error
+                if (fValidate && attDef->getCreateReason() == XMLAttDef::JustFaultIn
+                    && !attDef->getProvided())
+                {
+                    fValidator->emitError
+                    (
+                        XMLValid::AttNotDefinedForElement
+                        , fAttNameBuf.getRawBuffer()
+                        , elemDecl->getFullName()
+                    );
                 }
             }
 
@@ -2447,7 +2441,7 @@ bool XMLScanner::scanStartTag(bool& gotData)
             //  errors, but we just keep going. We only need to do this if
             //  we are validating.
             //
-            if (!wasAdded)
+            if (!wasAdded && attDef->getCreateReason() != XMLAttDef::JustFaultIn)
             {
                 // Let the validator pass judgement on the attribute value
                 if (fValidate)
diff --git a/src/internal/XMLScanner2.cpp b/src/internal/XMLScanner2.cpp
index e0d66322e..6d4f5c41f 100644
--- a/src/internal/XMLScanner2.cpp
+++ b/src/internal/XMLScanner2.cpp
@@ -243,10 +243,9 @@ XMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
             {
                 if (fValidate && !isNSAttr)
                 {
-                    // This is to tell the reuse Validator that this attribute was
+                    // This is to tell the Validator that this attribute was
                     // faulted-in, was not an attribute in the attdef originally
-                    if(!fReuseGrammar)
-                       attDef->setCreateReason(XMLAttDef::JustFaultIn);
+                    attDef->setCreateReason(XMLAttDef::JustFaultIn);
 
                     XMLBuffer bufURI;
                     getURIText(uriId, bufURI);
@@ -266,35 +265,47 @@ XMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
             }
             else
             {
-                // If we are reusing validator and this attribute was faulted-in,
+                // If this attribute was faulted-in and first occurence,
                 // then emit an error
-                if (fValidate && !isNSAttr)
+                if (fValidate && !isNSAttr
+                    && attDef->getCreateReason() == XMLAttDef::JustFaultIn
+                    && !attDef->getProvided())
                 {
-                   if (fReuseGrammar && attDef->getCreateReason()==XMLAttDef::JustFaultIn)
-                   {
-                      //reset the CreateReason to avoid redundant error
-                      attDef->setCreateReason(XMLAttDef::NoReason);
-
-                      XMLBuffer bufURI;
-                      getURIText(uriId, bufURI);
-
-                      XMLBuffer bufMsg;
-                      bufMsg.append(chOpenCurly);
-                      bufMsg.append(bufURI.getRawBuffer());
-                      bufMsg.append(chCloseCurly);
-                      bufMsg.append(suffPtr);
-                      fValidator->emitError
-                      (
-                          XMLValid::AttNotDefinedForElement
-                          , bufMsg.getRawBuffer()
-                          , elemDecl.getFullName()
-                      );
-                   }
+                    XMLBuffer bufURI;
+                    getURIText(uriId, bufURI);
+
+                    XMLBuffer bufMsg;
+                    bufMsg.append(chOpenCurly);
+                    bufMsg.append(bufURI.getRawBuffer());
+                    bufMsg.append(chCloseCurly);
+                    bufMsg.append(suffPtr);
+                    fValidator->emitError
+                    (
+                        XMLValid::AttNotDefinedForElement
+                        , bufMsg.getRawBuffer()
+                        , elemDecl.getFullName()
+                    );
                 }
              }
 
-            // Mark this one as provided (even if it was faulted in)
-            attDef->setProvided(true);
+            //
+            //  If its already provided, then there are more than one of
+            //  this attribute in this start tag, so emit an error.
+            //
+            if (attDef->getProvided())
+            {
+                emitError
+                (
+                    XMLErrs::AttrAlreadyUsedInSTag
+                    , attDef->getFullName()
+                    , elemDecl.getFullName()
+                );
+            }
+             else
+            {
+                // Mark this one as already seen
+                attDef->setProvided(true);
+            }
 
             //
             //  Now normalize the raw value since we have the attribute type. We
@@ -312,7 +323,7 @@ XMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
             //
             //  If we found an attdef for this one, then lets validate it.
             //
-            if (!wasAdded)
+            if (!wasAdded && attDef->getCreateReason() != XMLAttDef::JustFaultIn)
             {
                 if (fValidate)
                 {
@@ -335,24 +346,6 @@ XMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs
 
             // Save the type for later use
             attType = attDef->getType();
-
-            // Make sure it's not a dup of anything so far
-            for (unsigned int inner = 0; inner < retCount; inner++)
-            {
-                // If they have the same URI, then compare names
-                if (uriId == toFill.elementAt(inner)->getURIId())
-                {
-                    if (!XMLString::compareString(suffPtr, toFill.elementAt(inner)->getName()))
-                    {
-                        emitError
-                        (
-                            XMLErrs::AttrAlreadyUsedInSTag
-                            , attDef->getFullName()
-                            , elemDecl.getFullName()
-                        );
-                    }
-                }
-            }
         }
          else
         {
@@ -1106,7 +1099,7 @@ void XMLScanner::scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* t
     }
 
     // walk through the list again to deal with "xsi:...."
-    if (fDoSchema && fSeeXsi && !fReuseGrammar)
+    if (fDoSchema && fSeeXsi)
     {
         for (index = 0; index < attCount; index++)
         {
@@ -1121,19 +1114,22 @@ void XMLScanner::scanRawAttrListforNameSpaces(const RefVectorOf<KVStringPair>* t
 
             // if schema URI has been seen, scan for the schema location and uri
             // and resolve the schema grammar; or scan for schema type
-
             if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) {
-                if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
-                    parseSchemaLocation(valuePtr);
-                else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
-                    resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
-                else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_TYPE))
-                    fXsiType.set(valuePtr);
-                else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgATT_NILL)) {
-                    if (fValidator) {
-                        if (!XMLString::compareString(valuePtr, SchemaSymbols::fgATTVAL_TRUE))
+
+                if (!fReuseGrammar) {
+                    if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION))
+                        parseSchemaLocation(valuePtr);
+                    else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
+                        resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString);
+                }
+
+                if (!XMLString::compareString(suffPtr, SchemaSymbols::fgXSI_TYPE)) {
+                        fXsiType.set(valuePtr);
+                }
+                else if (!XMLString::compareString(suffPtr, SchemaSymbols::fgATT_NILL)
+                         && fValidator
+                         && !XMLString::compareString(valuePtr, SchemaSymbols::fgATTVAL_TRUE)) {
                             ((SchemaValidator*)fValidator)->setNillable(true);
-                    }
                 }
             }
         }
-- 
GitLab