Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}