OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 "xfa/fxfa/parser/cxfa_xml_parser.h" |
| 8 |
| 9 CXFA_XMLParser::CXFA_XMLParser(CFDE_XMLNode* pRoot, IFX_Stream* pStream) |
| 10 : m_nElementStart(0), |
| 11 m_dwCheckStatus(0), |
| 12 m_dwCurrentCheckStatus(0), |
| 13 m_pRoot(pRoot), |
| 14 m_pStream(pStream), |
| 15 m_pParser(new CFDE_XMLSyntaxParser), |
| 16 m_pParent(pRoot), |
| 17 m_pChild(nullptr), |
| 18 m_NodeStack(16), |
| 19 m_syntaxParserResult(FDE_XmlSyntaxResult::None) { |
| 20 ASSERT(m_pParent && m_pStream); |
| 21 m_NodeStack.Push(m_pParent); |
| 22 m_pParser->Init(m_pStream, 32 * 1024, 1024 * 1024); |
| 23 } |
| 24 |
| 25 CXFA_XMLParser::~CXFA_XMLParser() { |
| 26 m_NodeStack.RemoveAll(); |
| 27 m_ws1.clear(); |
| 28 m_ws2.clear(); |
| 29 } |
| 30 |
| 31 void CXFA_XMLParser::Release() { |
| 32 delete this; |
| 33 } |
| 34 |
| 35 int32_t CXFA_XMLParser::DoParser(IFX_Pause* pPause) { |
| 36 if (m_syntaxParserResult == FDE_XmlSyntaxResult::Error) |
| 37 return -1; |
| 38 if (m_syntaxParserResult == FDE_XmlSyntaxResult::EndOfString) |
| 39 return 100; |
| 40 |
| 41 int32_t iCount = 0; |
| 42 while (TRUE) { |
| 43 m_syntaxParserResult = m_pParser->DoSyntaxParse(); |
| 44 switch (m_syntaxParserResult) { |
| 45 case FDE_XmlSyntaxResult::InstructionOpen: |
| 46 break; |
| 47 case FDE_XmlSyntaxResult::InstructionClose: |
| 48 if (m_pChild) { |
| 49 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { |
| 50 m_syntaxParserResult = FDE_XmlSyntaxResult::Error; |
| 51 break; |
| 52 } |
| 53 } |
| 54 m_pChild = m_pParent; |
| 55 break; |
| 56 case FDE_XmlSyntaxResult::ElementOpen: |
| 57 if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 2) { |
| 58 m_nElementStart = m_pParser->GetCurrentPos() - 1; |
| 59 } |
| 60 break; |
| 61 case FDE_XmlSyntaxResult::ElementBreak: |
| 62 break; |
| 63 case FDE_XmlSyntaxResult::ElementClose: |
| 64 if (m_pChild->GetType() != FDE_XMLNODE_Element) { |
| 65 m_syntaxParserResult = FDE_XmlSyntaxResult::Error; |
| 66 break; |
| 67 } |
| 68 m_pParser->GetTagName(m_ws1); |
| 69 static_cast<CFDE_XMLElement*>(m_pChild)->GetTagName(m_ws2); |
| 70 if (m_ws1.GetLength() > 0 && m_ws1 != m_ws2) { |
| 71 m_syntaxParserResult = FDE_XmlSyntaxResult::Error; |
| 72 break; |
| 73 } |
| 74 m_NodeStack.Pop(); |
| 75 if (m_NodeStack.GetSize() < 1) { |
| 76 m_syntaxParserResult = FDE_XmlSyntaxResult::Error; |
| 77 break; |
| 78 } else if (m_dwCurrentCheckStatus != 0 && m_NodeStack.GetSize() == 2) { |
| 79 m_nSize[m_dwCurrentCheckStatus - 1] = |
| 80 m_pParser->GetCurrentBinaryPos() - |
| 81 m_nStart[m_dwCurrentCheckStatus - 1]; |
| 82 m_dwCurrentCheckStatus = 0; |
| 83 } |
| 84 |
| 85 m_pParent = static_cast<CFDE_XMLNode*>(*m_NodeStack.GetTopElement()); |
| 86 m_pChild = m_pParent; |
| 87 iCount++; |
| 88 break; |
| 89 case FDE_XmlSyntaxResult::TargetName: |
| 90 m_pParser->GetTargetName(m_ws1); |
| 91 if (m_ws1 == FX_WSTRC(L"originalXFAVersion") || |
| 92 m_ws1 == FX_WSTRC(L"acrobat")) { |
| 93 m_pChild = new CFDE_XMLInstruction(m_ws1); |
| 94 m_pParent->InsertChildNode(m_pChild); |
| 95 } else { |
| 96 m_pChild = nullptr; |
| 97 } |
| 98 m_ws1.clear(); |
| 99 break; |
| 100 case FDE_XmlSyntaxResult::TagName: |
| 101 m_pParser->GetTagName(m_ws1); |
| 102 m_pChild = new CFDE_XMLElement(m_ws1); |
| 103 m_pParent->InsertChildNode(m_pChild); |
| 104 m_NodeStack.Push(m_pChild); |
| 105 m_pParent = m_pChild; |
| 106 |
| 107 if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 3) { |
| 108 CFX_WideString wsTag; |
| 109 static_cast<CFDE_XMLElement*>(m_pChild)->GetLocalTagName(wsTag); |
| 110 if (wsTag == FX_WSTRC(L"template")) { |
| 111 m_dwCheckStatus |= 0x01; |
| 112 m_dwCurrentCheckStatus = 0x01; |
| 113 m_nStart[0] = m_pParser->GetCurrentBinaryPos() - |
| 114 (m_pParser->GetCurrentPos() - m_nElementStart); |
| 115 } else if (wsTag == FX_WSTRC(L"datasets")) { |
| 116 m_dwCheckStatus |= 0x02; |
| 117 m_dwCurrentCheckStatus = 0x02; |
| 118 m_nStart[1] = m_pParser->GetCurrentBinaryPos() - |
| 119 (m_pParser->GetCurrentPos() - m_nElementStart); |
| 120 } |
| 121 } |
| 122 break; |
| 123 case FDE_XmlSyntaxResult::AttriName: |
| 124 m_pParser->GetAttributeName(m_ws1); |
| 125 break; |
| 126 case FDE_XmlSyntaxResult::AttriValue: |
| 127 if (m_pChild) { |
| 128 m_pParser->GetAttributeName(m_ws2); |
| 129 if (m_pChild->GetType() == FDE_XMLNODE_Element) { |
| 130 static_cast<CFDE_XMLElement*>(m_pChild)->SetString(m_ws1, m_ws2); |
| 131 } |
| 132 } |
| 133 m_ws1.clear(); |
| 134 break; |
| 135 case FDE_XmlSyntaxResult::Text: |
| 136 m_pParser->GetTextData(m_ws1); |
| 137 m_pChild = new CFDE_XMLText(m_ws1); |
| 138 m_pParent->InsertChildNode(m_pChild); |
| 139 m_pChild = m_pParent; |
| 140 break; |
| 141 case FDE_XmlSyntaxResult::CData: |
| 142 m_pParser->GetTextData(m_ws1); |
| 143 m_pChild = new CFDE_XMLCharData(m_ws1); |
| 144 m_pParent->InsertChildNode(m_pChild); |
| 145 m_pChild = m_pParent; |
| 146 break; |
| 147 case FDE_XmlSyntaxResult::TargetData: |
| 148 if (m_pChild) { |
| 149 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { |
| 150 m_syntaxParserResult = FDE_XmlSyntaxResult::Error; |
| 151 break; |
| 152 } |
| 153 if (!m_ws1.IsEmpty()) { |
| 154 static_cast<CFDE_XMLInstruction*>(m_pChild)->AppendData(m_ws1); |
| 155 } |
| 156 m_pParser->GetTargetData(m_ws1); |
| 157 static_cast<CFDE_XMLInstruction*>(m_pChild)->AppendData(m_ws1); |
| 158 } |
| 159 m_ws1.clear(); |
| 160 break; |
| 161 default: |
| 162 break; |
| 163 } |
| 164 if (m_syntaxParserResult == FDE_XmlSyntaxResult::Error || |
| 165 m_syntaxParserResult == FDE_XmlSyntaxResult::EndOfString) { |
| 166 break; |
| 167 } |
| 168 if (pPause && iCount > 500 && pPause->NeedToPauseNow()) { |
| 169 break; |
| 170 } |
| 171 } |
| 172 return (m_syntaxParserResult == FDE_XmlSyntaxResult::Error || |
| 173 m_NodeStack.GetSize() != 1) |
| 174 ? -1 |
| 175 : m_pParser->GetStatus(); |
| 176 } |
OLD | NEW |