Beispiel #1
0
FX_BOOL CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict,
                                             CPDF_StructElementImpl* pElement) {
  CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectBy("K");
  if (!pObj)
    return FALSE;

  if (pObj->IsDictionary()) {
    if (pObj->GetObjNum() != pDict->GetObjNum())
      return FALSE;
    m_Kids[0].Reset(pElement);
  }
  if (CPDF_Array* pTopKids = pObj->AsArray()) {
    bool bSave = false;
    for (size_t i = 0; i < pTopKids->GetCount(); i++) {
      CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i));
      if (pKidRef && pKidRef->GetRefObjNum() == pDict->GetObjNum()) {
        m_Kids[i].Reset(pElement);
        bSave = true;
      }
    }
    if (!bSave)
      return FALSE;
  }
  return TRUE;
}
FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum,
        CPDF_Dictionary* pThisPageDict) {
    for (int i = 0; i < m_PageList.GetSize(); i++) {
        CPDF_Dictionary* pPageDict = GetPage(i);
        if (pPageDict == pThisPageDict) {
            continue;
        }
        CPDF_Object* pContents =
            pPageDict ? pPageDict->GetElement("Contents") : NULL;
        if (!pContents) {
            continue;
        }
        if (pContents->GetDirectType() == PDFOBJ_ARRAY) {
            CPDF_Array* pArray = pContents->GetDirect()->AsArray();
            for (FX_DWORD j = 0; j < pArray->GetCount(); j++) {
                CPDF_Reference* pRef = ToReference(pArray->GetElement(j));
                if (pRef && pRef->GetRefObjNum() == objnum)
                    return TRUE;
            }
        } else if (pContents->GetObjNum() == objnum) {
            return TRUE;
        }
    }
    return FALSE;
}
bool CPDF_DataAvail::CheckRoot(DownloadHints* pHints) {
  bool bExist = false;
  m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
    return true;
  }

  if (!m_pRoot) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR) {
      m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
      return true;
    }
    return false;
  }

  CPDF_Dictionary* pDict = m_pRoot->GetDict();
  if (!pDict) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  CPDF_Reference* pRef = ToReference(pDict->GetObjectFor("Pages"));
  if (!pRef) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  m_PagesObjNum = pRef->GetRefObjNum();
  CPDF_Reference* pAcroFormRef =
      ToReference(m_pRoot->GetDict()->GetObjectFor("AcroForm"));
  if (pAcroFormRef) {
    m_bHaveAcroForm = true;
    m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
  }

  if (m_dwInfoObjNum) {
    m_docStatus = PDF_DATAAVAIL_INFO;
  } else {
    m_docStatus =
        m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE;
  }
  return true;
}
bool CPDF_DataAvail::PreparePageItem() {
  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  CPDF_Reference* pRef =
      ToReference(pRoot ? pRoot->GetObjectFor("Pages") : nullptr);
  if (!pRef) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  m_PagesObjNum = pRef->GetRefObjNum();
  m_pCurrentParser = m_pDocument->GetParser();
  m_docStatus = PDF_DATAAVAIL_PAGETREE;
  return true;
}
void CPDF_StreamContentParser::Handle_ExecuteXObject() {
  CFX_ByteString name = GetString(0);
  if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() &&
      m_pLastImage->GetStream()->GetObjNum()) {
    AddImage(nullptr, m_pLastImage, FALSE);
    return;
  }

  if (m_Options.m_bTextOnly) {
    if (!m_pResources)
      return;

    CPDF_Dictionary* pList = m_pResources->GetDict("XObject");
    if (!pList && m_pPageResources && m_pResources != m_pPageResources)
      pList = m_pPageResources->GetDict("XObject");
    if (!pList)
      return;
    CPDF_Reference* pRes = ToReference(pList->GetElement(name));
    if (!pRes)
      return;

    FX_BOOL bForm;
    if (m_pDocument->IsFormStream(pRes->GetRefObjNum(), bForm) && !bForm)
      return;
  }

  CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name));
  if (!pXObject) {
    m_bResourceMissing = TRUE;
    return;
  }

  CFX_ByteStringC type = pXObject->GetDict()
                             ? pXObject->GetDict()->GetConstString("Subtype")
                             : CFX_ByteStringC();
  if (type == "Image") {
    if (m_Options.m_bTextOnly) {
      return;
    }
    CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE);
    m_LastImageName = name;
    m_pLastImage = pObj->m_pImage;
    if (!m_pObjectList->m_bHasImageMask)
      m_pObjectList->m_bHasImageMask = m_pLastImage->IsMask();
  } else if (type == "Form") {
    AddForm(pXObject);
  } else {
    return;
  }
}
static CPDF_Stream* GetFormStream(CPDF_Document* pDoc, CPDF_Object* pResObj)
{
    if (pResObj->GetType() != PDFOBJ_REFERENCE) {
        return NULL;
    }
    CPDF_Reference* pRef = (CPDF_Reference*)pResObj;
    FX_BOOL bForm;
    if (pDoc->IsFormStream(pRef->GetRefObjNum(), bForm) && !bForm) {
        return NULL;
    }
    pResObj = pRef->GetDirect();
    if (pResObj->GetType() != PDFOBJ_STREAM) {
        return NULL;
    }
    CPDF_Stream* pXObject = (CPDF_Stream*)pResObj;
    if (pXObject->GetDict()->GetString(FX_BSTRC("Subtype")) != FX_BSTRC("Form")) {
        return NULL;
    }
    return pXObject;
}
bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo,
                                        PageNode* pPageNode,
                                        DownloadHints* pHints) {
  bool bExist = false;
  std::unique_ptr<CPDF_Object> pPages = GetObject(dwPageNo, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (!pPages) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR) {
      m_docStatus = PDF_DATAAVAIL_ERROR;
      return false;
    }
    return false;
  }

  CPDF_Array* pArray = pPages->AsArray();
  if (!pArray) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  pPageNode->m_type = PDF_PAGENODE_PAGES;
  for (size_t i = 0; i < pArray->GetCount(); ++i) {
    CPDF_Reference* pKid = ToReference(pArray->GetObjectAt(i));
    if (!pKid)
      continue;

    PageNode* pNode = new PageNode();
    pPageNode->m_childNode.Add(pNode);
    pNode->m_dwPageNo = pKid->GetRefObjNum();
  }
  return true;
}
bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array,
                                         bool bParsePage,
                                         DownloadHints* pHints,
                                         std::vector<CPDF_Object*>& ret_array) {
  if (obj_array.empty())
    return true;

  uint32_t count = 0;
  std::vector<CPDF_Object*> new_obj_array;
  for (CPDF_Object* pObj : obj_array) {
    if (!pObj)
      continue;

    int32_t type = pObj->GetType();
    switch (type) {
      case CPDF_Object::ARRAY: {
        CPDF_Array* pArray = pObj->AsArray();
        for (size_t k = 0; k < pArray->GetCount(); ++k)
          new_obj_array.push_back(pArray->GetObjectAt(k));
      } break;
      case CPDF_Object::STREAM:
        pObj = pObj->GetDict();
      case CPDF_Object::DICTIONARY: {
        CPDF_Dictionary* pDict = pObj->GetDict();
        if (pDict && pDict->GetStringFor("Type") == "Page" && !bParsePage)
          continue;

        for (const auto& it : *pDict) {
          if (it.first != "Parent")
            new_obj_array.push_back(it.second.get());
        }
      } break;
      case CPDF_Object::REFERENCE: {
        CPDF_Reference* pRef = pObj->AsReference();
        uint32_t dwNum = pRef->GetRefObjNum();

        FX_FILESIZE offset;
        uint32_t size = GetObjectSize(dwNum, offset);
        if (size == 0 || offset < 0 || offset >= m_dwFileLen)
          break;

        if (!IsDataAvail(offset, size, pHints)) {
          ret_array.push_back(pObj);
          count++;
        } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) {
          m_ObjectSet.insert(dwNum);
          CPDF_Object* pReferred =
              m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum());
          if (pReferred)
            new_obj_array.push_back(pReferred);
        }
      } break;
    }
  }

  if (count > 0) {
    for (CPDF_Object* pObj : new_obj_array) {
      CPDF_Reference* pRef = pObj->AsReference();
      if (pRef && pdfium::ContainsKey(m_ObjectSet, pRef->GetRefObjNum()))
        continue;
      ret_array.push_back(pObj);
    }
    return false;
  }

  obj_array = new_obj_array;
  return AreObjectsAvailable(obj_array, false, pHints, ret_array);
}
bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo,
                                         PageNode* pPageNode,
                                         DownloadHints* pHints) {
  bool bExist = false;
  std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (!pPage) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR)
      m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (pPage->IsArray()) {
    pPageNode->m_dwPageNo = dwPageNo;
    pPageNode->m_type = PDF_PAGENODE_ARRAY;
    return true;
  }

  if (!pPage->IsDictionary()) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  pPageNode->m_dwPageNo = dwPageNo;
  CPDF_Dictionary* pDict = pPage->GetDict();
  CFX_ByteString type = pDict->GetStringFor("Type");
  if (type == "Pages") {
    pPageNode->m_type = PDF_PAGENODE_PAGES;
    CPDF_Object* pKids = pDict->GetObjectFor("Kids");
    if (!pKids) {
      m_docStatus = PDF_DATAAVAIL_PAGE;
      return true;
    }

    switch (pKids->GetType()) {
      case CPDF_Object::REFERENCE: {
        CPDF_Reference* pKid = pKids->AsReference();
        PageNode* pNode = new PageNode();
        pPageNode->m_childNode.Add(pNode);
        pNode->m_dwPageNo = pKid->GetRefObjNum();
      } break;
      case CPDF_Object::ARRAY: {
        CPDF_Array* pKidsArray = pKids->AsArray();
        for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
          CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
          if (!pKid)
            continue;

          PageNode* pNode = new PageNode();
          pPageNode->m_childNode.Add(pNode);
          pNode->m_dwPageNo = pKid->GetRefObjNum();
        }
      } break;
      default:
        break;
    }
  } else if (type == "Page") {
    pPageNode->m_type = PDF_PAGENODE_PAGE;
  } else {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }
  return true;
}