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