コード例 #1
0
void ValidationContextImpl::addId(const XMLCh * const content)
{
    if (!fIdRefList || !fToCheckIdRefList)
        return;

    XMLRefInfo* idEntry = fIdRefList->get(content);

    if (idEntry)
    {
        if (idEntry->getDeclared())
        {
            ThrowXMLwithMemMgr1(InvalidDatatypeValueException
                    , XMLExcepts::VALUE_ID_Not_Unique
                    , content
                    , fMemoryManager);
        }
    }
    else
    {
        idEntry = new (fMemoryManager) XMLRefInfo(content, false, false, fMemoryManager);
        fIdRefList->put((void*)idEntry->getRefName(), idEntry);
    }

    //
    //  Mark it declared
    //
    idEntry->setDeclared(true);

}
コード例 #2
0
void ValidationContextImpl::addIdRef(const XMLCh * const content)
{
    if (!fIdRefList || !fToCheckIdRefList)
        return;

    XMLRefInfo* idEntry = fIdRefList->get(content);

    if (!idEntry)
    {
        idEntry = new (fMemoryManager) XMLRefInfo(content, false, false, fMemoryManager);
        fIdRefList->put((void*)idEntry->getRefName(), idEntry);
    }

    //
    //  Mark it used
    //
    idEntry->setUsed(true);

}
コード例 #3
0
void
DTDValidator::validateAttrValue(const   XMLAttDef*      attDef
                                , const XMLCh* const    attrValue
                                , bool                  preValidation
                                , const XMLElementDecl*)
{
    //
    //  Get quick refs to lost of of the stuff in the passed objects in
    //  order to simplify the code below, which will reference them very
    //  often.
    //
    const XMLAttDef::AttTypes       type = attDef->getType();
    const XMLAttDef::DefAttTypes    defType = attDef->getDefaultType();
    const XMLCh* const              valueText = attDef->getValue();
    const XMLCh* const              fullName = attDef->getFullName();
    const XMLCh* const              enumList = attDef->getEnumeration();

    //
    //  If the default type is fixed, then make sure the passed value maps
    //  to the fixed value.
    //  If during preContentValidation, the value we are validating is the fixed value itself
    //  so no need to compare.
    //  Only need to do this for regular attribute value validation
    //
    if (defType == XMLAttDef::Fixed && !preValidation)
    {
        if (!XMLString::equals(attrValue, valueText))
            emitError(XMLValid::NotSameAsFixedValue, fullName, attrValue, valueText);
    }

    //
    //  If its a CDATA attribute, then we are done with any DTD level
    //  validation else do the rest.
    //
    if (type == XMLAttDef::CData)
        return;



    // An empty string cannot be valid for any of the other types
    if (!attrValue[0])
    {
        emitError(XMLValid::InvalidEmptyAttValue, fullName);
        return;
    }

    // See whether we are doing multiple values or not
    const bool multipleValues =
    (
        (type == XMLAttDef::IDRefs)
        || (type == XMLAttDef::Entities)
        || (type == XMLAttDef::NmTokens)
        || (type == XMLAttDef::Notation)
        || (type == XMLAttDef::Enumeration)
    );

    // And whether we must check for a first name char
    const bool firstNameChar =
    (
        (type == XMLAttDef::ID)
        || (type == XMLAttDef::IDRef)
        || (type == XMLAttDef::IDRefs)
        || (type == XMLAttDef::Entity)
        || (type == XMLAttDef::Entities)
        || (type == XMLAttDef::Notation)
    );

    // Whether it requires ref checking stuff
    const bool isARefType
    (
        (type == XMLAttDef::ID)
        || (type == XMLAttDef::IDRef)
        || (type == XMLAttDef::IDRefs)
    );

    // Some trigger flags to avoid issuing redundant errors and whatnot    
    bool alreadyCapped = false;

    //
    //  Make a copy of the text that we can mangle and get a pointer we can
    //  move through the value
    //

    // Use a stack-based buffer, when possible...
    XMLCh   tempBuffer[100];

    XMLCh* pszTmpVal = 0;

    ArrayJanitor<XMLCh> janTmpVal(0);

    if (XMLString::stringLen(attrValue) < sizeof(tempBuffer) / sizeof(tempBuffer[0]))
    {
        XMLString::copyString(tempBuffer, attrValue);
        pszTmpVal = tempBuffer;
    }
    else
    {
        janTmpVal.reset(XMLString::replicate(attrValue, getScanner()->getMemoryManager()), getScanner()->getMemoryManager());
        pszTmpVal = janTmpVal.get();
    }

    XMLCh* valPtr = pszTmpVal;

    bool doNamespace = getScanner()->getDoNamespaces();

    while (true)
    {
        //
        //  Make sure the first character is a valid first name char, i.e.
        //  if its a Name value. For NmToken values we don't treat the first
        //  char any differently.
        //
        if (firstNameChar)
        {
            // If its not, emit and error but try to keep going
            if (!getReaderMgr()->getCurrentReader()->isFirstNameChar(*valPtr))
                emitError(XMLValid::AttrValNotName, valPtr, fullName);
            valPtr++;
        }

        // Make sure all the remaining chars are valid name chars
        while (*valPtr)
        {
            //
            //  If we hit a whitespace, its either a break between two
            //  or more values, or an error if we have a single value.
            //
            //
            //   XML1.0-3rd
            //
            //   [6]   Names   ::=   Name (#x20 Name)*
            //   [8]   Nmtokens   ::=   Nmtoken (#x20 Nmtoken)*
            //
            //   only and only ONE #x20 is allowed to be the delimiter
            //
            if (*valPtr==chSpace)
            {
                if (!multipleValues)
                {
                    emitError(XMLValid::NoMultipleValues, fullName);
                    return;
                }

                break;
            }

            // Now this attribute can be of type
            //     ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION, NMTOKEN, NMTOKENS, ENUMERATION
            //  All these must be valid XMLName
            // If namespace is enabled, colon is not allowed in the first 6

            if (doNamespace && *valPtr == chColon && firstNameChar)
                emitError(XMLValid::ColonNotValidWithNS);

            if (!getReaderMgr()->getCurrentReader()->isNameChar(*valPtr))
            {
                emitError(XMLValid::AttrValNotName, valPtr, fullName);
                return;
            }
            valPtr++;
        }

        //
        //  Cap it off at the current non-name char. If already capped,
        //  then remember this.
        //
        if (!(*valPtr))
            alreadyCapped = true;
        *valPtr = 0;

        //
        //  If this type of attribute requires that we track reference
        //  stuff, then handle that.
        //
        if (isARefType)
        {
            if ((type == XMLAttDef::ID)
            ||  (type == XMLAttDef::IDRef)
            ||  (type == XMLAttDef::IDRefs))
            {
                XMLRefInfo* find = getScanner()->getIDRefList()->get(pszTmpVal);
                if (find)
                {
                    if (find->getDeclared() && (type == XMLAttDef::ID))
                        emitError(XMLValid::ReusedIDValue, pszTmpVal);
                }
                 else
                {
                    find = new (getScanner()->getMemoryManager()) XMLRefInfo
                    (
                        pszTmpVal
                        , false
                        , false
                        , getScanner()->getMemoryManager()
                    );
                    getScanner()->getIDRefList()->put((void*)find->getRefName(), find);
                }

                //
                //  Mark it declared or used, which might be redundant in some cases
                //  but not worth checking
                //
                if (type == XMLAttDef::ID)
                    find->setDeclared(true);
                else {
                    if (!preValidation) {
                        find->setUsed(true);
                    }
                }
            }
        }
         else if (!preValidation && ((type == XMLAttDef::Entity) || (type == XMLAttDef::Entities)))
        {
            //
            //  If its refering to a entity, then look up the name in the
            //  general entity pool. If not there, then its an error. If its
            //  not an external unparsed entity, then its an error.
            //
            //  In case of pre-validation, the above errors should be ignored.
            //
            const XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(pszTmpVal);
            if (decl)
            {
                if (!decl->isUnparsed())
                    emitError(XMLValid::BadEntityRefAttr, pszTmpVal, fullName);
            }
             else
            {
                emitError
                (
                    XMLValid::UnknownEntityRefAttr
                    , fullName
                    , pszTmpVal
                );
            }
        }
         else if ((type == XMLAttDef::Notation) || (type == XMLAttDef::Enumeration))
        {
            //
            //  Make sure that this value maps to one of the enumeration or
            //  notation values in the enumList parameter. We don't have to
            //  look it up in the notation pool (if a notation) because we
            //  will look up the enumerated values themselves. If they are in
            //  the notation pool (after the DTD is parsed), then obviously
            //  this value will be legal since it matches one of them.
            //
            if (!XMLString::isInList(pszTmpVal, enumList))
                emitError(XMLValid::DoesNotMatchEnumList, pszTmpVal, fullName);
        }

        // If not doing multiple values, then we are done
        if (!multipleValues)
            break;

        //
        //  If we are at the end, then break out now, else move up to the
        //  next char and update the base pointer.
        //
        if (alreadyCapped)
            break;

        valPtr++;
        pszTmpVal = valPtr;
    }

}