1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxcrt/xml/cfx_saxreaderhandler.h"
8
9 #include <string>
10
11 #include "core/fxcrt/cfx_checksumcontext.h"
12
CFX_SAXReaderHandler(CFX_ChecksumContext * pContext)13 CFX_SAXReaderHandler::CFX_SAXReaderHandler(CFX_ChecksumContext* pContext)
14 : m_pContext(pContext) {
15 ASSERT(m_pContext);
16 }
17
~CFX_SAXReaderHandler()18 CFX_SAXReaderHandler::~CFX_SAXReaderHandler() {}
19
OnTagEnter(const ByteStringView & bsTagName,CFX_SAXItem::Type eType,uint32_t dwStartPos)20 CFX_SAXContext* CFX_SAXReaderHandler::OnTagEnter(
21 const ByteStringView& bsTagName,
22 CFX_SAXItem::Type eType,
23 uint32_t dwStartPos) {
24 UpdateChecksum(true);
25 if (eType != CFX_SAXItem::Type::Tag &&
26 eType != CFX_SAXItem::Type::Instruction) {
27 return nullptr;
28 }
29
30 m_SAXContext.m_eNode = eType;
31 m_SAXContext.m_TextBuf << "<";
32 if (eType == CFX_SAXItem::Type::Instruction)
33 m_SAXContext.m_TextBuf << "?";
34
35 m_SAXContext.m_TextBuf << bsTagName;
36 m_SAXContext.m_bsTagName = bsTagName;
37 return &m_SAXContext;
38 }
39
OnTagAttribute(CFX_SAXContext * pTag,const ByteStringView & bsAttri,const ByteStringView & bsValue)40 void CFX_SAXReaderHandler::OnTagAttribute(CFX_SAXContext* pTag,
41 const ByteStringView& bsAttri,
42 const ByteStringView& bsValue) {
43 if (!pTag)
44 return;
45 pTag->m_TextBuf << " " << bsAttri << "=\"" << bsValue << "\"";
46 }
47
OnTagBreak(CFX_SAXContext * pTag)48 void CFX_SAXReaderHandler::OnTagBreak(CFX_SAXContext* pTag) {
49 if (!pTag)
50 return;
51
52 pTag->m_TextBuf << ">";
53 UpdateChecksum(false);
54 }
55
OnTagData(CFX_SAXContext * pTag,CFX_SAXItem::Type eType,const ByteStringView & bsData,uint32_t dwStartPos)56 void CFX_SAXReaderHandler::OnTagData(CFX_SAXContext* pTag,
57 CFX_SAXItem::Type eType,
58 const ByteStringView& bsData,
59 uint32_t dwStartPos) {
60 if (!pTag)
61 return;
62
63 if (eType == CFX_SAXItem::Type::CharData)
64 pTag->m_TextBuf << "<![CDATA[";
65
66 pTag->m_TextBuf << bsData;
67 if (eType == CFX_SAXItem::Type::CharData)
68 pTag->m_TextBuf << "]]>";
69 }
70
OnTagClose(CFX_SAXContext * pTag,uint32_t dwEndPos)71 void CFX_SAXReaderHandler::OnTagClose(CFX_SAXContext* pTag, uint32_t dwEndPos) {
72 if (!pTag)
73 return;
74
75 if (pTag->m_eNode == CFX_SAXItem::Type::Instruction)
76 pTag->m_TextBuf << "?>";
77 else if (pTag->m_eNode == CFX_SAXItem::Type::Tag)
78 pTag->m_TextBuf << "></" << pTag->m_bsTagName.AsStringView() << ">";
79
80 UpdateChecksum(false);
81 }
82
OnTagEnd(CFX_SAXContext * pTag,const ByteStringView & bsTagName,uint32_t dwEndPos)83 void CFX_SAXReaderHandler::OnTagEnd(CFX_SAXContext* pTag,
84 const ByteStringView& bsTagName,
85 uint32_t dwEndPos) {
86 if (!pTag)
87 return;
88
89 pTag->m_TextBuf << "</" << bsTagName << ">";
90 UpdateChecksum(false);
91 }
92
OnTargetData(CFX_SAXContext * pTag,CFX_SAXItem::Type eType,const ByteStringView & bsData,uint32_t dwStartPos)93 void CFX_SAXReaderHandler::OnTargetData(CFX_SAXContext* pTag,
94 CFX_SAXItem::Type eType,
95 const ByteStringView& bsData,
96 uint32_t dwStartPos) {
97 if (!pTag && eType != CFX_SAXItem::Type::Comment)
98 return;
99
100 if (eType == CFX_SAXItem::Type::Comment) {
101 m_SAXContext.m_TextBuf << "<!--" << bsData << "-->";
102 UpdateChecksum(false);
103 } else {
104 pTag->m_TextBuf << " " << bsData;
105 }
106 }
107
UpdateChecksum(bool bCheckSpace)108 void CFX_SAXReaderHandler::UpdateChecksum(bool bCheckSpace) {
109 int32_t iLength = m_SAXContext.m_TextBuf.tellp();
110 if (iLength < 1)
111 return;
112
113 std::string sBuffer = m_SAXContext.m_TextBuf.str();
114 const uint8_t* pBuffer = reinterpret_cast<const uint8_t*>(sBuffer.c_str());
115 bool bUpdata = true;
116 if (bCheckSpace) {
117 bUpdata = false;
118 for (int32_t i = 0; i < iLength; i++) {
119 bUpdata = (pBuffer[i] > 0x20);
120 if (bUpdata)
121 break;
122 }
123 }
124 if (bUpdata)
125 m_pContext->Update(ByteStringView(pBuffer, iLength));
126
127 m_SAXContext.m_TextBuf.str("");
128 }
129