diff options
-rw-r--r-- | core/fxcrt/xml/cfx_saxreader.cpp | 416 | ||||
-rw-r--r-- | core/fxcrt/xml/cfx_saxreader.h | 20 | ||||
-rw-r--r-- | core/fxcrt/xml/cfx_saxreader_unittest.cpp | 18 |
3 files changed, 233 insertions, 221 deletions
diff --git a/core/fxcrt/xml/cfx_saxreader.cpp b/core/fxcrt/xml/cfx_saxreader.cpp index a7810c9884..13efdccdda 100644 --- a/core/fxcrt/xml/cfx_saxreader.cpp +++ b/core/fxcrt/xml/cfx_saxreader.cpp @@ -107,36 +107,25 @@ CFX_SAXReader::CFX_SAXReader() m_pHandler(nullptr), m_iState(-1), m_dwItemID(0), - m_iDataSize(256), - m_iNameSize(256), - m_dwParseMode(0), - m_pCommentContext(nullptr) { - m_pszData = FX_Alloc(uint8_t, m_iDataSize); - m_pszName = FX_Alloc(uint8_t, m_iNameSize); + m_dwParseMode(0) { + m_Data.reserve(256); + m_Name.reserve(256); } + CFX_SAXReader::~CFX_SAXReader() { Reset(); - if (m_pszData) { - FX_Free(m_pszData); - m_pszData = nullptr; - } - if (m_pszName) { - FX_Free(m_pszName); - m_pszName = nullptr; - } } void CFX_SAXReader::Reset() { m_File.Reset(); + m_iState = -1; m_Stack = std::stack<std::unique_ptr<CFX_SAXItem>>(); m_dwItemID = 0; m_SkipStack = std::stack<char>(); m_SkipChar = 0; - m_iDataLength = 0; - m_iEntityStart = -1; - m_iNameLength = 0; - m_iDataPos = 0; m_pCommentContext.reset(); + ClearData(); + ClearName(); } void CFX_SAXReader::Push() { @@ -156,38 +145,39 @@ CFX_SAXItem* CFX_SAXReader::GetCurrentItem() const { return m_Stack.empty() ? nullptr : m_Stack.top().get(); } -void CFX_SAXReader::AppendData(uint8_t ch) { - ReallocDataBuffer(); - m_pszData[m_iDataPos++] = ch; +void CFX_SAXReader::ClearData() { + m_Data.clear(); + m_iEntityStart = -1; } -void CFX_SAXReader::AppendName(uint8_t ch) { - ReallocNameBuffer(); - m_pszName[m_iDataPos++] = ch; +void CFX_SAXReader::ClearName() { + m_Name.clear(); } -void CFX_SAXReader::ReallocDataBuffer() { - if (m_iDataPos < m_iDataSize) { - return; - } - if (m_iDataSize <= 1024 * 1024) { - m_iDataSize *= 2; - } else { - m_iDataSize += 1024 * 1024; - } - m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize); +void CFX_SAXReader::AppendToData(uint8_t ch) { + m_Data.push_back(ch); } -void CFX_SAXReader::ReallocNameBuffer() { - if (m_iDataPos < m_iNameSize) { - return; - } - if (m_iNameSize <= 1024 * 1024) { - m_iNameSize *= 2; - } else { - m_iNameSize += 1024 * 1024; - } - m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize); +void CFX_SAXReader::AppendToName(uint8_t ch) { + m_Name.push_back(ch); +} + +void CFX_SAXReader::BackUpAndReplaceDataAt(int32_t index, uint8_t ch) { + ASSERT(index > -1); + m_Data.erase(m_Data.begin() + index, m_Data.end()); + AppendToData(ch); +} + +int32_t CFX_SAXReader::CurrentDataIndex() const { + return pdfium::CollectionSize<int32_t>(m_Data) - 1; +} + +bool CFX_SAXReader::IsEntityStart(uint8_t ch) const { + return m_iEntityStart == -1 && ch == '&'; +} + +bool CFX_SAXReader::IsEntityEnd(uint8_t ch) const { + return m_iEntityStart != -1 && ch == ';'; } bool CFX_SAXReader::SkipSpace(uint8_t ch) { @@ -199,7 +189,6 @@ int32_t CFX_SAXReader::StartParse( uint32_t dwStart, uint32_t dwLen, uint32_t dwParseMode) { - m_iState = -1; Reset(); if (!m_File.StartFile(pFile, dwStart, dwLen)) return -1; @@ -293,100 +282,96 @@ void CFX_SAXReader::ParseInternal() { } void CFX_SAXReader::ParseChar(uint8_t ch) { - ReallocDataBuffer(); - m_pszData[m_iDataPos] = ch; - if (m_iEntityStart > -1 && ch == ';') { - int32_t iSaveEntityStart = m_iEntityStart; - CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1, - m_iDataPos - m_iEntityStart - 1); - int32_t iLen = csEntity.GetLength(); - if (iLen > 0) { - if (csEntity[0] == '#') { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_sharp) == 0) { - ch = 0; - uint8_t w; - if (iLen > 1 && csEntity[1] == 'x') { - for (int32_t i = 2; i < iLen; i++) { - w = csEntity[i]; - if (w >= '0' && w <= '9') { - ch = (ch << 4) + w - '0'; - } else if (w >= 'A' && w <= 'F') { - ch = (ch << 4) + w - 55; - } else if (w >= 'a' && w <= 'f') { - ch = (ch << 4) + w - 87; - } else { - break; - } - } - } else { - for (int32_t i = 1; i < iLen; i++) { - w = csEntity[i]; - if (w < '0' || w > '9') { - break; - } - ch = ch * 10 + w - '0'; - } - } - if (ch != 0) { - m_pszData[m_iEntityStart++] = ch; - } + AppendToData(ch); + if (IsEntityStart(ch)) { + m_iEntityStart = CurrentDataIndex(); + return; + } + if (!IsEntityEnd(ch)) + return; + + // No matter what, we're no longer in an entity. + ASSERT(m_iEntityStart > -1); + int32_t iSaveStart = m_iEntityStart; + m_iEntityStart = -1; + + // NOTE: Relies on negative lengths being treated as empty strings. + CFX_ByteString csEntity(m_Data.data() + iSaveStart + 1, + CurrentDataIndex() - iSaveStart - 1); + int32_t iLen = csEntity.GetLength(); + if (iLen == 0) + return; + + if (csEntity[0] == '#') { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_sharp) == 0) { + ch = 0; + uint8_t w; + if (iLen > 1 && csEntity[1] == 'x') { + for (int32_t i = 2; i < iLen; i++) { + w = csEntity[i]; + if (w >= '0' && w <= '9') + ch = (ch << 4) + w - '0'; + else if (w >= 'A' && w <= 'F') + ch = (ch << 4) + w - 55; + else if (w >= 'a' && w <= 'f') + ch = (ch << 4) + w - 87; + else + break; } } else { - if (csEntity.Compare("amp") == 0) { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_amp) == 0) { - m_pszData[m_iEntityStart++] = '&'; - } - } else if (csEntity.Compare("lt") == 0) { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_lt) == 0) { - m_pszData[m_iEntityStart++] = '<'; - } - } else if (csEntity.Compare("gt") == 0) { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_gt) == 0) { - m_pszData[m_iEntityStart++] = '>'; - } - } else if (csEntity.Compare("apos") == 0) { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_apos) == 0) { - m_pszData[m_iEntityStart++] = '\''; - } - } else if (csEntity.Compare("quot") == 0) { - if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_quot) == 0) { - m_pszData[m_iEntityStart++] = '\"'; - } + for (int32_t i = 1; i < iLen; i++) { + w = csEntity[i]; + if (w < '0' || w > '9') + break; + ch = ch * 10 + w - '0'; } } + if (ch != 0) + BackUpAndReplaceDataAt(iSaveStart, ch); } - if (iSaveEntityStart != m_iEntityStart) { - m_iDataPos = m_iEntityStart; - m_iEntityStart = -1; - } else { - m_iDataPos++; - m_iEntityStart = -1; - } - } else { - if (m_iEntityStart < 0 && ch == '&') { - m_iEntityStart = m_iDataPos; - } - m_iDataPos++; + return; + } + if (csEntity == "amp") { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_amp) == 0) + BackUpAndReplaceDataAt(iSaveStart, '&'); + return; + } + if (csEntity == "lt") { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_lt) == 0) + BackUpAndReplaceDataAt(iSaveStart, '<'); + return; + } + if (csEntity == "gt") { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_gt) == 0) + BackUpAndReplaceDataAt(iSaveStart, '>'); + return; + } + if (csEntity == "apos") { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_apos) == 0) + BackUpAndReplaceDataAt(iSaveStart, '\''); + return; + } + if (csEntity == "quot") { + if ((m_dwParseMode & CFX_SaxParseMode_NotConvert_quot) == 0) + BackUpAndReplaceDataAt(iSaveStart, '\"'); + return; } } void CFX_SAXReader::ParseText() { if (m_CurByte == '<') { - if (m_iDataPos > 0) { - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyData(); - } + if (!m_Data.empty()) { + NotifyData(); + ClearData(); } Push(); m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; m_eMode = CFX_SaxMode::NodeStart; return; } - if (m_iDataPos < 1 && SkipSpace(m_CurByte)) { + if (m_Data.empty() && SkipSpace(m_CurByte)) return; - } + ParseChar(m_CurByte); } @@ -413,7 +398,7 @@ void CFX_SAXReader::ParseNodeStart() { m_dwDataOffset = m_File.m_dwBufIndex; GetCurrentItem()->m_eNode = CFX_SAXItem::Type::Tag; m_eMode = CFX_SaxMode::TagName; - AppendData(m_CurByte); + AppendToData(m_CurByte); } } @@ -443,58 +428,55 @@ void CFX_SAXReader::ParseComment() { void CFX_SAXReader::ParseCommentContent() { if (m_CurByte == '-') { m_pCommentContext->m_iTailCount++; - } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) { - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyTargetData(); - } + return; + } + if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) { + NotifyTargetData(); + ClearData(); Pop(); m_eMode = CFX_SaxMode::Text; - } else { - while (m_pCommentContext->m_iTailCount > 0) { - AppendData('-'); - m_pCommentContext->m_iTailCount--; - } - AppendData(m_CurByte); + return; } + while (m_pCommentContext->m_iTailCount > 0) { + AppendToData('-'); + m_pCommentContext->m_iTailCount--; + } + AppendToData(m_CurByte); } + void CFX_SAXReader::ParseDeclNode() { SkipNode(); } + void CFX_SAXReader::ParseTagName() { if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') { - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyEnter(); - } + NotifyEnter(); + ClearData(); if (m_CurByte < 0x21) { + ClearName(); m_eMode = CFX_SaxMode::TagAttributeName; } else if (m_CurByte == '/' || m_CurByte == '?') { m_ePrevMode = m_eMode; m_eMode = CFX_SaxMode::TagMaybeClose; } else { - if (m_pHandler) { - NotifyBreak(); - } + NotifyBreak(); m_eMode = CFX_SaxMode::Text; } } else { - AppendData(m_CurByte); + AppendToData(m_CurByte); } } + void CFX_SAXReader::ParseTagAttributeName() { if (m_CurByte < 0x21 || m_CurByte == '=') { - if (m_iDataPos < 1 && m_CurByte < 0x21) { + if (m_Name.empty() && m_CurByte < 0x21) return; - } - m_iNameLength = m_iDataPos; - m_iDataPos = 0; + m_SkipChar = 0; m_eMode = m_CurByte == '=' ? CFX_SaxMode::TagAttributeValue : CFX_SaxMode::TagAttributeEqual; + ClearData(); return; } if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') { @@ -502,17 +484,14 @@ void CFX_SAXReader::ParseTagAttributeName() { m_ePrevMode = m_eMode; m_eMode = CFX_SaxMode::TagMaybeClose; } else { - if (m_pHandler) { - NotifyBreak(); - } + NotifyBreak(); m_eMode = CFX_SaxMode::Text; } return; } - if (m_iDataPos < 1) { + if (m_Name.empty()) m_dwDataOffset = m_File.m_dwBufIndex; - } - AppendName(m_CurByte); + AppendToName(m_CurByte); } void CFX_SAXReader::ParseTagAttributeEqual() { @@ -522,8 +501,7 @@ void CFX_SAXReader::ParseTagAttributeEqual() { return; } if (GetCurrentItem()->m_eNode == CFX_SAXItem::Type::Instruction) { - m_iDataPos = m_iNameLength; - AppendName(0x20); + AppendToName(0x20); m_eMode = CFX_SaxMode::TargetData; ParseTargetData(); } @@ -532,13 +510,9 @@ void CFX_SAXReader::ParseTagAttributeEqual() { void CFX_SAXReader::ParseTagAttributeValue() { if (m_SkipChar) { if (m_SkipChar == m_CurByte) { - { - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyAttribute(); - } - } + NotifyAttribute(); + ClearData(); + ClearName(); m_SkipChar = 0; m_eMode = CFX_SaxMode::TagAttributeName; return; @@ -549,36 +523,33 @@ void CFX_SAXReader::ParseTagAttributeValue() { if (m_CurByte < 0x21) { return; } - if (m_iDataPos < 1) { - if (m_CurByte == '\'' || m_CurByte == '\"') { + if (m_Data.empty()) { + if (m_CurByte == '\'' || m_CurByte == '\"') m_SkipChar = m_CurByte; - } } } void CFX_SAXReader::ParseMaybeClose() { if (m_CurByte == '>') { if (GetCurrentItem()->m_eNode == CFX_SAXItem::Type::Instruction) { - m_iNameLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyTargetData(); - } + NotifyTargetData(); + ClearData(); + ClearName(); } ParseTagClose(); m_eMode = CFX_SaxMode::Text; } else if (m_ePrevMode == CFX_SaxMode::TagName) { - AppendData('/'); + AppendToData('/'); m_eMode = CFX_SaxMode::TagName; m_ePrevMode = CFX_SaxMode::Text; ParseTagName(); } else if (m_ePrevMode == CFX_SaxMode::TagAttributeName) { - AppendName('/'); + AppendToName('/'); m_eMode = CFX_SaxMode::TagAttributeName; m_ePrevMode = CFX_SaxMode::Text; ParseTagAttributeName(); } else if (m_ePrevMode == CFX_SaxMode::TargetData) { - AppendName('?'); + AppendToName('?'); m_eMode = CFX_SaxMode::TargetData; m_ePrevMode = CFX_SaxMode::Text; ParseTargetData(); @@ -586,9 +557,7 @@ void CFX_SAXReader::ParseMaybeClose() { } void CFX_SAXReader::ParseTagClose() { m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; - if (m_pHandler) { - NotifyClose(); - } + NotifyClose(); Pop(); } void CFX_SAXReader::ParseTagEnd() { @@ -598,11 +567,8 @@ void CFX_SAXReader::ParseTagEnd() { if (m_CurByte == '>') { Pop(); m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex; - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_pHandler) { - NotifyEnd(); - } + NotifyEnd(); + ClearData(); Pop(); m_eMode = CFX_SaxMode::Text; } else { @@ -614,7 +580,7 @@ void CFX_SAXReader::ParseTargetData() { m_ePrevMode = m_eMode; m_eMode = CFX_SaxMode::TagMaybeClose; } else { - AppendName(m_CurByte); + AppendToName(m_CurByte); } } void CFX_SAXReader::SkipNode() { @@ -653,24 +619,18 @@ void CFX_SAXReader::SkipNode() { m_SkipStack.pop(); m_SkipChar = !m_SkipStack.empty() ? m_SkipStack.top() : 0; if (m_SkipStack.empty() && m_CurByte == '>') { - m_iDataLength = m_iDataPos; - m_iDataPos = 0; - if (m_iDataLength >= 9 && - memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 && - memcmp(m_pszData + m_iDataLength - 2, "]]", - 2 * sizeof(uint8_t)) == 0) { + if (m_Data.size() >= 9 && memcmp(m_Data.data(), "[CDATA[", 7) == 0 && + memcmp(m_Data.data() + m_Data.size() - 2, "]]", 2) == 0) { Pop(); - m_iDataLength -= 9; - m_dwDataOffset += 7; - memmove(m_pszData, m_pszData + 7, m_iDataLength * sizeof(uint8_t)); + m_Data.erase(m_Data.begin(), m_Data.begin() + 7); + m_Data.erase(m_Data.end() - 2, m_Data.end()); m_bCharData = true; - if (m_pHandler) { - NotifyData(); - } + NotifyData(); m_bCharData = false; } else { Pop(); } + ClearData(); m_eMode = CFX_SaxMode::Text; } } @@ -681,6 +641,9 @@ void CFX_SAXReader::SkipNode() { } void CFX_SAXReader::NotifyData() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); if (!pItem) return; @@ -689,37 +652,59 @@ void CFX_SAXReader::NotifyData() { m_pHandler->OnTagData( pItem->m_pNode, m_bCharData ? CFX_SAXItem::Type::CharData : CFX_SAXItem::Type::Text, - CFX_ByteStringC(m_pszData, m_iDataLength), - m_File.m_dwCur + m_dwDataOffset); + CFX_ByteStringC(m_Data), m_File.m_dwCur + m_dwDataOffset); } void CFX_SAXReader::NotifyEnter() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); + if (!pItem) + return; + if (pItem->m_eNode == CFX_SAXItem::Type::Tag || pItem->m_eNode == CFX_SAXItem::Type::Instruction) { - pItem->m_pNode = m_pHandler->OnTagEnter( - CFX_ByteStringC(m_pszData, m_iDataLength), pItem->m_eNode, m_dwNodePos); + pItem->m_pNode = m_pHandler->OnTagEnter(CFX_ByteStringC(m_Data), + pItem->m_eNode, m_dwNodePos); } } void CFX_SAXReader::NotifyAttribute() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); + if (!pItem) + return; + if (pItem->m_eNode == CFX_SAXItem::Type::Tag || pItem->m_eNode == CFX_SAXItem::Type::Instruction) { - m_pHandler->OnTagAttribute(pItem->m_pNode, - CFX_ByteStringC(m_pszName, m_iNameLength), - CFX_ByteStringC(m_pszData, m_iDataLength)); + m_pHandler->OnTagAttribute(pItem->m_pNode, CFX_ByteStringC(m_Name), + CFX_ByteStringC(m_Data)); } } void CFX_SAXReader::NotifyBreak() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); + if (!pItem) + return; + if (pItem->m_eNode == CFX_SAXItem::Type::Tag) m_pHandler->OnTagBreak(pItem->m_pNode); } void CFX_SAXReader::NotifyClose() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); + if (!pItem) + return; + if (pItem->m_eNode == CFX_SAXItem::Type::Tag || pItem->m_eNode == CFX_SAXItem::Type::Instruction) { m_pHandler->OnTagClose(pItem->m_pNode, m_dwNodePos); @@ -727,31 +712,36 @@ void CFX_SAXReader::NotifyClose() { } void CFX_SAXReader::NotifyEnd() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); - if (!pItem || pItem->m_eNode != CFX_SAXItem::Type::Tag) + if (!pItem) return; - m_pHandler->OnTagEnd(pItem->m_pNode, - CFX_ByteStringC(m_pszData, m_iDataLength), m_dwNodePos); + if (pItem->m_eNode == CFX_SAXItem::Type::Tag) + m_pHandler->OnTagEnd(pItem->m_pNode, CFX_ByteStringC(m_Data), m_dwNodePos); } void CFX_SAXReader::NotifyTargetData() { + if (!m_pHandler) + return; + CFX_SAXItem* pItem = GetCurrentItem(); + if (!pItem) + return; + if (pItem->m_eNode == CFX_SAXItem::Type::Instruction) { m_pHandler->OnTargetData(pItem->m_pNode, pItem->m_eNode, - CFX_ByteStringC(m_pszName, m_iNameLength), - m_dwNodePos); + CFX_ByteStringC(m_Name), m_dwNodePos); } else if (pItem->m_eNode == CFX_SAXItem::Type::Comment) { m_pHandler->OnTargetData(pItem->m_pNode, pItem->m_eNode, - CFX_ByteStringC(m_pszData, m_iDataLength), - m_dwNodePos); + CFX_ByteStringC(m_Data), m_dwNodePos); } } void CFX_SAXReader::SkipCurrentNode() { CFX_SAXItem* pItem = GetCurrentItem(); - if (!pItem) - return; - - pItem->m_bSkip = true; + if (pItem) + pItem->m_bSkip = true; } diff --git a/core/fxcrt/xml/cfx_saxreader.h b/core/fxcrt/xml/cfx_saxreader.h index 45f0d07084..47ef79c50f 100644 --- a/core/fxcrt/xml/cfx_saxreader.h +++ b/core/fxcrt/xml/cfx_saxreader.h @@ -9,6 +9,7 @@ #include <memory> #include <stack> +#include <vector> #include "core/fxcrt/fx_basic.h" @@ -124,6 +125,14 @@ class CFX_SAXReader { void ParseTagEnd(); void ParseTargetData(); void Reset(); + void ClearData(); + void ClearName(); + void AppendToData(uint8_t ch); + void AppendToName(uint8_t ch); + void BackUpAndReplaceDataAt(int32_t index, uint8_t ch); + bool IsEntityStart(uint8_t ch) const; + bool IsEntityEnd(uint8_t ch) const; + int32_t CurrentDataIndex() const; void Push(); void Pop(); CFX_SAXItem* GetCurrentItem() const; @@ -153,14 +162,9 @@ class CFX_SAXReader { std::stack<char> m_SkipStack; uint8_t m_SkipChar; uint32_t m_dwNodePos; - uint8_t* m_pszData; - int32_t m_iDataSize; - int32_t m_iDataLength; - int32_t m_iEntityStart; - int32_t m_iDataPos; - uint8_t* m_pszName; - int32_t m_iNameSize; - int32_t m_iNameLength; + std::vector<uint8_t> m_Data; + int32_t m_iEntityStart; // Index into m_Data. + std::vector<uint8_t> m_Name; uint32_t m_dwParseMode; std::unique_ptr<CFX_SAXCommentContext> m_pCommentContext; }; diff --git a/core/fxcrt/xml/cfx_saxreader_unittest.cpp b/core/fxcrt/xml/cfx_saxreader_unittest.cpp index f79b82c3cc..7865d0b77c 100644 --- a/core/fxcrt/xml/cfx_saxreader_unittest.cpp +++ b/core/fxcrt/xml/cfx_saxreader_unittest.cpp @@ -130,3 +130,21 @@ TEST_F(CFX_SAXReaderTest, TextWithinTag) { ASSERT_TRUE(StartParse(data)); EXPECT_EQ(100, ContinueParse()); } + +TEST_F(CFX_SAXReaderTest, bug_711459) { + char data[] = + "&a<tag " + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ">x;"; + ASSERT_TRUE(StartParse(data)); + EXPECT_EQ(100, ContinueParse()); +} |