Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fxfa / src / app / xfa_checksum.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_common.h"\r
9 #include "xfa_checksum.h"\r
10 CXFA_SAXReaderHandler::CXFA_SAXReaderHandler(CXFA_ChecksumContext *pContext)\r
11     : m_pContext(pContext)\r
12 {\r
13     FXSYS_assert(m_pContext);\r
14 }\r
15 CXFA_SAXReaderHandler::~CXFA_SAXReaderHandler()\r
16 {\r
17 }\r
18 FX_LPVOID CXFA_SAXReaderHandler::OnTagEnter(FX_BSTR bsTagName, FX_SAXNODE eType, FX_DWORD dwStartPos)\r
19 {\r
20     UpdateChecksum(TRUE);\r
21     if (eType != FX_SAXNODE_Tag && eType != FX_SAXNODE_Instruction) {\r
22         return NULL;\r
23     }\r
24     m_SAXContext.m_eNode = eType;\r
25     CFX_ByteTextBuf &textBuf = m_SAXContext.m_TextBuf;\r
26     textBuf << FX_BSTRC("<");\r
27     if (eType == FX_SAXNODE_Instruction) {\r
28         textBuf << FX_BSTRC("?");\r
29     }\r
30     textBuf << bsTagName;\r
31     m_SAXContext.m_bsTagName = bsTagName;\r
32     return &m_SAXContext;\r
33 }\r
34 void CXFA_SAXReaderHandler::OnTagAttribute(FX_LPVOID pTag, FX_BSTR bsAttri, FX_BSTR bsValue)\r
35 {\r
36     if (pTag == NULL) {\r
37         return;\r
38     }\r
39     CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;\r
40     textBuf << FX_BSTRC(" ");\r
41     textBuf << bsAttri;\r
42     textBuf << FX_BSTRC("=\"");\r
43     textBuf << bsValue;\r
44     textBuf << FX_BSTRC("\"");\r
45 }\r
46 void CXFA_SAXReaderHandler::OnTagBreak(FX_LPVOID pTag)\r
47 {\r
48     if (pTag == NULL) {\r
49         return;\r
50     }\r
51     CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;\r
52     textBuf << FX_BSTRC(">");\r
53     UpdateChecksum(FALSE);\r
54 }\r
55 void CXFA_SAXReaderHandler::OnTagData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos)\r
56 {\r
57     if (pTag == NULL) {\r
58         return;\r
59     }\r
60     CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;\r
61     if (eType == FX_SAXNODE_CharData) {\r
62         textBuf << FX_BSTRC("<![CDATA[");\r
63     }\r
64     textBuf << bsData;\r
65     if (eType == FX_SAXNODE_CharData) {\r
66         textBuf << FX_BSTRC("]]>");\r
67     }\r
68 }\r
69 void CXFA_SAXReaderHandler::OnTagClose(FX_LPVOID pTag, FX_DWORD dwEndPos)\r
70 {\r
71     if (pTag == NULL) {\r
72         return;\r
73     }\r
74     CXFA_SAXContext *pSAXContext = (CXFA_SAXContext*)pTag;\r
75     CFX_ByteTextBuf &textBuf = pSAXContext->m_TextBuf;\r
76     if (pSAXContext->m_eNode == FX_SAXNODE_Instruction) {\r
77         textBuf << FX_BSTRC("?>");\r
78     } else if (pSAXContext->m_eNode == FX_SAXNODE_Tag) {\r
79         textBuf << FX_BSTRC("></");\r
80         textBuf << pSAXContext->m_bsTagName;\r
81         textBuf << FX_BSTRC(">");\r
82     }\r
83     UpdateChecksum(FALSE);\r
84 }\r
85 void CXFA_SAXReaderHandler::OnTagEnd(FX_LPVOID pTag, FX_BSTR bsTagName, FX_DWORD dwEndPos)\r
86 {\r
87     if (pTag == NULL) {\r
88         return;\r
89     }\r
90     CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;\r
91     textBuf << FX_BSTRC("</");\r
92     textBuf << bsTagName;\r
93     textBuf << FX_BSTRC(">");\r
94     UpdateChecksum(FALSE);\r
95 }\r
96 void CXFA_SAXReaderHandler::OnTargetData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos)\r
97 {\r
98     if (pTag == NULL && eType != FX_SAXNODE_Comment) {\r
99         return;\r
100     }\r
101     if (eType == FX_SAXNODE_Comment) {\r
102         CFX_ByteTextBuf &textBuf = m_SAXContext.m_TextBuf;\r
103         textBuf << FX_BSTRC("<!--");\r
104         textBuf << bsData;\r
105         textBuf << FX_BSTRC("-->");\r
106         UpdateChecksum(FALSE);\r
107     } else {\r
108         CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;\r
109         textBuf << FX_BSTRC(" ");\r
110         textBuf << bsData;\r
111     }\r
112 }\r
113 void CXFA_SAXReaderHandler::UpdateChecksum(FX_BOOL bCheckSpace)\r
114 {\r
115     int32_t iLength = m_SAXContext.m_TextBuf.GetLength();\r
116     if (iLength < 1) {\r
117         return;\r
118     }\r
119     FX_LPBYTE pBuffer = m_SAXContext.m_TextBuf.GetBuffer();\r
120     FX_BOOL bUpdata = TRUE;\r
121     if (bCheckSpace) {\r
122         bUpdata = FALSE;\r
123         for (int32_t i = 0; i < iLength; i++) {\r
124             bUpdata = (pBuffer[i] > 0x20);\r
125             if (bUpdata) {\r
126                 break;\r
127             }\r
128         }\r
129     }\r
130     if (bUpdata) {\r
131         m_pContext->Update(CFX_ByteStringC(pBuffer, iLength));\r
132     }\r
133     m_SAXContext.m_TextBuf.Clear();\r
134 }\r
135 IXFA_ChecksumContext* XFA_Checksum_Create()\r
136 {\r
137     return FX_NEW CXFA_ChecksumContext;\r
138 }\r
139 CXFA_ChecksumContext::CXFA_ChecksumContext()\r
140     : m_pSAXReader(NULL)\r
141     , m_pByteContext(NULL)\r
142 {\r
143 }\r
144 CXFA_ChecksumContext::~CXFA_ChecksumContext()\r
145 {\r
146     FinishChecksum();\r
147 }\r
148 FX_BOOL CXFA_ChecksumContext::StartChecksum()\r
149 {\r
150     FinishChecksum();\r
151     m_pByteContext = FX_Alloc(uint8_t, 128);\r
152     FXSYS_assert(m_pByteContext != NULL);\r
153     CRYPT_SHA1Start(m_pByteContext);\r
154     m_bsChecksum.Empty();\r
155     m_pSAXReader = FX_SAXReader_Create();\r
156     return m_pSAXReader != NULL;\r
157 }\r
158 FX_BOOL CXFA_ChecksumContext::UpdateChecksum(IFX_FileRead *pSrcFile, FX_FILESIZE offset, size_t size)\r
159 {\r
160     if (m_pSAXReader == NULL)   {\r
161         return FALSE;\r
162     }\r
163     if (pSrcFile == NULL) {\r
164         return FALSE;\r
165     }\r
166     if (size < 1) {\r
167         size = pSrcFile->GetSize();\r
168     }\r
169     CXFA_SAXReaderHandler handler(this);\r
170     m_pSAXReader->SetHandler(&handler);\r
171     if (m_pSAXReader->StartParse(pSrcFile, (FX_DWORD)offset, (FX_DWORD)size, FX_SAXPARSEMODE_NotSkipSpace | FX_SAXPARSEMODE_NotConvert_amp | FX_SAXPARSEMODE_NotConvert_lt | FX_SAXPARSEMODE_NotConvert_gt | FX_SAXPARSEMODE_NotConvert_sharp) < 0) {\r
172         return FALSE;\r
173     }\r
174     return m_pSAXReader->ContinueParse(NULL) > 99;\r
175 }\r
176 void CXFA_ChecksumContext::FinishChecksum()\r
177 {\r
178     if (m_pSAXReader != NULL) {\r
179         m_pSAXReader->Release();\r
180         m_pSAXReader = NULL;\r
181     }\r
182     if (m_pByteContext) {\r
183         uint8_t digest[20];\r
184         FXSYS_memset(digest, 0, 20);\r
185         CRYPT_SHA1Finish(m_pByteContext, digest);\r
186         int32_t nLen = FX_Base64EncodeA(digest, 20, NULL);\r
187         FX_LPSTR pBuffer = m_bsChecksum.GetBuffer(nLen);\r
188         FX_Base64EncodeA(digest, 20, pBuffer);\r
189         m_bsChecksum.ReleaseBuffer(nLen);\r
190         FX_Free(m_pByteContext);\r
191         m_pByteContext = NULL;\r
192     }\r
193 }\r
194 void CXFA_ChecksumContext::GetChecksum(CFX_ByteString &bsChecksum)\r
195 {\r
196     bsChecksum = m_bsChecksum;\r
197 }\r
198 void CXFA_ChecksumContext::Update(FX_BSTR bsText)\r
199 {\r
200     if (m_pByteContext != NULL) {\r
201         CRYPT_SHA1Update(m_pByteContext, bsText.GetPtr(), bsText.GetLength());\r
202     }\r
203 }\r