| // Copyright 2016 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" | |
| #include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h" | |
| CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, uint32_t dwSize) | |
| : m_pData(pData), m_dwSize(dwSize), m_dwCurPos(0) {} | |
| CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) | |
| : m_pData(str.raw_str()), m_dwSize(str.GetLength()), m_dwCurPos(0) {} | |
| void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, uint32_t& dwSize) { | |
| pStart = nullptr; | |
| dwSize = 0; | |
| uint8_t ch; | |
| while (1) { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| while (PDFCharIsWhitespace(ch)) { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| } | |
| if (ch != '%') | |
| break; | |
| while (1) { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| if (PDFCharIsLineEnding(ch)) | |
| break; | |
| } | |
| } | |
| uint32_t start_pos = m_dwCurPos - 1; | |
| pStart = m_pData + start_pos; | |
| if (PDFCharIsDelimiter(ch)) { | |
| if (ch == '/') { | |
| while (1) { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) { | |
| m_dwCurPos--; | |
| dwSize = m_dwCurPos - start_pos; | |
| return; | |
| } | |
| } | |
| } else { | |
| dwSize = 1; | |
| if (ch == '<') { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| if (ch == '<') | |
| dwSize = 2; | |
| else | |
| m_dwCurPos--; | |
| } else if (ch == '>') { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| if (ch == '>') | |
| dwSize = 2; | |
| else | |
| m_dwCurPos--; | |
| } | |
| } | |
| return; | |
| } | |
| dwSize = 1; | |
| while (1) { | |
| if (m_dwSize <= m_dwCurPos) | |
| return; | |
| ch = m_pData[m_dwCurPos++]; | |
| if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { | |
| m_dwCurPos--; | |
| break; | |
| } | |
| dwSize++; | |
| } | |
| } | |
| CFX_ByteStringC CPDF_SimpleParser::GetWord() { | |
| const uint8_t* pStart; | |
| uint32_t dwSize; | |
| ParseWord(pStart, dwSize); | |
| if (dwSize == 1 && pStart[0] == '<') { | |
| while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { | |
| m_dwCurPos++; | |
| } | |
| if (m_dwCurPos < m_dwSize) { | |
| m_dwCurPos++; | |
| } | |
| return CFX_ByteStringC(pStart, | |
| (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); | |
| } | |
| if (dwSize == 1 && pStart[0] == '(') { | |
| int level = 1; | |
| while (m_dwCurPos < m_dwSize) { | |
| if (m_pData[m_dwCurPos] == ')') { | |
| level--; | |
| if (level == 0) { | |
| break; | |
| } | |
| } | |
| if (m_pData[m_dwCurPos] == '\\') { | |
| if (m_dwSize <= m_dwCurPos) { | |
| break; | |
| } | |
| m_dwCurPos++; | |
| } else if (m_pData[m_dwCurPos] == '(') { | |
| level++; | |
| } | |
| if (m_dwSize <= m_dwCurPos) { | |
| break; | |
| } | |
| m_dwCurPos++; | |
| } | |
| if (m_dwCurPos < m_dwSize) { | |
| m_dwCurPos++; | |
| } | |
| return CFX_ByteStringC(pStart, | |
| (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); | |
| } | |
| return CFX_ByteStringC(pStart, dwSize); | |
| } | |
| bool CPDF_SimpleParser::FindTagParamFromStart(const CFX_ByteStringC& token, | |
| int nParams) { | |
| nParams++; | |
| uint32_t* pBuf = FX_Alloc(uint32_t, nParams); | |
| int buf_index = 0; | |
| int buf_count = 0; | |
| m_dwCurPos = 0; | |
| while (1) { | |
| pBuf[buf_index++] = m_dwCurPos; | |
| if (buf_index == nParams) { | |
| buf_index = 0; | |
| } | |
| buf_count++; | |
| if (buf_count > nParams) { | |
| buf_count = nParams; | |
| } | |
| CFX_ByteStringC word = GetWord(); | |
| if (word.IsEmpty()) { | |
| FX_Free(pBuf); | |
| return false; | |
| } | |
| if (word == token) { | |
| if (buf_count < nParams) { | |
| continue; | |
| } | |
| m_dwCurPos = pBuf[buf_index]; | |
| FX_Free(pBuf); | |
| return true; | |
| } | |
| } | |
| return false; | |
| } |