• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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