summaryrefslogtreecommitdiff
path: root/fpdfsdk/fsdk_define.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/fsdk_define.cpp')
-rw-r--r--fpdfsdk/fsdk_define.cpp462
1 files changed, 462 insertions, 0 deletions
diff --git a/fpdfsdk/fsdk_define.cpp b/fpdfsdk/fsdk_define.cpp
new file mode 100644
index 0000000000..917d36d88e
--- /dev/null
+++ b/fpdfsdk/fsdk_define.cpp
@@ -0,0 +1,462 @@
+// Copyright 2018 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 "fpdfsdk/fsdk_define.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fpdfdoc/cpdf_metadata.h"
+#include "core/fxcrt/xml/cxml_content.h"
+#include "core/fxcrt/xml/cxml_element.h"
+#include "public/fpdf_ext.h"
+
+namespace {
+
+FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
+ return static_cast<FPDF_DOCUMENT>(doc);
+}
+
+bool RaiseUnSupportError(int nError) {
+ CFSDK_UnsupportInfo_Adapter* pAdapter =
+ CPDF_ModuleMgr::Get()->GetUnsupportInfoAdapter();
+ if (!pAdapter)
+ return false;
+
+ UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(pAdapter->GetUnspInfo());
+ if (info && info->FSDK_UnSupport_Handler)
+ info->FSDK_UnSupport_Handler(info, nError);
+ return true;
+}
+
+bool CheckSharedForm(const CXML_Element* pElement, ByteString cbName) {
+ size_t count = pElement->CountAttrs();
+ for (size_t i = 0; i < count; ++i) {
+ ByteString space;
+ ByteString name;
+ WideString value;
+ pElement->GetAttrByIndex(i, &space, &name, &value);
+ if (space == "xmlns" && name == "adhocwf" &&
+ value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") {
+ CXML_Element* pVersion =
+ pElement->GetElement("adhocwf", cbName.AsStringView(), 0);
+ if (!pVersion)
+ continue;
+ CXML_Content* pContent = ToContent(pVersion->GetChild(0));
+ if (!pContent)
+ continue;
+ switch (pContent->m_Content.GetInteger()) {
+ case 1:
+ RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
+ break;
+ case 2:
+ RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
+ break;
+ case 0:
+ RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
+ break;
+ }
+ }
+ }
+
+ size_t nCount = pElement->CountChildren();
+ for (size_t i = 0; i < nCount; ++i) {
+ CXML_Element* pChild = ToElement(pElement->GetChild(i));
+ if (pChild && CheckSharedForm(pChild, cbName))
+ return true;
+ }
+ return false;
+}
+
+#ifdef PDF_ENABLE_XFA
+class FPDF_FileHandlerContext : public IFX_SeekableStream {
+ public:
+ template <typename T, typename... Args>
+ friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+ ~FPDF_FileHandlerContext() override;
+
+ // IFX_SeekableStream:
+ FX_FILESIZE GetSize() override;
+ bool IsEOF() override;
+ FX_FILESIZE GetPosition() override;
+ bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+ size_t ReadBlock(void* buffer, size_t size) override;
+ bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
+ bool Flush() override;
+
+ void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
+
+ protected:
+ explicit FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS);
+
+ FPDF_FILEHANDLER* m_pFS;
+ FX_FILESIZE m_nCurPos;
+};
+
+FPDF_FileHandlerContext::FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS) {
+ m_pFS = pFS;
+ m_nCurPos = 0;
+}
+
+FPDF_FileHandlerContext::~FPDF_FileHandlerContext() {
+ if (m_pFS && m_pFS->Release)
+ m_pFS->Release(m_pFS->clientData);
+}
+
+FX_FILESIZE FPDF_FileHandlerContext::GetSize() {
+ if (m_pFS && m_pFS->GetSize)
+ return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
+ return 0;
+}
+
+bool FPDF_FileHandlerContext::IsEOF() {
+ return m_nCurPos >= GetSize();
+}
+
+FX_FILESIZE FPDF_FileHandlerContext::GetPosition() {
+ return m_nCurPos;
+}
+
+bool FPDF_FileHandlerContext::ReadBlock(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ if (!buffer || !size || !m_pFS->ReadBlock)
+ return false;
+
+ if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+ (FPDF_DWORD)size) == 0) {
+ m_nCurPos = offset + size;
+ return true;
+ }
+ return false;
+}
+
+size_t FPDF_FileHandlerContext::ReadBlock(void* buffer, size_t size) {
+ if (!buffer || !size || !m_pFS->ReadBlock)
+ return 0;
+
+ FX_FILESIZE nSize = GetSize();
+ if (m_nCurPos >= nSize)
+ return 0;
+ FX_FILESIZE dwAvail = nSize - m_nCurPos;
+ if (dwAvail < (FX_FILESIZE)size)
+ size = static_cast<size_t>(dwAvail);
+ if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
+ (FPDF_DWORD)size) == 0) {
+ m_nCurPos += size;
+ return size;
+ }
+
+ return 0;
+}
+
+bool FPDF_FileHandlerContext::WriteBlock(const void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ if (!m_pFS || !m_pFS->WriteBlock)
+ return false;
+
+ if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+ (FPDF_DWORD)size) == 0) {
+ m_nCurPos = offset + size;
+ return true;
+ }
+ return false;
+}
+
+bool FPDF_FileHandlerContext::Flush() {
+ if (!m_pFS || !m_pFS->Flush)
+ return true;
+
+ return m_pFS->Flush(m_pFS->clientData) == 0;
+}
+#endif // PDF_ENABLE_XFA
+
+} // namespace
+
+UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
+ return static_cast<UnderlyingDocumentType*>(doc);
+}
+
+UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
+ return static_cast<UnderlyingPageType*>(page);
+}
+
+CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
+#ifdef PDF_ENABLE_XFA
+ return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
+#else // PDF_ENABLE_XFA
+ return UnderlyingFromFPDFDocument(doc);
+#endif // PDF_ENABLE_XFA
+}
+
+FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
+#ifdef PDF_ENABLE_XFA
+ return doc ? FPDFDocumentFromUnderlying(
+ new CPDFXFA_Context(pdfium::WrapUnique(doc)))
+ : nullptr;
+#else // PDF_ENABLE_XFA
+ return FPDFDocumentFromUnderlying(doc);
+#endif // PDF_ENABLE_XFA
+}
+
+CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
+#ifdef PDF_ENABLE_XFA
+ return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
+#else // PDF_ENABLE_XFA
+ return UnderlyingFromFPDFPage(page);
+#endif // PDF_ENABLE_XFA
+}
+
+CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
+ return static_cast<CPDF_PageObject*>(page_object);
+}
+
+ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
+ return WideString::FromUTF16LE(wide_string,
+ WideString::WStringLength(wide_string))
+ .UTF8Encode();
+}
+
+CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) {
+ return static_cast<CFX_DIBitmap*>(bitmap);
+}
+
+void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot) {
+ CPDF_Annot::Subtype nAnnotSubtype = pPDFAnnot->GetSubtype();
+ if (nAnnotSubtype == CPDF_Annot::Subtype::THREED) {
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::SCREEN) {
+ const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
+ ByteString cbString;
+ if (pAnnotDict->KeyExist("IT"))
+ cbString = pAnnotDict->GetStringFor("IT");
+ if (cbString.Compare("Img") != 0)
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::MOVIE) {
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_MOVIE);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::SOUND) {
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_SOUND);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::RICHMEDIA) {
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) {
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
+ } else if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET) {
+ const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
+ ByteString cbString;
+ if (pAnnotDict->KeyExist("FT"))
+ cbString = pAnnotDict->GetStringFor("FT");
+ if (cbString.Compare("Sig") == 0)
+ RaiseUnSupportError(FPDF_UNSP_ANNOT_SIG);
+ }
+}
+
+void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
+ // Security
+ if (err_code == FPDF_ERR_SECURITY) {
+ RaiseUnSupportError(FPDF_UNSP_DOC_SECURITY);
+ return;
+ }
+ if (!pDoc)
+ return;
+
+ // Portfolios and Packages
+ const CPDF_Dictionary* pRootDict = pDoc->GetRoot();
+ if (pRootDict) {
+ ByteString cbString;
+ if (pRootDict->KeyExist("Collection")) {
+ RaiseUnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
+ return;
+ }
+ if (pRootDict->KeyExist("Names")) {
+ CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
+ if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
+ RaiseUnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
+ return;
+ }
+ if (pNameDict && pNameDict->KeyExist("JavaScript")) {
+ CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
+ CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
+ if (pArray) {
+ for (size_t i = 0; i < pArray->GetCount(); i++) {
+ ByteString cbStr = pArray->GetStringAt(i);
+ if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
+ RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // SharedForm
+ CPDF_Metadata metaData(pDoc);
+ const CXML_Element* pElement = metaData.GetRoot();
+ if (pElement)
+ CheckSharedForm(pElement, "workflowType");
+
+#ifndef PDF_ENABLE_XFA
+ // XFA Forms
+ CPDF_InterForm interform(pDoc);
+ if (interform.HasXFAForm())
+ RaiseUnSupportError(FPDF_UNSP_DOC_XFAFORM);
+#endif // PDF_ENABLE_XFA
+}
+
+#ifndef _WIN32
+int g_LastError;
+void SetLastError(int err) {
+ g_LastError = err;
+}
+
+int GetLastError() {
+ return g_LastError;
+}
+#endif // _WIN32
+
+void ProcessParseError(CPDF_Parser::Error err) {
+ uint32_t err_code = FPDF_ERR_SUCCESS;
+ // Translate FPDFAPI error code to FPDFVIEW error code
+ switch (err) {
+ case CPDF_Parser::SUCCESS:
+ err_code = FPDF_ERR_SUCCESS;
+ break;
+ case CPDF_Parser::FILE_ERROR:
+ err_code = FPDF_ERR_FILE;
+ break;
+ case CPDF_Parser::FORMAT_ERROR:
+ err_code = FPDF_ERR_FORMAT;
+ break;
+ case CPDF_Parser::PASSWORD_ERROR:
+ err_code = FPDF_ERR_PASSWORD;
+ break;
+ case CPDF_Parser::HANDLER_ERROR:
+ err_code = FPDF_ERR_SECURITY;
+ break;
+ }
+ SetLastError(err_code);
+}
+
+// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
+static uint32_t foxit_sandbox_policy = 0xFFFFFFFF;
+
+void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
+ switch (policy) {
+ case FPDF_POLICY_MACHINETIME_ACCESS: {
+ if (enable)
+ foxit_sandbox_policy |= 0x01;
+ else
+ foxit_sandbox_policy &= 0xFFFFFFFE;
+ } break;
+ default:
+ break;
+ }
+}
+
+FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
+ switch (policy) {
+ case FPDF_POLICY_MACHINETIME_ACCESS:
+ return !!(foxit_sandbox_policy & 0x01);
+ default:
+ return false;
+ }
+}
+
+unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
+ void* buffer,
+ unsigned long buflen) {
+ ASSERT(stream);
+ uint8_t* data = stream->GetRawData();
+ uint32_t len = stream->GetRawSize();
+ CPDF_Dictionary* dict = stream->GetDict();
+ CPDF_Object* decoder = dict ? dict->GetDirectObjectFor("Filter") : nullptr;
+ if (decoder && (decoder->IsArray() || decoder->IsName())) {
+ // Decode the stream if one or more stream filters are specified.
+ uint8_t* decoded_data = nullptr;
+ uint32_t decoded_len = 0;
+ ByteString dummy_last_decoder;
+ CPDF_Dictionary* dummy_last_param;
+ if (PDF_DataDecode(data, len, dict, dict->GetIntegerFor("DL"), false,
+ &decoded_data, &decoded_len, &dummy_last_decoder,
+ &dummy_last_param)) {
+ if (buffer && buflen >= decoded_len)
+ memcpy(buffer, decoded_data, decoded_len);
+
+ // Free the buffer for the decoded data if it was allocated by
+ // PDF_DataDecode(). Note that for images with a single image-specific
+ // filter, |decoded_data| is directly assigned to be |data|, so
+ // |decoded_data| does not need to be freed.
+ if (decoded_data != data)
+ FX_Free(decoded_data);
+
+ return decoded_len;
+ }
+ }
+ // Copy the raw data and return its length if there is no valid filter
+ // specified or if decoding failed.
+ if (buffer && buflen >= len)
+ memcpy(buffer, data, len);
+
+ return len;
+}
+
+unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
+ void* buffer,
+ unsigned long buflen) {
+ ByteString encoded_text = text.UTF16LE_Encode();
+ unsigned long len = encoded_text.GetLength();
+ if (buffer && len <= buflen)
+ memcpy(buffer, encoded_text.c_str(), len);
+ return len;
+}
+
+void FSRECTFFromCFXFloatRect(const CFX_FloatRect& rect, FS_RECTF* out_rect) {
+ out_rect->left = rect.left;
+ out_rect->top = rect.top;
+ out_rect->right = rect.right;
+ out_rect->bottom = rect.bottom;
+}
+
+CFX_FloatRect CFXFloatRectFromFSRECTF(const FS_RECTF& rect) {
+ return CFX_FloatRect(rect.left, rect.bottom, rect.right, rect.top);
+}
+
+const CPDF_Array* GetQuadPointsArrayFromDictionary(CPDF_Dictionary* dict) {
+ return dict ? dict->GetArrayFor("QuadPoints") : nullptr;
+}
+
+bool GetQuadPointsFromDictionary(CPDF_Dictionary* dict,
+ size_t quad_index,
+ FS_QUADPOINTSF* quad_points) {
+ ASSERT(quad_points);
+
+ const CPDF_Array* pArray = GetQuadPointsArrayFromDictionary(dict);
+ if (!pArray || quad_index >= pArray->GetCount() / 8)
+ return false;
+
+ quad_index *= 8;
+ quad_points->x1 = pArray->GetNumberAt(quad_index);
+ quad_points->y1 = pArray->GetNumberAt(quad_index + 1);
+ quad_points->x2 = pArray->GetNumberAt(quad_index + 2);
+ quad_points->y2 = pArray->GetNumberAt(quad_index + 3);
+ quad_points->x3 = pArray->GetNumberAt(quad_index + 4);
+ quad_points->y3 = pArray->GetNumberAt(quad_index + 5);
+ quad_points->x4 = pArray->GetNumberAt(quad_index + 6);
+ quad_points->y4 = pArray->GetNumberAt(quad_index + 7);
+ return true;
+}
+
+#ifdef PDF_ENABLE_XFA
+RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+ FPDF_FILEHANDLER* pFilehandler) {
+ return pdfium::MakeRetain<FPDF_FileHandlerContext>(pFilehandler);
+}
+#endif // PDF_ENABLE_XFA