| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/fpdf_page/pageint.h" | 7 #include "core/fpdfapi/fpdf_page/pageint.h" |
| 8 | 8 |
| 9 #include <limits.h> | 9 #include <limits.h> |
| 10 | 10 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 if (decoder == "RunLengthDecode" || decoder == "RL") { | 117 if (decoder == "RunLengthDecode" || decoder == "RL") { |
| 118 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); | 118 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); |
| 119 } | 119 } |
| 120 dest_size = 0; | 120 dest_size = 0; |
| 121 dest_buf = 0; | 121 dest_buf = 0; |
| 122 return (uint32_t)-1; | 122 return (uint32_t)-1; |
| 123 } | 123 } |
| 124 | 124 |
| 125 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, | 125 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, |
| 126 CPDF_Dictionary* pDict, | 126 CPDF_Dictionary* pDict, |
| 127 CPDF_Object* pCSObj, | 127 CPDF_Object* pCSObj) { |
| 128 FX_BOOL bDecode) { | |
| 129 if (m_Pos == m_Size) | 128 if (m_Pos == m_Size) |
| 130 return nullptr; | 129 return nullptr; |
| 131 | 130 |
| 132 if (PDFCharIsWhitespace(m_pBuf[m_Pos])) | 131 if (PDFCharIsWhitespace(m_pBuf[m_Pos])) |
| 133 m_Pos++; | 132 m_Pos++; |
| 134 | 133 |
| 135 CFX_ByteString Decoder; | 134 CFX_ByteString Decoder; |
| 136 CPDF_Dictionary* pParam = nullptr; | 135 CPDF_Dictionary* pParam = nullptr; |
| 137 CPDF_Object* pFilter = pDict->GetDirectObjectBy("Filter"); | 136 CPDF_Object* pFilter = pDict->GetDirectObjectBy("Filter"); |
| 138 if (pFilter) { | 137 if (pFilter) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 } | 191 } |
| 193 pData = FX_Alloc(uint8_t, OrigSize); | 192 pData = FX_Alloc(uint8_t, OrigSize); |
| 194 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); | 193 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); |
| 195 dwStreamSize = OrigSize; | 194 dwStreamSize = OrigSize; |
| 196 m_Pos += OrigSize; | 195 m_Pos += OrigSize; |
| 197 } else { | 196 } else { |
| 198 uint32_t dwDestSize = OrigSize; | 197 uint32_t dwDestSize = OrigSize; |
| 199 dwStreamSize = | 198 dwStreamSize = |
| 200 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, | 199 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, |
| 201 Decoder, pParam, pData, dwDestSize); | 200 Decoder, pParam, pData, dwDestSize); |
| 202 if ((int)dwStreamSize < 0) { | 201 FX_Free(pData); |
| 203 FX_Free(pData); | 202 if ((int)dwStreamSize < 0) |
| 204 return NULL; | 203 return NULL; |
| 204 |
| 205 uint32_t dwSavePos = m_Pos; |
| 206 m_Pos += dwStreamSize; |
| 207 while (1) { |
| 208 uint32_t dwPrevPos = m_Pos; |
| 209 CPDF_StreamParser::SyntaxType type = ParseNextElement(); |
| 210 if (type == CPDF_StreamParser::EndOfData) |
| 211 break; |
| 212 |
| 213 if (type != CPDF_StreamParser::Keyword) { |
| 214 dwStreamSize += m_Pos - dwPrevPos; |
| 215 continue; |
| 216 } |
| 217 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && |
| 218 GetWordBuf()[1] == 'I') { |
| 219 m_Pos = dwPrevPos; |
| 220 break; |
| 221 } |
| 222 dwStreamSize += m_Pos - dwPrevPos; |
| 205 } | 223 } |
| 206 if (bDecode) { | 224 m_Pos = dwSavePos; |
| 207 m_Pos += dwStreamSize; | 225 pData = FX_Alloc(uint8_t, dwStreamSize); |
| 208 dwStreamSize = dwDestSize; | 226 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); |
| 209 if (CPDF_Array* pArray = pFilter->AsArray()) { | 227 m_Pos += dwStreamSize; |
| 210 pArray->RemoveAt(0); | |
| 211 CPDF_Array* pParams = pDict->GetArrayBy("DecodeParms"); | |
| 212 if (pParams) | |
| 213 pParams->RemoveAt(0); | |
| 214 } else { | |
| 215 pDict->RemoveAt("Filter"); | |
| 216 pDict->RemoveAt("DecodeParms"); | |
| 217 } | |
| 218 } else { | |
| 219 FX_Free(pData); | |
| 220 uint32_t dwSavePos = m_Pos; | |
| 221 m_Pos += dwStreamSize; | |
| 222 while (1) { | |
| 223 uint32_t dwPrevPos = m_Pos; | |
| 224 CPDF_StreamParser::SyntaxType type = ParseNextElement(); | |
| 225 if (type == CPDF_StreamParser::EndOfData) { | |
| 226 break; | |
| 227 } | |
| 228 if (type != CPDF_StreamParser::Keyword) { | |
| 229 dwStreamSize += m_Pos - dwPrevPos; | |
| 230 continue; | |
| 231 } | |
| 232 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && | |
| 233 GetWordBuf()[1] == 'I') { | |
| 234 m_Pos = dwPrevPos; | |
| 235 break; | |
| 236 } | |
| 237 dwStreamSize += m_Pos - dwPrevPos; | |
| 238 } | |
| 239 m_Pos = dwSavePos; | |
| 240 pData = FX_Alloc(uint8_t, dwStreamSize); | |
| 241 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); | |
| 242 m_Pos += dwStreamSize; | |
| 243 } | |
| 244 } | 228 } |
| 245 pDict->SetAtInteger("Length", (int)dwStreamSize); | 229 pDict->SetAtInteger("Length", (int)dwStreamSize); |
| 246 return new CPDF_Stream(pData, dwStreamSize, pDict); | 230 return new CPDF_Stream(pData, dwStreamSize, pDict); |
| 247 } | 231 } |
| 248 | 232 |
| 249 #define MAX_WORD_BUFFER 256 | 233 #define MAX_WORD_BUFFER 256 |
| 250 #define MAX_STRING_LENGTH 32767 | 234 #define MAX_STRING_LENGTH 32767 |
| 251 | 235 |
| 252 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { | 236 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { |
| 253 if (m_pLastObj) { | 237 if (m_pLastObj) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 } | 308 } |
| 325 } else if (m_WordSize == 5) { | 309 } else if (m_WordSize == 5) { |
| 326 if (memcmp(m_WordBuffer, "false", 5) == 0) { | 310 if (memcmp(m_WordBuffer, "false", 5) == 0) { |
| 327 m_pLastObj = new CPDF_Boolean(FALSE); | 311 m_pLastObj = new CPDF_Boolean(FALSE); |
| 328 return Others; | 312 return Others; |
| 329 } | 313 } |
| 330 } | 314 } |
| 331 return Keyword; | 315 return Keyword; |
| 332 } | 316 } |
| 333 | 317 |
| 334 void CPDF_StreamParser::SkipPathObject() { | |
| 335 uint32_t command_startpos = m_Pos; | |
| 336 if (!PositionIsInBounds()) | |
| 337 return; | |
| 338 | |
| 339 int ch = m_pBuf[m_Pos++]; | |
| 340 while (1) { | |
| 341 while (PDFCharIsWhitespace(ch)) { | |
| 342 if (!PositionIsInBounds()) | |
| 343 return; | |
| 344 ch = m_pBuf[m_Pos++]; | |
| 345 } | |
| 346 | |
| 347 if (!PDFCharIsNumeric(ch)) { | |
| 348 m_Pos = command_startpos; | |
| 349 return; | |
| 350 } | |
| 351 | |
| 352 while (1) { | |
| 353 while (!PDFCharIsWhitespace(ch)) { | |
| 354 if (!PositionIsInBounds()) | |
| 355 return; | |
| 356 ch = m_pBuf[m_Pos++]; | |
| 357 } | |
| 358 | |
| 359 while (PDFCharIsWhitespace(ch)) { | |
| 360 if (!PositionIsInBounds()) | |
| 361 return; | |
| 362 ch = m_pBuf[m_Pos++]; | |
| 363 } | |
| 364 | |
| 365 if (PDFCharIsNumeric(ch)) | |
| 366 continue; | |
| 367 | |
| 368 uint32_t op_startpos = m_Pos - 1; | |
| 369 while (!PDFCharIsWhitespace(ch) && !PDFCharIsDelimiter(ch)) { | |
| 370 if (!PositionIsInBounds()) | |
| 371 return; | |
| 372 ch = m_pBuf[m_Pos++]; | |
| 373 } | |
| 374 | |
| 375 if (IsPathOperator(&m_pBuf[op_startpos], m_Pos - 1 - op_startpos)) { | |
| 376 command_startpos = m_Pos; | |
| 377 break; | |
| 378 } | |
| 379 m_Pos = command_startpos; | |
| 380 return; | |
| 381 } | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, | 318 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, |
| 386 FX_BOOL bInArray) { | 319 FX_BOOL bInArray) { |
| 387 FX_BOOL bIsNumber; | 320 FX_BOOL bIsNumber; |
| 388 GetNextWord(bIsNumber); | 321 GetNextWord(bIsNumber); |
| 389 if (m_WordSize == 0) { | 322 if (m_WordSize == 0) { |
| 390 return NULL; | 323 return NULL; |
| 391 } | 324 } |
| 392 if (bIsNumber) { | 325 if (bIsNumber) { |
| 393 m_WordBuffer[m_WordSize] = 0; | 326 m_WordBuffer[m_WordSize] = 0; |
| 394 return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize)); | 327 return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize)); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 m_pType3Char(nullptr), | 623 m_pType3Char(nullptr), |
| 691 m_pData(nullptr), | 624 m_pData(nullptr), |
| 692 m_Size(0), | 625 m_Size(0), |
| 693 m_CurrentOffset(0) {} | 626 m_CurrentOffset(0) {} |
| 694 | 627 |
| 695 CPDF_ContentParser::~CPDF_ContentParser() { | 628 CPDF_ContentParser::~CPDF_ContentParser() { |
| 696 if (!m_pSingleStream) | 629 if (!m_pSingleStream) |
| 697 FX_Free(m_pData); | 630 FX_Free(m_pData); |
| 698 } | 631 } |
| 699 | 632 |
| 700 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) { | 633 void CPDF_ContentParser::Start(CPDF_Page* pPage) { |
| 701 if (m_Status != Ready || !pPage || !pPage->m_pDocument || | 634 if (m_Status != Ready || !pPage || !pPage->m_pDocument || |
| 702 !pPage->m_pFormDict) { | 635 !pPage->m_pFormDict) { |
| 703 m_Status = Done; | 636 m_Status = Done; |
| 704 return; | 637 return; |
| 705 } | 638 } |
| 706 m_pObjectHolder = pPage; | 639 m_pObjectHolder = pPage; |
| 707 m_bForm = FALSE; | 640 m_bForm = FALSE; |
| 708 if (pOptions) { | |
| 709 m_Options = *pOptions; | |
| 710 } | |
| 711 m_Status = ToBeContinued; | 641 m_Status = ToBeContinued; |
| 712 m_InternalStage = STAGE_GETCONTENT; | 642 m_InternalStage = STAGE_GETCONTENT; |
| 713 m_CurrentOffset = 0; | 643 m_CurrentOffset = 0; |
| 714 | 644 |
| 715 CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectBy("Contents"); | 645 CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectBy("Contents"); |
| 716 if (!pContent) { | 646 if (!pContent) { |
| 717 m_Status = Done; | 647 m_Status = Done; |
| 718 return; | 648 return; |
| 719 } | 649 } |
| 720 if (CPDF_Stream* pStream = pContent->AsStream()) { | 650 if (CPDF_Stream* pStream = pContent->AsStream()) { |
| 721 m_nStreams = 0; | 651 m_nStreams = 0; |
| 722 m_pSingleStream.reset(new CPDF_StreamAcc); | 652 m_pSingleStream.reset(new CPDF_StreamAcc); |
| 723 m_pSingleStream->LoadAllData(pStream, FALSE); | 653 m_pSingleStream->LoadAllData(pStream, FALSE); |
| 724 } else if (CPDF_Array* pArray = pContent->AsArray()) { | 654 } else if (CPDF_Array* pArray = pContent->AsArray()) { |
| 725 m_nStreams = pArray->GetCount(); | 655 m_nStreams = pArray->GetCount(); |
| 726 if (m_nStreams) | 656 if (m_nStreams) |
| 727 m_StreamArray.resize(m_nStreams); | 657 m_StreamArray.resize(m_nStreams); |
| 728 else | 658 else |
| 729 m_Status = Done; | 659 m_Status = Done; |
| 730 } else { | 660 } else { |
| 731 m_Status = Done; | 661 m_Status = Done; |
| 732 } | 662 } |
| 733 } | 663 } |
| 734 | 664 |
| 735 void CPDF_ContentParser::Start(CPDF_Form* pForm, | 665 void CPDF_ContentParser::Start(CPDF_Form* pForm, |
| 736 CPDF_AllStates* pGraphicStates, | 666 CPDF_AllStates* pGraphicStates, |
| 737 CFX_Matrix* pParentMatrix, | 667 CFX_Matrix* pParentMatrix, |
| 738 CPDF_Type3Char* pType3Char, | 668 CPDF_Type3Char* pType3Char, |
| 739 CPDF_ParseOptions* pOptions, | |
| 740 int level) { | 669 int level) { |
| 741 m_pType3Char = pType3Char; | 670 m_pType3Char = pType3Char; |
| 742 m_pObjectHolder = pForm; | 671 m_pObjectHolder = pForm; |
| 743 m_bForm = TRUE; | 672 m_bForm = TRUE; |
| 744 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixBy("Matrix"); | 673 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixBy("Matrix"); |
| 745 if (pGraphicStates) { | 674 if (pGraphicStates) { |
| 746 form_matrix.Concat(pGraphicStates->m_CTM); | 675 form_matrix.Concat(pGraphicStates->m_CTM); |
| 747 } | 676 } |
| 748 CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayBy("BBox"); | 677 CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayBy("BBox"); |
| 749 CFX_FloatRect form_bbox; | 678 CFX_FloatRect form_bbox; |
| 750 CPDF_Path ClipPath; | 679 CPDF_Path ClipPath; |
| 751 if (pBBox) { | 680 if (pBBox) { |
| 752 form_bbox = pBBox->GetRect(); | 681 form_bbox = pBBox->GetRect(); |
| 753 ClipPath.New(); | 682 ClipPath.New(); |
| 754 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, | 683 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, |
| 755 form_bbox.top); | 684 form_bbox.top); |
| 756 ClipPath.Transform(&form_matrix); | 685 ClipPath.Transform(&form_matrix); |
| 757 if (pParentMatrix) { | 686 if (pParentMatrix) { |
| 758 ClipPath.Transform(pParentMatrix); | 687 ClipPath.Transform(pParentMatrix); |
| 759 } | 688 } |
| 760 form_bbox.Transform(&form_matrix); | 689 form_bbox.Transform(&form_matrix); |
| 761 if (pParentMatrix) { | 690 if (pParentMatrix) { |
| 762 form_bbox.Transform(pParentMatrix); | 691 form_bbox.Transform(pParentMatrix); |
| 763 } | 692 } |
| 764 } | 693 } |
| 765 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictBy("Resources"); | 694 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictBy("Resources"); |
| 766 m_pParser.reset(new CPDF_StreamContentParser( | 695 m_pParser.reset(new CPDF_StreamContentParser( |
| 767 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, | 696 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, |
| 768 pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, | 697 pParentMatrix, pForm, pResources, &form_bbox, pGraphicStates, level)); |
| 769 level)); | |
| 770 m_pParser->GetCurStates()->m_CTM = form_matrix; | 698 m_pParser->GetCurStates()->m_CTM = form_matrix; |
| 771 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; | 699 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; |
| 772 if (ClipPath.NotNull()) { | 700 if (ClipPath.NotNull()) { |
| 773 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, | 701 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, |
| 774 TRUE); | 702 TRUE); |
| 775 } | 703 } |
| 776 if (pForm->m_Transparency & PDFTRANS_GROUP) { | 704 if (pForm->m_Transparency & PDFTRANS_GROUP) { |
| 777 CPDF_GeneralStateData* pData = | 705 CPDF_GeneralStateData* pData = |
| 778 m_pParser->GetCurStates()->m_GeneralState.GetModify(); | 706 m_pParser->GetCurStates()->m_GeneralState.GetModify(); |
| 779 pData->m_BlendType = FXDIB_BLEND_NORMAL; | 707 pData->m_BlendType = FXDIB_BLEND_NORMAL; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); | 757 pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); |
| 830 m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); | 758 m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); |
| 831 m_CurrentOffset++; | 759 m_CurrentOffset++; |
| 832 } | 760 } |
| 833 } | 761 } |
| 834 if (m_InternalStage == STAGE_PARSE) { | 762 if (m_InternalStage == STAGE_PARSE) { |
| 835 if (!m_pParser) { | 763 if (!m_pParser) { |
| 836 m_pParser.reset(new CPDF_StreamContentParser( | 764 m_pParser.reset(new CPDF_StreamContentParser( |
| 837 m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, | 765 m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, |
| 838 nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, | 766 nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, |
| 839 &m_pObjectHolder->m_BBox, &m_Options, nullptr, 0)); | 767 &m_pObjectHolder->m_BBox, nullptr, 0)); |
| 840 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); | 768 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); |
| 841 } | 769 } |
| 842 if (m_CurrentOffset >= m_Size) { | 770 if (m_CurrentOffset >= m_Size) { |
| 843 m_InternalStage = STAGE_CHECKCLIP; | 771 m_InternalStage = STAGE_CHECKCLIP; |
| 844 } else { | 772 } else { |
| 845 m_CurrentOffset += | 773 m_CurrentOffset += |
| 846 m_pParser->Parse(m_pData + m_CurrentOffset, | 774 m_pParser->Parse(m_pData + m_CurrentOffset, |
| 847 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); | 775 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); |
| 848 } | 776 } |
| 849 } | 777 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 } | 813 } |
| 886 m_Status = Done; | 814 m_Status = Done; |
| 887 return; | 815 return; |
| 888 } | 816 } |
| 889 steps++; | 817 steps++; |
| 890 if (pPause && pPause->NeedToPauseNow()) { | 818 if (pPause && pPause->NeedToPauseNow()) { |
| 891 break; | 819 break; |
| 892 } | 820 } |
| 893 } | 821 } |
| 894 } | 822 } |
| OLD | NEW |