Chromium Code Reviews| Index: xfa/fxfa/app/xfa_ffdoc.cpp | 
| diff --git a/xfa/fxfa/app/xfa_ffdoc.cpp b/xfa/fxfa/app/xfa_ffdoc.cpp | 
| index f93881564d54232042fc9f435fa900629a0ffa23..ce7628e43e0376753c2a1d8908f54318bb9d0ea5 100644 | 
| --- a/xfa/fxfa/app/xfa_ffdoc.cpp | 
| +++ b/xfa/fxfa/app/xfa_ffdoc.cpp | 
| @@ -14,7 +14,6 @@ | 
| #include "core/fxcrt/include/fx_ext.h" | 
| #include "core/fxcrt/include/fx_memory.h" | 
| #include "xfa/fde/xml/fde_xml_imp.h" | 
| -#include "xfa/fgas/crt/fgas_algorithm.h" | 
| #include "xfa/fwl/core/fwl_noteimp.h" | 
| #include "xfa/fxfa/app/xfa_ffnotify.h" | 
| #include "xfa/fxfa/include/xfa_checksum.h" | 
| @@ -28,6 +27,127 @@ | 
| #include "xfa/fxfa/parser/xfa_parser_imp.h" | 
| #include "xfa/fxfa/parser/xfa_parser_imp.h" | 
| +namespace { | 
| + | 
| +struct FX_BASE64DATA { | 
| + uint32_t data1 : 2; | 
| + uint32_t data2 : 6; | 
| + uint32_t data3 : 4; | 
| + uint32_t data4 : 4; | 
| + uint32_t data5 : 6; | 
| + uint32_t data6 : 2; | 
| + uint32_t data7 : 8; | 
| +}; | 
| + | 
| +const uint8_t kStartValuesRemoved = 43; | 
| +const uint8_t kDecoderMapSize = 80; | 
| +const uint8_t g_FXBase64DecoderMap[kDecoderMapSize] = { | 
| + 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, | 
| + 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, | 
| + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, | 
| + 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, | 
| + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, | 
| + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, | 
| + 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, | 
| +}; | 
| + | 
| +uint8_t base64DecoderValue(uint8_t val) { | 
| 
 
Tom Sepez
2016/05/19 21:23:42
The numbers look right, alternatively you might wa
 
dsinclair
2016/05/20 01:06:31
I think it's going to be strange either way. I thi
 
 | 
| + if (val < kStartValuesRemoved || val >= kStartValuesRemoved + kDecoderMapSize) | 
| + return 0xFF; | 
| + return g_FXBase64DecoderMap[val - kStartValuesRemoved]; | 
| +} | 
| + | 
| +void Base64DecodePiece(const FX_CHAR src[4], | 
| + int32_t iChars, | 
| + FX_BASE64DATA& dst, | 
| + int32_t& iBytes) { | 
| + ASSERT(iChars > 0 && iChars < 5); | 
| + iBytes = 1; | 
| + dst.data2 = base64DecoderValue(static_cast<uint8_t>(src[0])); | 
| + if (iChars > 1) { | 
| + uint8_t b = base64DecoderValue(static_cast<uint8_t>(src[1])); | 
| + dst.data1 = b >> 4; | 
| + dst.data4 = b; | 
| + if (iChars > 2) { | 
| + iBytes = 2; | 
| + b = base64DecoderValue(static_cast<uint8_t>(src[2])); | 
| + dst.data3 = b >> 2; | 
| + dst.data6 = b; | 
| + if (iChars > 3) { | 
| + iBytes = 3; | 
| + dst.data5 = base64DecoderValue(static_cast<uint8_t>(src[3])); | 
| + } else { | 
| + dst.data5 = 0; | 
| + } | 
| + } else { | 
| + dst.data3 = 0; | 
| + } | 
| + } else { | 
| + dst.data1 = 0; | 
| + } | 
| +} | 
| + | 
| +int32_t Base64DecodeW(const FX_WCHAR* pSrc, int32_t iSrcLen, uint8_t* pDst) { | 
| + ASSERT(pSrc); | 
| + if (iSrcLen < 1) { | 
| + return 0; | 
| + } | 
| + while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') { | 
| + iSrcLen--; | 
| + } | 
| + if (iSrcLen < 1) { | 
| + return 0; | 
| + } | 
| + if (!pDst) { | 
| + int32_t iDstLen = iSrcLen / 4 * 3; | 
| + iSrcLen %= 4; | 
| + if (iSrcLen == 1) { | 
| + iDstLen += 1; | 
| + } else if (iSrcLen == 2) { | 
| + iDstLen += 1; | 
| + } else if (iSrcLen == 3) { | 
| + iDstLen += 2; | 
| + } | 
| + return iDstLen; | 
| + } | 
| + FX_CHAR srcData[4]; | 
| + FX_BASE64DATA dstData; | 
| + int32_t iChars = 4, iBytes; | 
| + uint8_t* pDstEnd = pDst; | 
| + while (iSrcLen > 0) { | 
| + if (iSrcLen > 3) { | 
| + srcData[0] = (FX_CHAR)*pSrc++; | 
| + srcData[1] = (FX_CHAR)*pSrc++; | 
| + srcData[2] = (FX_CHAR)*pSrc++; | 
| + srcData[3] = (FX_CHAR)*pSrc++; | 
| + iSrcLen -= 4; | 
| + } else { | 
| + *((uint32_t*)&dstData) = 0; | 
| + *((uint32_t*)srcData) = 0; | 
| + srcData[0] = (FX_CHAR)*pSrc++; | 
| + if (iSrcLen > 1) { | 
| + srcData[1] = (FX_CHAR)*pSrc++; | 
| + } | 
| + if (iSrcLen > 2) { | 
| + srcData[2] = (FX_CHAR)*pSrc++; | 
| + } | 
| + iChars = iSrcLen; | 
| + iSrcLen = 0; | 
| + } | 
| + Base64DecodePiece(srcData, iChars, dstData, iBytes); | 
| + *pDstEnd++ = ((uint8_t*)&dstData)[0]; | 
| + if (iBytes > 1) { | 
| + *pDstEnd++ = ((uint8_t*)&dstData)[1]; | 
| + } | 
| + if (iBytes > 2) { | 
| + *pDstEnd++ = ((uint8_t*)&dstData)[2]; | 
| + } | 
| + } | 
| + return pDstEnd - pDst; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocProvider* pDocProvider) | 
| : m_pDocProvider(pDocProvider), | 
| m_pDocument(nullptr), | 
| @@ -53,7 +173,7 @@ int32_t CXFA_FFDoc::StartLoad() { | 
| FX_BOOL XFA_GetPDFContentsFromPDFXML(CFDE_XMLNode* pPDFElement, | 
| uint8_t*& pByteBuffer, | 
| int32_t& iBufferSize) { | 
| - CFDE_XMLElement* pDocumentElement = NULL; | 
| + CFDE_XMLElement* pDocumentElement = nullptr; | 
| for (CFDE_XMLNode* pXMLNode = | 
| pPDFElement->GetNodeItem(CFDE_XMLNode::FirstChild); | 
| pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) { | 
| @@ -70,7 +190,7 @@ FX_BOOL XFA_GetPDFContentsFromPDFXML(CFDE_XMLNode* pPDFElement, | 
| if (!pDocumentElement) { | 
| return FALSE; | 
| } | 
| - CFDE_XMLElement* pChunkElement = NULL; | 
| + CFDE_XMLElement* pChunkElement = nullptr; | 
| for (CFDE_XMLNode* pXMLNode = | 
| pDocumentElement->GetNodeItem(CFDE_XMLNode::FirstChild); | 
| pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) { | 
| @@ -90,10 +210,10 @@ FX_BOOL XFA_GetPDFContentsFromPDFXML(CFDE_XMLNode* pPDFElement, | 
| CFX_WideString wsPDFContent; | 
| pChunkElement->GetTextData(wsPDFContent); | 
| iBufferSize = | 
| - FX_Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), NULL); | 
| + Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), nullptr); | 
| pByteBuffer = FX_Alloc(uint8_t, iBufferSize + 1); | 
| pByteBuffer[iBufferSize] = '0'; // FIXME: I bet this is wrong. | 
| - FX_Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), pByteBuffer); | 
| + Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), pByteBuffer); | 
| return TRUE; | 
| } | 
| void XFA_XPDPacket_MergeRootNode(CXFA_Node* pOriginRoot, CXFA_Node* pNewRoot) { | 
| @@ -109,7 +229,7 @@ void XFA_XPDPacket_MergeRootNode(CXFA_Node* pOriginRoot, CXFA_Node* pNewRoot) { | 
| pNewRoot->RemoveChild(pChildNode); | 
| pOriginRoot->InsertChild(pChildNode); | 
| pChildNode = pNextSibling; | 
| - pNextSibling = NULL; | 
| + pNextSibling = nullptr; | 
| } | 
| } | 
| } | 
| @@ -125,8 +245,8 @@ int32_t CXFA_FFDoc::DoLoad(IFX_Pause* pPause) { | 
| return XFA_PARSESTATUS_SyntaxErr; | 
| } | 
| int32_t iBufferSize = 0; | 
| - uint8_t* pByteBuffer = NULL; | 
| - IFX_FileRead* pXFAReader = NULL; | 
| + uint8_t* pByteBuffer = nullptr; | 
| + IFX_FileRead* pXFAReader = nullptr; | 
| if (XFA_GetPDFContentsFromPDFXML(pPDFXML, pByteBuffer, iBufferSize)) { | 
| pXFAReader = FX_CreateMemoryStream(pByteBuffer, iBufferSize, TRUE); | 
| } else { | 
| @@ -149,9 +269,9 @@ int32_t CXFA_FFDoc::DoLoad(IFX_Pause* pPause) { | 
| if (!pParser) { | 
| return XFA_PARSESTATUS_SyntaxErr; | 
| } | 
| - CXFA_Node* pRootNode = NULL; | 
| + CXFA_Node* pRootNode = nullptr; | 
| if (pParser->StartParse(m_pStream) == XFA_PARSESTATUS_Ready && | 
| - pParser->DoParse(NULL) == XFA_PARSESTATUS_Done) { | 
| + pParser->DoParse(nullptr) == XFA_PARSESTATUS_Done) { | 
| pRootNode = pParser->GetRootNode(); | 
| } | 
| if (pRootNode && m_pDocument->GetRoot()) { | 
| @@ -161,7 +281,7 @@ int32_t CXFA_FFDoc::DoLoad(IFX_Pause* pPause) { | 
| iStatus = XFA_PARSESTATUS_StatusErr; | 
| } | 
| pParser->Release(); | 
| - pParser = NULL; | 
| + pParser = nullptr; | 
| } | 
| return iStatus; | 
| } | 
| @@ -217,21 +337,21 @@ FX_BOOL CXFA_FFDoc::OpenDoc(IFX_FileRead* pStream, FX_BOOL bTakeOverFile) { | 
| return TRUE; | 
| } | 
| FX_BOOL CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc) { | 
| - if (pPDFDoc == NULL) { | 
| + if (!pPDFDoc) | 
| return FALSE; | 
| - } | 
| + | 
| CPDF_Dictionary* pRoot = pPDFDoc->GetRoot(); | 
| - if (pRoot == NULL) { | 
| + if (!pRoot) | 
| return FALSE; | 
| - } | 
| + | 
| CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); | 
| - if (pAcroForm == NULL) { | 
| + if (!pAcroForm) | 
| return FALSE; | 
| - } | 
| + | 
| CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectBy("XFA"); | 
| - if (pElementXFA == NULL) { | 
| + if (!pElementXFA) | 
| return FALSE; | 
| - } | 
| + | 
| CFX_ArrayTemplate<CPDF_Stream*> xfaStreams; | 
| if (pElementXFA->IsArray()) { | 
| CPDF_Array* pXFAArray = (CPDF_Array*)pElementXFA; | 
| @@ -249,7 +369,7 @@ FX_BOOL CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc) { | 
| m_pPDFDoc = pPDFDoc; | 
| if (m_pStream) { | 
| m_pStream->Release(); | 
| - m_pStream = NULL; | 
| + m_pStream = nullptr; | 
| } | 
| m_pStream = pFileRead; | 
| m_bOwnStream = TRUE; |