Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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/parser/cpdf_syntax_parser.h" | 7 #include "core/fpdfapi/parser/cpdf_syntax_parser.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "core/fpdfapi/cpdf_modulemgr.h" | 11 #include "core/fpdfapi/cpdf_modulemgr.h" |
| 12 #include "core/fpdfapi/parser/cpdf_array.h" | 12 #include "core/fpdfapi/parser/cpdf_array.h" |
| 13 #include "core/fpdfapi/parser/cpdf_boolean.h" | 13 #include "core/fpdfapi/parser/cpdf_boolean.h" |
| 14 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" | 14 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" |
| 15 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 15 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| 16 #include "core/fpdfapi/parser/cpdf_name.h" | 16 #include "core/fpdfapi/parser/cpdf_name.h" |
| 17 #include "core/fpdfapi/parser/cpdf_null.h" | 17 #include "core/fpdfapi/parser/cpdf_null.h" |
| 18 #include "core/fpdfapi/parser/cpdf_number.h" | 18 #include "core/fpdfapi/parser/cpdf_number.h" |
| 19 #include "core/fpdfapi/parser/cpdf_reference.h" | 19 #include "core/fpdfapi/parser/cpdf_reference.h" |
| 20 #include "core/fpdfapi/parser/cpdf_stream.h" | 20 #include "core/fpdfapi/parser/cpdf_stream.h" |
| 21 #include "core/fpdfapi/parser/cpdf_string.h" | 21 #include "core/fpdfapi/parser/cpdf_string.h" |
| 22 #include "core/fpdfapi/parser/fpdf_parser_decode.h" | 22 #include "core/fpdfapi/parser/fpdf_parser_decode.h" |
| 23 #include "core/fpdfapi/parser/fpdf_parser_utility.h" | 23 #include "core/fpdfapi/parser/fpdf_parser_utility.h" |
| 24 #include "core/fxcrt/fx_ext.h" | 24 #include "core/fxcrt/fx_ext.h" |
| 25 #include "third_party/base/numerics/safe_math.h" | 25 #include "third_party/base/numerics/safe_math.h" |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 struct SearchTagRecord { | 29 struct SearchTagRecord { |
|
Lei Zhang
2016/11/03 08:11:27
No longer needed?
npm
2016/11/03 18:58:56
Done.
| |
| 30 CFX_ByteStringC m_bsTag; | 30 CFX_ByteStringC m_bsTag; |
| 31 FX_STRSIZE m_Offset; | 31 FX_STRSIZE m_Offset; |
| 32 }; | 32 }; |
| 33 | 33 |
| 34 enum class ReadStatus { Normal, Backslash, Octal, FinishOctal, CarriageReturn }; | |
| 35 | |
| 34 } // namespace | 36 } // namespace |
| 35 | 37 |
| 36 // static | 38 // static |
| 37 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; | 39 int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; |
| 38 | 40 |
| 39 CPDF_SyntaxParser::CPDF_SyntaxParser() | 41 CPDF_SyntaxParser::CPDF_SyntaxParser() |
| 40 : CPDF_SyntaxParser(CFX_WeakPtr<CFX_ByteStringPool>()) {} | 42 : CPDF_SyntaxParser(CFX_WeakPtr<CFX_ByteStringPool>()) {} |
| 41 | 43 |
| 42 CPDF_SyntaxParser::CPDF_SyntaxParser( | 44 CPDF_SyntaxParser::CPDF_SyntaxParser( |
| 43 const CFX_WeakPtr<CFX_ByteStringPool>& pPool) | 45 const CFX_WeakPtr<CFX_ByteStringPool>& pPool) |
| 44 : m_MetadataObjnum(0), | 46 : m_MetadataObjnum(0), |
| 45 m_pFileAccess(nullptr), | 47 m_pFileAccess(nullptr), |
| 46 m_pFileBuf(nullptr), | 48 m_pFileBuf(nullptr), |
| 47 m_BufSize(CPDF_ModuleMgr::kFileBufSize), | 49 m_BufSize(CPDF_ModuleMgr::kFileBufSize), |
| 48 m_pPool(pPool) {} | 50 m_pPool(pPool) {} |
| 49 | 51 |
| 50 CPDF_SyntaxParser::~CPDF_SyntaxParser() { | 52 CPDF_SyntaxParser::~CPDF_SyntaxParser() { |
| 51 FX_Free(m_pFileBuf); | 53 FX_Free(m_pFileBuf); |
| 52 } | 54 } |
| 53 | 55 |
| 54 bool CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { | 56 bool CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { |
| 55 CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); | 57 CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); |
| 56 m_Pos = pos; | 58 m_Pos = pos; |
| 57 return GetNextChar(ch); | 59 return GetNextChar(ch); |
| 58 } | 60 } |
| 59 | 61 |
| 62 bool CPDF_SyntaxParser::ReadChar(FX_FILESIZE read_pos, uint32_t read_size) { | |
| 63 if (static_cast<FX_FILESIZE>(read_pos + read_size) > m_FileLen) { | |
| 64 if (m_FileLen < static_cast<FX_FILESIZE>(read_size)) { | |
| 65 read_pos = 0; | |
| 66 read_size = static_cast<uint32_t>(m_FileLen); | |
| 67 } else { | |
| 68 read_pos = m_FileLen - read_size; | |
| 69 } | |
| 70 } | |
| 71 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) | |
| 72 return false; | |
| 73 | |
| 74 m_BufOffset = read_pos; | |
| 75 return true; | |
| 76 } | |
| 77 | |
| 60 bool CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { | 78 bool CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { |
| 61 FX_FILESIZE pos = m_Pos + m_HeaderOffset; | 79 FX_FILESIZE pos = m_Pos + m_HeaderOffset; |
| 62 if (pos >= m_FileLen) | 80 if (pos >= m_FileLen) |
| 63 return false; | 81 return false; |
| 64 | 82 |
| 65 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { | 83 if (m_BufOffset >= pos || |
|
Lei Zhang
2016/11/03 08:11:27
This same check is in 3 places.
npm
2016/11/03 18:58:56
Replaced with inline method. Only found it in 2 pl
| |
| 84 static_cast<FX_FILESIZE>(m_BufOffset + m_BufSize) <= pos) { | |
| 66 FX_FILESIZE read_pos = pos; | 85 FX_FILESIZE read_pos = pos; |
| 67 uint32_t read_size = m_BufSize; | 86 uint32_t read_size = m_BufSize; |
| 68 if ((FX_FILESIZE)read_size > m_FileLen) | 87 if (static_cast<FX_FILESIZE>(read_size) > m_FileLen) |
|
Lei Zhang
2016/11/03 08:11:27
std::min()
npm
2016/11/03 18:58:56
Done.
| |
| 69 read_size = (uint32_t)m_FileLen; | 88 read_size = static_cast<uint32_t>(m_FileLen); |
| 70 | 89 if (!ReadChar(read_pos, read_size)) |
| 71 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { | |
| 72 if (m_FileLen < (FX_FILESIZE)read_size) { | |
| 73 read_pos = 0; | |
| 74 read_size = (uint32_t)m_FileLen; | |
| 75 } else { | |
| 76 read_pos = m_FileLen - read_size; | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) | |
| 81 return false; | 90 return false; |
| 82 | |
| 83 m_BufOffset = read_pos; | |
| 84 } | 91 } |
| 85 ch = m_pFileBuf[pos - m_BufOffset]; | 92 ch = m_pFileBuf[pos - m_BufOffset]; |
| 86 m_Pos++; | 93 m_Pos++; |
| 87 return true; | 94 return true; |
| 88 } | 95 } |
| 89 | 96 |
| 90 bool CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) { | 97 bool CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) { |
| 91 pos += m_HeaderOffset; | 98 pos += m_HeaderOffset; |
| 92 if (pos >= m_FileLen) | 99 if (pos >= m_FileLen) |
| 93 return false; | 100 return false; |
| 94 | 101 |
| 95 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { | 102 if (m_BufOffset >= pos || |
| 103 static_cast<FX_FILESIZE>(m_BufOffset + m_BufSize) <= pos) { | |
|
Lei Zhang
2016/11/03 08:11:27
For later, since it's pre-existing - I'm paranoid
npm
2016/11/03 18:58:56
Agreed. Might need to add more checks to operation
| |
| 96 FX_FILESIZE read_pos; | 104 FX_FILESIZE read_pos; |
| 97 if (pos < (FX_FILESIZE)m_BufSize) | 105 if (pos < static_cast<FX_FILESIZE>(m_BufSize)) |
| 98 read_pos = 0; | 106 read_pos = 0; |
| 99 else | 107 else |
| 100 read_pos = pos - m_BufSize + 1; | 108 read_pos = pos - m_BufSize + 1; |
| 101 | |
| 102 uint32_t read_size = m_BufSize; | 109 uint32_t read_size = m_BufSize; |
| 103 if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { | 110 if (!ReadChar(read_pos, read_size)) |
| 104 if (m_FileLen < (FX_FILESIZE)read_size) { | |
| 105 read_pos = 0; | |
| 106 read_size = (uint32_t)m_FileLen; | |
| 107 } else { | |
| 108 read_pos = m_FileLen - read_size; | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) | |
| 113 return false; | 111 return false; |
| 114 | |
| 115 m_BufOffset = read_pos; | |
| 116 } | 112 } |
| 117 ch = m_pFileBuf[pos - m_BufOffset]; | 113 ch = m_pFileBuf[pos - m_BufOffset]; |
| 118 return true; | 114 return true; |
| 119 } | 115 } |
| 120 | 116 |
| 121 bool CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, uint32_t size) { | 117 bool CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, uint32_t size) { |
| 122 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) | 118 if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) |
| 123 return false; | 119 return false; |
| 124 m_Pos += size; | 120 m_Pos += size; |
| 125 return true; | 121 return true; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 } | 204 } |
| 209 } | 205 } |
| 210 | 206 |
| 211 CFX_ByteString CPDF_SyntaxParser::ReadString() { | 207 CFX_ByteString CPDF_SyntaxParser::ReadString() { |
| 212 uint8_t ch; | 208 uint8_t ch; |
| 213 if (!GetNextChar(ch)) | 209 if (!GetNextChar(ch)) |
| 214 return CFX_ByteString(); | 210 return CFX_ByteString(); |
| 215 | 211 |
| 216 CFX_ByteTextBuf buf; | 212 CFX_ByteTextBuf buf; |
| 217 int32_t parlevel = 0; | 213 int32_t parlevel = 0; |
| 218 int32_t status = 0; | 214 ReadStatus status = ReadStatus::Normal; |
| 219 int32_t iEscCode = 0; | 215 int32_t iEscCode = 0; |
| 220 while (1) { | 216 while (1) { |
| 221 switch (status) { | 217 switch (status) { |
| 222 case 0: | 218 case ReadStatus::Normal: |
| 223 if (ch == ')') { | 219 if (ch == ')') { |
| 224 if (parlevel == 0) { | 220 if (parlevel == 0) |
| 225 return buf.MakeString(); | 221 return buf.MakeString(); |
| 226 } | |
| 227 parlevel--; | 222 parlevel--; |
| 228 buf.AppendChar(')'); | |
| 229 } else if (ch == '(') { | 223 } else if (ch == '(') { |
| 230 parlevel++; | 224 parlevel++; |
| 231 buf.AppendChar('('); | 225 } |
| 232 } else if (ch == '\\') { | 226 if (ch == '\\') |
| 233 status = 1; | 227 status = ReadStatus::Backslash; |
| 234 } else { | 228 else |
| 235 buf.AppendChar(ch); | 229 buf.AppendChar(ch); |
| 236 } | |
| 237 break; | 230 break; |
| 238 case 1: | 231 case ReadStatus::Backslash: |
| 239 if (ch >= '0' && ch <= '7') { | 232 if (ch >= '0' && ch <= '7') { |
| 240 iEscCode = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 233 iEscCode = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
| 241 status = 2; | 234 status = ReadStatus::Octal; |
| 242 break; | 235 break; |
| 243 } | 236 } |
| 244 | 237 |
| 245 if (ch == 'n') { | 238 if (ch == 'n') { |
| 246 buf.AppendChar('\n'); | 239 buf.AppendChar('\n'); |
| 247 } else if (ch == 'r') { | 240 } else if (ch == 'r') { |
| 248 buf.AppendChar('\r'); | 241 buf.AppendChar('\r'); |
| 249 } else if (ch == 't') { | 242 } else if (ch == 't') { |
| 250 buf.AppendChar('\t'); | 243 buf.AppendChar('\t'); |
| 251 } else if (ch == 'b') { | 244 } else if (ch == 'b') { |
| 252 buf.AppendChar('\b'); | 245 buf.AppendChar('\b'); |
| 253 } else if (ch == 'f') { | 246 } else if (ch == 'f') { |
| 254 buf.AppendChar('\f'); | 247 buf.AppendChar('\f'); |
| 255 } else if (ch == '\r') { | 248 } else if (ch == '\r') { |
| 256 status = 4; | 249 status = ReadStatus::CarriageReturn; |
| 257 break; | 250 break; |
| 258 } else if (ch != '\n') { | 251 } else if (ch != '\n') { |
| 259 buf.AppendChar(ch); | 252 buf.AppendChar(ch); |
| 260 } | 253 } |
| 261 status = 0; | 254 status = ReadStatus::Normal; |
| 262 break; | 255 break; |
| 263 case 2: | 256 case ReadStatus::Octal: |
| 264 if (ch >= '0' && ch <= '7') { | 257 if (ch >= '0' && ch <= '7') { |
| 265 iEscCode = | 258 iEscCode = |
| 266 iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 259 iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
| 267 status = 3; | 260 status = ReadStatus::FinishOctal; |
| 268 } else { | 261 } else { |
| 269 buf.AppendChar(iEscCode); | 262 buf.AppendChar(iEscCode); |
| 270 status = 0; | 263 status = ReadStatus::Normal; |
| 271 continue; | 264 continue; |
| 272 } | 265 } |
| 273 break; | 266 break; |
| 274 case 3: | 267 case ReadStatus::FinishOctal: |
| 268 status = ReadStatus::Normal; | |
| 275 if (ch >= '0' && ch <= '7') { | 269 if (ch >= '0' && ch <= '7') { |
| 276 iEscCode = | 270 iEscCode = |
| 277 iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); | 271 iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); |
| 278 buf.AppendChar(iEscCode); | 272 buf.AppendChar(iEscCode); |
| 279 status = 0; | |
| 280 } else { | 273 } else { |
| 281 buf.AppendChar(iEscCode); | 274 buf.AppendChar(iEscCode); |
| 282 status = 0; | |
| 283 continue; | 275 continue; |
| 284 } | 276 } |
| 285 break; | 277 break; |
| 286 case 4: | 278 case ReadStatus::CarriageReturn: |
| 287 status = 0; | 279 status = ReadStatus::Normal; |
| 288 if (ch != '\n') | 280 if (ch != '\n') |
| 289 continue; | 281 continue; |
| 290 break; | 282 break; |
| 291 } | 283 } |
| 292 | 284 |
| 293 if (!GetNextChar(ch)) | 285 if (!GetNextChar(ch)) |
| 294 break; | 286 break; |
| 295 } | 287 } |
| 296 | 288 |
| 297 GetNextChar(ch); | 289 GetNextChar(ch); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 len = pLenObj->GetInteger(); | 633 len = pLenObj->GetInteger(); |
| 642 | 634 |
| 643 // Locate the start of stream. | 635 // Locate the start of stream. |
| 644 ToNextLine(); | 636 ToNextLine(); |
| 645 FX_FILESIZE streamStartPos = m_Pos; | 637 FX_FILESIZE streamStartPos = m_Pos; |
| 646 | 638 |
| 647 const CFX_ByteStringC kEndStreamStr("endstream"); | 639 const CFX_ByteStringC kEndStreamStr("endstream"); |
| 648 const CFX_ByteStringC kEndObjStr("endobj"); | 640 const CFX_ByteStringC kEndObjStr("endobj"); |
| 649 | 641 |
| 650 CPDF_CryptoHandler* pCryptoHandler = | 642 CPDF_CryptoHandler* pCryptoHandler = |
| 651 objnum == (uint32_t)m_MetadataObjnum ? nullptr : m_pCryptoHandler.get(); | 643 objnum == static_cast<uint32_t>(m_MetadataObjnum) |
|
Lei Zhang
2016/11/03 08:11:27
Can we just make |m_MetadataObjnum| unsigned?
npm
2016/11/03 18:58:56
Done.
| |
| 644 ? nullptr | |
| 645 : m_pCryptoHandler.get(); | |
| 652 if (!pCryptoHandler) { | 646 if (!pCryptoHandler) { |
| 653 bool bSearchForKeyword = true; | 647 bool bSearchForKeyword = true; |
| 654 if (len >= 0) { | 648 if (len >= 0) { |
| 655 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; | 649 pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; |
| 656 pos += len; | 650 pos += len; |
| 657 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) | 651 if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) |
| 658 m_Pos = pos.ValueOrDie(); | 652 m_Pos = pos.ValueOrDie(); |
| 659 | 653 |
| 660 m_Pos += ReadEOLMarkers(m_Pos); | 654 m_Pos += ReadEOLMarkers(m_Pos); |
| 661 FXSYS_memset(m_WordBuffer, 0, kEndStreamStr.GetLength() + 1); | 655 FXSYS_memset(m_WordBuffer, 0, kEndStreamStr.GetLength() + 1); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 FX_Free(m_pFileBuf); | 781 FX_Free(m_pFileBuf); |
| 788 | 782 |
| 789 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); | 783 m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); |
| 790 m_HeaderOffset = HeaderOffset; | 784 m_HeaderOffset = HeaderOffset; |
| 791 m_FileLen = pFileAccess->GetSize(); | 785 m_FileLen = pFileAccess->GetSize(); |
| 792 m_Pos = 0; | 786 m_Pos = 0; |
| 793 m_pFileAccess = pFileAccess; | 787 m_pFileAccess = pFileAccess; |
| 794 m_BufOffset = 0; | 788 m_BufOffset = 0; |
| 795 pFileAccess->ReadBlock( | 789 pFileAccess->ReadBlock( |
| 796 m_pFileBuf, 0, | 790 m_pFileBuf, 0, |
| 797 (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize)); | 791 static_cast<size_t>(static_cast<FX_FILESIZE>(m_BufSize) > m_FileLen |
|
Lei Zhang
2016/11/03 08:11:27
Something like:
std::min(m_BufSize, static_cast<u
npm
2016/11/03 18:58:56
Done.
| |
| 792 ? m_FileLen | |
| 793 : m_BufSize)); | |
| 798 } | 794 } |
| 799 | 795 |
| 800 uint32_t CPDF_SyntaxParser::GetDirectNum() { | 796 uint32_t CPDF_SyntaxParser::GetDirectNum() { |
| 801 bool bIsNumber; | 797 bool bIsNumber; |
| 802 GetNextWordInternal(&bIsNumber); | 798 GetNextWordInternal(&bIsNumber); |
| 803 if (!bIsNumber) | 799 if (!bIsNumber) |
| 804 return 0; | 800 return 0; |
| 805 | 801 |
| 806 m_WordBuffer[m_WordSize] = 0; | 802 m_WordBuffer[m_WordSize] = 0; |
| 807 return FXSYS_atoui(reinterpret_cast<const FX_CHAR*>(m_WordBuffer)); | 803 return FXSYS_atoui(reinterpret_cast<const FX_CHAR*>(m_WordBuffer)); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 898 pos--; | 894 pos--; |
| 899 } | 895 } |
| 900 | 896 |
| 901 if (pos < 0) | 897 if (pos < 0) |
| 902 return false; | 898 return false; |
| 903 } | 899 } |
| 904 | 900 |
| 905 return false; | 901 return false; |
| 906 } | 902 } |
| 907 | 903 |
| 908 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, | |
| 909 bool bWholeWord, | |
| 910 FX_FILESIZE limit) { | |
| 911 int32_t ntags = 1; | |
| 912 for (int i = 0; i < tags.GetLength(); ++i) { | |
| 913 if (tags[i] == 0) | |
| 914 ++ntags; | |
| 915 } | |
| 916 | |
| 917 // Ensure that the input byte string happens to be nul-terminated. This | |
| 918 // need not be the case, but the loop below uses this guarantee to put | |
| 919 // the last pattern into the vector. | |
| 920 ASSERT(tags[tags.GetLength()] == 0); | |
| 921 std::vector<SearchTagRecord> patterns(ntags); | |
| 922 uint32_t start = 0; | |
| 923 uint32_t itag = 0; | |
| 924 uint32_t max_len = 0; | |
| 925 for (int i = 0; i <= tags.GetLength(); ++i) { | |
| 926 if (tags[i] == 0) { | |
| 927 uint32_t len = i - start; | |
| 928 max_len = std::max(len, max_len); | |
| 929 patterns[itag].m_bsTag = tags.Mid(start, len); | |
| 930 patterns[itag].m_Offset = 0; | |
| 931 start = i + 1; | |
| 932 ++itag; | |
| 933 } | |
| 934 } | |
| 935 | |
| 936 const FX_FILESIZE pos_limit = m_Pos + limit; | |
| 937 for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) { | |
| 938 uint8_t byte; | |
| 939 if (!GetCharAt(pos, byte)) | |
| 940 break; | |
| 941 | |
| 942 for (int i = 0; i < ntags; ++i) { | |
| 943 SearchTagRecord& pat = patterns[i]; | |
| 944 if (pat.m_bsTag[pat.m_Offset] != byte) { | |
| 945 pat.m_Offset = (pat.m_bsTag[0] == byte) ? 1 : 0; | |
| 946 continue; | |
| 947 } | |
| 948 | |
| 949 ++pat.m_Offset; | |
| 950 if (pat.m_Offset != pat.m_bsTag.GetLength()) | |
| 951 continue; | |
| 952 | |
| 953 if (!bWholeWord || IsWholeWord(pos - pat.m_bsTag.GetLength(), limit, | |
| 954 pat.m_bsTag, false)) { | |
| 955 return i; | |
| 956 } | |
| 957 | |
| 958 pat.m_Offset = (pat.m_bsTag[0] == byte) ? 1 : 0; | |
| 959 } | |
| 960 } | |
| 961 return -1; | |
| 962 } | |
| 963 | |
| 964 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, | 904 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, |
| 965 FX_FILESIZE limit) { | 905 FX_FILESIZE limit) { |
| 966 int32_t taglen = tag.GetLength(); | 906 int32_t taglen = tag.GetLength(); |
| 967 int32_t match = 0; | 907 int32_t match = 0; |
| 968 limit += m_Pos; | 908 limit += m_Pos; |
| 969 FX_FILESIZE startpos = m_Pos; | 909 FX_FILESIZE startpos = m_Pos; |
| 970 | 910 |
| 971 while (1) { | 911 while (1) { |
| 972 uint8_t ch; | 912 uint8_t ch; |
| 973 if (!GetNextChar(ch)) | 913 if (!GetNextChar(ch)) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 988 } | 928 } |
| 989 | 929 |
| 990 void CPDF_SyntaxParser::SetEncrypt( | 930 void CPDF_SyntaxParser::SetEncrypt( |
| 991 std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler) { | 931 std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler) { |
| 992 m_pCryptoHandler = std::move(pCryptoHandler); | 932 m_pCryptoHandler = std::move(pCryptoHandler); |
| 993 } | 933 } |
| 994 | 934 |
| 995 CFX_ByteString CPDF_SyntaxParser::MaybeIntern(const CFX_ByteString& str) { | 935 CFX_ByteString CPDF_SyntaxParser::MaybeIntern(const CFX_ByteString& str) { |
| 996 return m_pPool ? m_pPool->Intern(str) : str; | 936 return m_pPool ? m_pPool->Intern(str) : str; |
| 997 } | 937 } |
| OLD | NEW |