📄 looseprs.cpp
字号:
tag = NULL; return XMLPBadAttribute; } } else { tag->new_attribute()->name = 0; } if(bUseNonQuotedValues) { if(bHasDirectives) { res = GetString(cur, close, tag->m_cur_attribute->value, AttributeValueDirective); } else { res = GetString(cur, close, tag->m_cur_attribute->value, AttributeValueNoQuote); } } else { res = GetString(cur, close, tag->m_cur_attribute->value, AttributeValue); } if(res == GSMissingQuote) { delete tag; tag = NULL; return XMLPAttributeValueNotQuoted; } else if(res != GSFoundExpected) { delete tag; tag = NULL; return XMLPBadAttribute; } } } if(m_bStrictCompliance) { // error on duplicate attributes CHXMapStringToOb dupMap; BOOL bDupFound = FALSE; XMLAttribute* pAttr = NULL; for(UINT32 i=0;i<tag->m_numAttributes;++i) { pAttr = tag->attribute(i); void* pLookupValue = NULL; if(pAttr->name) { if(dupMap.Lookup(pAttr->name, pLookupValue)) { bDupFound = TRUE; break; } else { dupMap.SetAt(pAttr->name, NULL); } } } if(bDupFound) {#if defined(XXXEH_CHECK_THIS_IN_AFTER_U2_RELEASE) return XMLPDupAttribute;#else /* XXXEH- Back out BAB's fix for PR 9172 because it breaks a lot of * old content (this rebreaks PR 9172 and fixes PR 12447) */ HX_ASSERT(1); //line exists only for setting a breakpoint.#endif } } return XMLPTag;}XMLParseResultXMLParser::ScanTag(const char* open, const char* close, XMLTag* tag){ const char* cur = open+1; const char* afterclose = close+1; char cQuote = '"'; CHXXMLEncode xmlStr(m_pEncoding, (BYTE*)cur, close - cur); UINT16 uLen = 0; const char* ptr = (const char*)xmlStr.GetNextChar(uLen); //tag->m_need_close //tag->m_type; // check the spacing.... switch (tag->m_type) { case XMLEndTag: { // scan name... if (!xmlStr.IsNameValid((const BYTE*)tag->m_name, strlen(tag->m_name))) { XMLError* err = NULL; SetError(err, XMLErrorInvalidName, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); } } break; case XMLPlainTag: case XMLProcInstTag: { // scan tag if (!xmlStr.IsNameValid((const BYTE*)tag->m_name, strlen(tag->m_name))) { XMLError* err = NULL; SetError(err, XMLErrorInvalidName, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); } // check PI name //if (!xmlStr.IsPINameValid(tag->m_name, strlen(tag->m_name))) //{ // XMLError* err = NULL; // SetError(err, XMLErrorInvalidPITarget, m_ulTagStartLine, m_ulTagStartCol, // tag->m_name, strlen(tag->m_name), 0); // tag->m_errs->Add(err); // } // check the spacing. enum { InTagName, InTag, InBeginAttributeName, InAttributeName, InEndAttributeName, InBeginAttributeValue, InAttributeValue, Done } state; state = InTagName; for (const char* pos = cur; *pos && pos < close && state != Done; pos = (const char*)xmlStr.GetNextChar(uLen)) { switch (state) { case InTagName: { // go to first white space if ( isspace(*pos) ) { state = InBeginAttributeName; } else if ( *pos == '>' ) { // done state = Done; } } break; case InTag: { if ( *pos == '>' || (*pos == '/' && *(pos+1) == '>')) { // done. state = Done; } else { // grab the first char... keep it and switch states. // it should be a space... state = InBeginAttributeName; if (!isspace(*pos)) { XMLError* err = NULL; SetError(err, XMLErrorMissingReqSpace, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); } } } break; case InBeginAttributeName: { if ( isspace(*pos) ) { // continue... } else if ( *pos == '=' ) { XMLError* err = NULL; SetError(err, XMLErrorMissingEquals, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); state = InBeginAttributeValue; } else if ( *pos == '>' || (*pos == '/' && *(pos+1) == '>')) { // done state = Done; } else { state = InAttributeName; } } break; case InAttributeName: { if ( isspace(*pos) ) { state = InEndAttributeName; } else if ( *pos == '=' ) { state = InBeginAttributeValue; } else if ( *pos == '>' ) { XMLError* err = NULL; SetError(err, XMLErrorMissingEquals, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); // done state = Done; } else if (*pos == '\'' || *pos == '"') { XMLError* err = NULL; SetError(err, XMLErrorBadAttribute, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); cQuote = *pos; state = InAttributeValue; } } break; case InEndAttributeName: { if ( isspace(*pos) ) { // continue.. } else if ( *pos == '=' ) { state = InBeginAttributeValue; } else if ( *pos == '>' ) { XMLError* err = NULL; SetError(err, XMLErrorMissingEquals, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); state = Done; } else { // hmm. we got a non whitespace before the = //First, let's see if we have a ["] or a ['] // (i.e., an attribute value start) in which // case the author must have forgotten to // put an '=' between the name/value pair. // In this case, we need to keep the renderers // from firing off an error with old bad content, // so we pretend we're in the "InAttributeValue" // state: if ( *pos == '\'' ) { XMLError* err = NULL; SetError(err, XMLErrorBadAttribute, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); cQuote = *pos; state = InAttributeValue; } else if ( *pos == '\"' ) { XMLError* err = NULL; SetError(err, XMLErrorBadAttribute, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); cQuote = *pos; state = InAttributeValue; } else { XMLError* err = NULL; SetError(err, XMLErrorBadAttribute, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); // lets go back to the attribute name state. state = InAttributeName; } } } break; case InBeginAttributeValue: { if ( isspace(*pos) ) { } else if ( *pos == '\'' || *pos == '\"') { cQuote = *pos; state = InAttributeValue; } else if ( *pos == '>' ) { XMLError* err = NULL; SetError(err, XMLErrorMissingEquals, m_ulTagStartLine, m_ulTagStartCol, tag->m_name, strlen(tag->m_name), 0); tag->m_errs->Add(err); // done state = Done; } } break; case InAttributeValue: { if ( *pos == cQuote ) { state = InTag; } } break; } } } break; case XMLCommentTag: { // we will not scan... } break; case XMLDirectiveTag: { // TODO: scan Directive. } break; } // error on duplicate attributes // also validate the names and attributes. CHXMapStringToOb dupMap; BOOL bDupFound = FALSE; XMLAttribute* pAttr = NULL; const char* name = NULL; for(UINT32 i=0;i<tag->m_numAttributes;++i) { pAttr = tag->attribute(i); if (!xmlStr.IsNameValid((const BYTE*)pAttr->name, strlen(pAttr->name))) { XMLError* err = NULL; SetError(err, XMLErrorInvalidName, m_ulTagStartLine, m_ulTagStartCol, pAttr->name, strlen(pAttr->name), 0); tag->m_errs->Add(err); } if (!xmlStr.IsAttValueValid((const BYTE*)pAttr->value, strlen(pAttr->value))) { XMLError* err = NULL; SetError(err, XMLErrorInvalidCharInDoc, m_ulTagStartLine, m_ulTagStartCol, pAttr->value, strlen(pAttr->value), 0); tag->m_errs->Add(err); } void* pLookupValue = NULL; if(pAttr->name) { if(dupMap.Lookup(pAttr->name, pLookupValue)) { name = pAttr->name; bDupFound = TRUE; break; } else { dupMap.SetAt(pAttr->name, NULL); } } } if (bDupFound) { XMLError* err = NULL; SetError(err, XMLErrorDupAttribute, m_ulTagStartLine, m_ulTagStartCol, name, strlen(name), 0); tag->m_errs->Add(err); } return XMLPTag;} void XMLParser::SetEncoding(const char* pszEncoding){ if (pszEncoding) { INT32 lLen = strlen(pszEncoding); if (lLen > 0) { HX_VECTOR_DELETE(m_pEncoding); m_pEncoding = new char [lLen + 1]; if (m_pEncoding) { strcpy(m_pEncoding, pszEncoding); } } }}HX_RESULT XMLParser::GetEncoding(REF(char*) rpszEncoding){ HX_RESULT retVal = HXR_FAIL; if (m_pEncoding) { HX_VECTOR_DELETE(rpszEncoding); rpszEncoding = new char [strlen(m_pEncoding) + 1]; if (rpszEncoding) { strcpy(rpszEncoding, m_pEncoding); retVal = HXR_OK; } } return retVal;}voidXMLParser::SetError(REF(XMLError*) pErr, XMLErrorTag tag, INT32 lLine, INT32 lPos, const char* pErrorText, INT32 lErrorTextLen, const char* pFrameText){ HX_DELETE(m_pLastError); INT32 lTextLen = (lErrorTextLen > MAX_ERROR_LEN) ? MAX_ERROR_LEN: lErrorTextLen; char tmpBuf[MAX_ERROR_LEN * 2]; // overdo it a bit... // convert control characters to spaces INT32 j = 0; for(INT32 i = 0; i < lTextLen; ++i) { if(iscntrl(pErrorText[i])) { tmpBuf[j++] = ' '; } else { tmpBuf[j++] = pErrorText[i]; } } tmpBuf[j] = 0; pErr = new XMLError(tag, lLine, lPos, tmpBuf, pFrameText);}XMLTag::XMLTag(BOOL bStrictCompliance, BOOL bStoreErrors): m_bStrictCompliance(bStrictCompliance){ m_numAttributes = 0; m_name = NULL; m_type = XMLPlainTag; m_need_close = TRUE; m_errs = NULL; if (bStoreErrors) { m_errs = new CHXPtrArray(); }}XMLTag::~XMLTag(){ UINT32 i; for(i = 0; i < m_numAttributes; i++) { delete (XMLAttribute*)m_attributes[(int)i]; } HX_VECTOR_DELETE(m_name); if (m_errs) { UINT32 size = m_errs->GetSize(); for(i = 0; i < size; i++) { delete (XMLError*)(*m_errs)[(int)i]; } HX_DELETE(m_errs); }}XMLAttribute*XMLTag::new_attribute(){ m_cur_attribute = new XMLAttribute; m_attributes.SetAtGrow((int)m_numAttributes, m_cur_attribute); m_numAttributes++; return m_cur_attribute;}const char*XMLTag::get_attribute(const char* name){ for(UINT32 i = 0; i < m_numAttributes; i++) { if(((XMLAttribute*)m_attributes[(int)i])->name) { if(m_bStrictCompliance) { if(strcmp(((XMLAttribute*)m_attributes[(int)i])->name, name) == 0) { return (const char*)((XMLAttribute*)m_attributes[(int)i])->value; } } else { if(strcasecmp(((XMLAttribute*)m_attributes[(int)i])->name, name) == 0) { return (const char*)((XMLAttribute*)m_attributes[(int)i])->value; } } } } return NULL;}/* * XMLError methods */XMLError::XMLError(XMLErrorTag errorTag, INT32 lLineNumber, INT32 lLinePosition, const char* pErrorString, const char* pFrameString): m_errorTag(errorTag), m_lLineNumber(lLineNumber), m_lLinePosition(lLinePosition), m_pErrorString(0), m_pFrameString(0){ if(pErrorString) { m_pErrorString = new_string(pErrorString); } if(pFrameString) { m_pFrameString = new_string(pFrameString); }}XMLError::~XMLError(){ delete[] m_pErrorString; delete[] m_pFrameString;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -