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 13 CFX_SAXReaderHandler::CFX_SAXReaderHandler(CFX_ChecksumContext* pContext) 14 : m_pContext(pContext) { 15 ASSERT(m_pContext); 16 } 17 18 CFX_SAXReaderHandler::~CFX_SAXReaderHandler() {} 19 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 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 48 void CFX_SAXReaderHandler::OnTagBreak(CFX_SAXContext* pTag) { 49 if (!pTag) 50 return; 51 52 pTag->m_TextBuf << ">"; 53 UpdateChecksum(false); 54 } 55 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 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 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 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 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