CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOOL bInArray) { FX_BOOL bIsNumber; GetNextWord(bIsNumber); if (m_WordSize == 0) { return NULL; } if (bIsNumber) { m_WordBuffer[m_WordSize] = 0; return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); } int first_char = m_WordBuffer[0]; if (first_char == '/') { return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); } if (first_char == '(') { return CPDF_String::Create(ReadString()); } if (first_char == '<') { if (m_WordSize == 1) { return CPDF_String::Create(ReadHexString(), TRUE); } CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 0) { pDict->Release(); return NULL; } if (m_WordSize == 2 && m_WordBuffer[0] == '>') { break; } if (m_WordBuffer[0] != '/') { pDict->Release(); return NULL; } CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); CPDF_Object* pObj = ReadNextObject(TRUE); if (pObj == NULL) { if (pDict) { pDict->Release(); } return NULL; } if (!key.IsEmpty()) { pDict->SetAt(key, pObj); } else { pObj->Release(); } } return pDict; } if (first_char == '[') { if (!bAllowNestedArray && bInArray) { return NULL; } CPDF_Array* pArray = CPDF_Array::Create(); while (1) { CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); if (pObj == NULL) { if (m_WordSize == 0 || m_WordBuffer[0] == ']') { return pArray; } if (m_WordBuffer[0] == '[') { continue; } } else { pArray->Add(pObj); } } } if (m_WordSize == 4) { if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { return CPDF_Boolean::Create(TRUE); } if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { return CPDF_Null::Create(); } } else if (m_WordSize == 5) { if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { return CPDF_Boolean::Create(FALSE); } } return NULL; }
std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( bool bAllowNestedArray, bool bInArray, uint32_t dwRecursionLevel) { bool bIsNumber; // Must get the next word before returning to avoid infinite loops. GetNextWord(bIsNumber); if (!m_WordSize || dwRecursionLevel > kMaxNestedParsingLevel) return nullptr; if (bIsNumber) { m_WordBuffer[m_WordSize] = 0; return pdfium::MakeUnique<CPDF_Number>( ByteStringView(m_WordBuffer, m_WordSize)); } int first_char = m_WordBuffer[0]; if (first_char == '/') { ByteString name = PDF_NameDecode(ByteStringView(m_WordBuffer + 1, m_WordSize - 1)); return pdfium::MakeUnique<CPDF_Name>(m_pPool, name); } if (first_char == '(') { ByteString str = ReadString(); return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false); } if (first_char == '<') { if (m_WordSize == 1) return pdfium::MakeUnique<CPDF_String>(m_pPool, ReadHexString(), true); auto pDict = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 2 && m_WordBuffer[0] == '>') break; if (!m_WordSize || m_WordBuffer[0] != '/') return nullptr; ByteString key = PDF_NameDecode(ByteStringView(m_WordBuffer + 1, m_WordSize - 1)); std::unique_ptr<CPDF_Object> pObj = ReadNextObject(true, bInArray, dwRecursionLevel + 1); if (!pObj) return nullptr; if (!key.IsEmpty()) pDict->SetFor(key, std::move(pObj)); } return std::move(pDict); } if (first_char == '[') { if ((!bAllowNestedArray && bInArray)) return nullptr; auto pArray = pdfium::MakeUnique<CPDF_Array>(); while (1) { std::unique_ptr<CPDF_Object> pObj = ReadNextObject(bAllowNestedArray, true, dwRecursionLevel + 1); if (pObj) { pArray->Add(std::move(pObj)); continue; } if (!m_WordSize || m_WordBuffer[0] == ']') break; } return std::move(pArray); } if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5)) return pdfium::MakeUnique<CPDF_Boolean>(false); if (m_WordSize == 4) { if (memcmp(m_WordBuffer, "true", 4) == 0) return pdfium::MakeUnique<CPDF_Boolean>(true); if (memcmp(m_WordBuffer, "null", 4) == 0) return pdfium::MakeUnique<CPDF_Null>(); } return nullptr; }