Update pdfium to 7188

Now that CI has VS2022.

Drop retrieve-MIME-type-from-PDF-attachments.patch.1, it was a backport.

Patch out absl::flat_hash_set<> usage for now, it would pull in tons of
absl code, some of that is even platform-dependent. std::set<> is
probably good enough, as it was used in the past.

Change-Id: I86c8c934c43a03de50077a6be4b5e26903223316
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192283
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
Miklos Vajna
2025-10-13 17:57:11 +02:00
parent 2f5df98892
commit 31bfebac64
7 changed files with 153 additions and 188 deletions
+2 -2
View File
@@ -564,8 +564,8 @@ PAGEMAKER_TARBALL := libpagemaker-0.0.4.tar.xz
# three static lines
# so that git cherry-pick
# will not run into conflicts
PDFIUM_SHA256SUM := e647ca4fcc2c91d9dca717452e1b1be1ab6155ac4977dca716041652c7b10bdd
PDFIUM_TARBALL := pdfium-7012.tar.bz2
PDFIUM_SHA256SUM := 39fb44362857fa347cea1bd4653db85c926e6b2d87027487f15ff04a1d69b163
PDFIUM_TARBALL := pdfium-7188.tar.bz2
# three static lines
# so that git cherry-pick
# will not run into conflicts
-23
View File
@@ -101,13 +101,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_interactiveform \
UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_renderpage \
UnpackedTarball/pdfium/fpdfsdk/fpdf_signature \
UnpackedTarball/pdfium/constants/annotation_common \
UnpackedTarball/pdfium/constants/appearance \
UnpackedTarball/pdfium/constants/form_fields \
UnpackedTarball/pdfium/constants/page_object \
UnpackedTarball/pdfium/constants/stream_dict_common \
UnpackedTarball/pdfium/constants/transparency \
UnpackedTarball/pdfium/constants/font_encodings \
))
# fdrm
@@ -135,7 +128,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
# fpdfapi
$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/Adobe-CNS1-UCS2_5 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/B5pc-H_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/B5pc-V_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/CNS-EUC-H_0 \
@@ -149,8 +141,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UCS2-H_3 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UCS2-V_3 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UTF16-H_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/cmaps_cns1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/Adobe-GB1-UCS2_5 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GB-EUC-H_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GB-EUC-V_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBK-EUC-H_2 \
@@ -163,7 +153,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBpc-EUC-V_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/UniGB-UCS2-H_4 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/UniGB-UCS2-V_4 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/cmaps_gb1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/83pv-RKSJ-H_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90ms-RKSJ-H_2 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90ms-RKSJ-V_2 \
@@ -172,7 +161,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90pv-RKSJ-H_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Add-RKSJ-H_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Add-RKSJ-V_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Adobe-Japan1-UCS2_4 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/EUC-H_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/EUC-V_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Ext-RKSJ-H_2 \
@@ -183,8 +171,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-H_4 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-V_4 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/V_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/cmaps_japan1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/Adobe-Korea1-UCS2_2 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSC-EUC-H_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSC-EUC-V_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCms-UHC-HW-H_1 \
@@ -195,7 +181,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UCS2-H_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UCS2-V_1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UTF16-H_0 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/cmaps_korea1 \
UnpackedTarball/pdfium/core/fpdfapi/cmaps/fpdf_cmaps \
UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_pagecontentgenerator \
UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_npagetooneexporter \
@@ -554,14 +539,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/third_party/agg23/agg_vcgen_stroke \
))
ifneq ($(SYSTEM_ABSEIL),TRUE)
# third_party/abseil-cpp
$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
UnpackedTarball/pdfium/third_party/abseil-cpp/absl/types/bad_optional_access \
UnpackedTarball/pdfium/third_party/abseil-cpp/absl/types/bad_variant_access \
))
endif
ifneq ($(SYSTEM_OPENJPEG2),TRUE)
# third_party/fx_libopenjpeg
$(eval $(call gb_Library_add_generated_cobjects,pdfium,\
+1 -6
View File
@@ -22,9 +22,6 @@ pdfium_patches += tounicodeinfo.patch.1
pdfium_patches += system-fast_float.diff
# https://pdfium-review.googlesource.com/c/pdfium/+/130970
pdfium_patches += retrieve-MIME-type-from-PDF-attachments.patch.1
ifeq ($(OS),WNT)
pdfium_patches += pdfium-vs2019-arm64_no-__umulh.patch.1
endif
@@ -49,9 +46,7 @@ $(eval $(call gb_UnpackedTarball_set_post_action,pdfium,\
mv third_party/bigint/BigUnsignedInABase.cc third_party/bigint/BigUnsignedInABase.cpp && \
mv core/fxcrt/debug/alias.cc core/fxcrt/debug/alias.cpp && \
mv core/fxcrt/win/win_util.cc core/fxcrt/win/win_util.cpp && \
mv third_party/libopenjpeg/opj_malloc.cc third_party/libopenjpeg/opj_malloc.cpp && \
mv third_party/abseil-cpp/absl/types/bad_optional_access.cc third_party/abseil-cpp/absl/types/bad_optional_access.cpp && \
mv third_party/abseil-cpp/absl/types/bad_variant_access.cc third_party/abseil-cpp/absl/types/bad_variant_access.cpp \
mv third_party/libopenjpeg/opj_malloc.cc third_party/libopenjpeg/opj_malloc.cpp \
))
# vim: set noet sw=4 ts=4:
+144 -65
View File
@@ -1,17 +1,4 @@
-*- Mode: diff -*-
diff --git a/core/fpdfdoc/cpdf_metadata.cpp b/core/fpdfdoc/cpdf_metadata.cpp
index 31564f45f..5858549ef 100644
--- a/core/fpdfdoc/cpdf_metadata.cpp
+++ b/core/fpdfdoc/cpdf_metadata.cpp
@@ -87,7 +87,7 @@ std::vector<UnsupportedFeature> CPDF_Metadata::CheckForSharedForm() const {
CFX_XMLParser parser(stream);
std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
if (!doc)
- return {};
+ return std::vector<UnsupportedFeature>();
std::vector<UnsupportedFeature> unsupported;
CheckForSharedFormInternal(/*depth=*/0, doc->GetRoot(), &unsupported);
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index 7d9cd0f44..0d0a311aa 100644
--- a/core/fxge/cfx_face.cpp
@@ -25,58 +12,6 @@ index 7d9cd0f44..0d0a311aa 100644
}
FX_RECT CFX_Face::GetCharBBox(uint32_t code, int glyph_index) {
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp
index a5b687d76..076a260d5 100644
--- a/core/fpdfdoc/cpdf_action.cpp
+++ b/core/fpdfdoc/cpdf_action.cpp
@@ -21,7 +21,7 @@
namespace {
-constexpr auto kActionTypeStrings = fxcrt::ToArray<const char*>({
+std::array<const char*, 18> kActionTypeStrings = {
"GoTo",
"GoToR",
"GoToE",
@@ -40,7 +40,7 @@ constexpr auto kActionTypeStrings = fxcrt::ToArray<const char*>({
"Rendition",
"Trans",
"GoTo3DView",
-});
+};
} // namespace
diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp
index 8026a75d5..34c20d62f 100644
--- a/core/fpdfdoc/cpdf_dest.cpp
+++ b/core/fpdfdoc/cpdf_dest.cpp
@@ -21,9 +21,9 @@ namespace {
// These arrays are indexed by the PDFDEST_VIEW_* constants.
-constexpr auto kZoomModes =
- fxcrt::ToArray<const char*>({"Unknown", "XYZ", "Fit", "FitH", "FitV",
- "FitR", "FitB", "FitBH", "FitBV"});
+std::array<const char*, 9> kZoomModes = {
+ "Unknown", "XYZ", "Fit", "FitH", "FitV",
+ "FitR", "FitB", "FitBH", "FitBV"};
constexpr auto kZoomModeMaxParamCount =
fxcrt::ToArray<const uint8_t>({0, 3, 0, 1, 1, 4, 0, 1, 1});
--- pdfium/fpdfsdk/fpdf_annot.cpp.orig 2024-08-15 10:01:30.443712200 +0200
+++ pdfium/fpdfsdk/fpdf_annot.cpp 2024-08-15 10:04:41.161274500 +0200
@@ -1079,8 +1079,8 @@
if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT)
return false;
- static constexpr auto kModeKeyForMode =
- fxcrt::ToArray<const char*>({"N", "R", "D"});
+ static constexpr std::array<const char*, 3UL> kModeKeyForMode
+ ({"N", "R", "D"});
static_assert(kModeKeyForMode.size() == FPDF_ANNOT_APPEARANCEMODE_COUNT,
"length of kModeKeyForMode should be equal to "
"FPDF_ANNOT_APPEARANCEMODE_COUNT");
--- a/core/fxcrt/fx_memory_wrappers.h 2025-02-13 13:38:35.761778900 +0100
+++ b/core/fxcrt/fx_memory_wrappers.h 2025-02-13 13:38:48.136654800 +0100
@@ -33,9 +33,6 @@
@@ -89,3 +24,147 @@ index 8026a75d5..34c20d62f 100644
using value_type = T;
using pointer = T*;
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index a8e9e6090..0c341ab7f 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -289,7 +289,7 @@ void CloneResourcesDictEntries(CPDF_Document* doc,
pdfium::Contains(kResourceKeys, key)) {
RetainPtr<const CPDF_Object> direct_object = object->GetDirect();
if (direct_object) {
- entries_to_maybe_clone.emplace_back(key, std::move(direct_object));
+ entries_to_maybe_clone.push_back(KeyAndObject{key, std::move(direct_object)});
}
}
}
diff --git a/core/fxcrt/numerics/safe_conversions_impl.h b/core/fxcrt/numerics/safe_conversions_impl.h
index b51078761..5e5d9fca7 100644
--- a/core/fxcrt/numerics/safe_conversions_impl.h
+++ b/core/fxcrt/numerics/safe_conversions_impl.h
@@ -373,7 +373,7 @@ INTEGER_FOR_DIGITS_AND_SIGN(uint64_t);
template <size_t Size, bool IsSigned>
using IntegerForDigitsAndSign =
- IntegerForDigitsAndSignImpl<Size, IsSigned>::type;
+ typename IntegerForDigitsAndSignImpl<Size, IsSigned>::type;
// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to
// support 128-bit math, then the ArithmeticPromotion template below will need
@@ -437,7 +437,7 @@ struct BigEnoughPromotionImpl<Lhs, Rhs, true, false> {
};
template <typename Lhs, typename Rhs>
-using BigEnoughPromotion = BigEnoughPromotionImpl<Lhs, Rhs>::type;
+using BigEnoughPromotion = typename BigEnoughPromotionImpl<Lhs, Rhs>::type;
template <typename Lhs, typename Rhs>
inline constexpr bool kIsBigEnoughPromotionContained =
@@ -480,7 +480,7 @@ struct FastIntegerArithmeticPromotionImpl<Lhs, Rhs> {
template <typename Lhs, typename Rhs>
using FastIntegerArithmeticPromotion =
- FastIntegerArithmeticPromotionImpl<Lhs, Rhs>::type;
+ typename FastIntegerArithmeticPromotionImpl<Lhs, Rhs>::type;
template <typename Lhs, typename Rhs>
inline constexpr bool kIsFastIntegerArithmeticPromotionContained =
@@ -494,7 +494,7 @@ struct ArithmeticOrIntegralConstant {
template <typename T>
requires IntegralConstantLike<T>
struct ArithmeticOrIntegralConstant<T> {
- using type = T::value_type;
+ using type = typename T::value_type;
};
// Extracts the underlying type from an enum.
@@ -556,7 +556,7 @@ struct UnderlyingTypeImpl<StrictNumeric<T>> {
using type = T;
};
template <typename T>
-using UnderlyingType = UnderlyingTypeImpl<T>::type;
+using UnderlyingType = typename UnderlyingTypeImpl<T>::type;
template <typename T>
inline constexpr bool kIsNumeric = std::is_arithmetic_v<UnderlyingType<T>>;
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index 47fae4b61..65e3e1c40 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -191,7 +191,7 @@ bool UpdateNodesAndLimitsUponDeletion(CPDF_Dictionary* pNode,
}
bool IsTraversedObject(const CPDF_Object* obj,
- absl::flat_hash_set<uint32_t>* seen_obj_nums) {
+ std::set<uint32_t>* seen_obj_nums) {
uint32_t obj_num = obj->GetObjNum();
if (!obj_num) {
return false;
@@ -202,7 +202,7 @@ bool IsTraversedObject(const CPDF_Object* obj,
}
bool IsArrayWithTraversedObject(const CPDF_Array* array,
- absl::flat_hash_set<uint32_t>* seen_obj_nums) {
+ std::set<uint32_t>* seen_obj_nums) {
if (IsTraversedObject(array, seen_obj_nums)) {
return true;
}
@@ -227,7 +227,7 @@ RetainPtr<const CPDF_Object> SearchNameNodeByNameInternal(
int nLevel,
size_t* nIndex,
NodeToInsert* node_to_insert,
- absl::flat_hash_set<uint32_t>* seen_obj_nums) {
+ std::set<uint32_t>* seen_obj_nums) {
if (nLevel > kNameTreeMaxRecursion) {
return nullptr;
}
@@ -317,7 +317,7 @@ RetainPtr<const CPDF_Object> SearchNameNodeByName(
const WideString& csName,
NodeToInsert* node_to_insert) {
size_t nIndex = 0;
- absl::flat_hash_set<uint32_t> seen_obj_nums;
+ std::set<uint32_t> seen_obj_nums;
return SearchNameNodeByNameInternal(pNode, csName, 0, &nIndex, node_to_insert,
&seen_obj_nums);
}
@@ -398,7 +398,7 @@ std::optional<IndexSearchResult> SearchNameNodeByIndex(
// Get the total number of key-value pairs in the tree with root |pNode|.
size_t CountNamesInternal(const CPDF_Dictionary* pNode,
int nLevel,
- absl::flat_hash_set<const CPDF_Dictionary*>& seen) {
+ std::set<const CPDF_Dictionary*>& seen) {
if (nLevel > kNameTreeMaxRecursion) {
return 0;
}
@@ -535,7 +535,7 @@ RetainPtr<const CPDF_Array> CPDF_NameTree::LookupNamedDest(
}
size_t CPDF_NameTree::GetCount() const {
- absl::flat_hash_set<const CPDF_Dictionary*> seen;
+ std::set<const CPDF_Dictionary*> seen;
return CountNamesInternal(root_.Get(), 0, seen);
}
diff --git a/core/fxcrt/span.h b/core/fxcrt/span.h
index bad07b723..b960f90b4 100644
--- a/core/fxcrt/span.h
+++ b/core/fxcrt/span.h
@@ -791,9 +791,6 @@ class GSL_POINTER span {
template <typename OtherElementType,
size_t OtherExtent,
typename OtherInternalPtrType>
- requires((OtherExtent == dynamic_extent || extent == OtherExtent) &&
- std::equality_comparable_with<const element_type,
- const OtherElementType>)
friend constexpr bool operator==(
span lhs,
span<OtherElementType, OtherExtent, OtherInternalPtrType> rhs) {
@@ -826,9 +823,6 @@ class GSL_POINTER span {
template <typename OtherElementType,
size_t OtherExtent,
typename OtherInternalPtrType>
- requires((OtherExtent == dynamic_extent || extent == OtherExtent) &&
- std::three_way_comparable_with<const element_type,
- const OtherElementType>)
friend constexpr auto operator<=>(
span lhs,
span<OtherElementType, OtherExtent, OtherInternalPtrType> rhs) {
+4 -1
View File
@@ -31,6 +31,7 @@
#include <agg_vcgen_stroke.h>
#include <algorithm>
#include <array>
#include <bit>
#include <cassert>
#include <cfloat>
#include <climits>
@@ -62,6 +63,7 @@
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#include <wchar.h>
#endif // PCH_LEVEL >= 1
@@ -298,6 +300,7 @@
#include <core/fxcrt/compiler_specific.h>
#include <core/fxcrt/containers/adapters.h>
#include <core/fxcrt/containers/contains.h>
#include <core/fxcrt/containers/unique_ptr_adapters.h>
#include <core/fxcrt/css/cfx_css.h>
#include <core/fxcrt/css/cfx_csscolorvalue.h>
#include <core/fxcrt/css/cfx_csscomputedstyle.h>
@@ -478,7 +481,7 @@
#include <public/fpdf_text.h>
#include <public/fpdf_transformpage.h>
#include <public/fpdfview.h>
#include <third_party/abseil-cpp/absl/types/variant.h>
#include <third_party/abseil-cpp/absl/container/flat_hash_set.h>
#include <third_party/agg23/agg_clip_liang_barsky.h>
#include <third_party/agg23/agg_conv_dash.h>
#include <third_party/agg23/agg_conv_stroke.h>
+2 -2
View File
@@ -29,10 +29,10 @@
const ByteString type = pXObject->GetDict()->GetByteStringFor("Subtype");
if (type == "Form") {
+ if (!m_RecursionState->PushForm(pXObject.Get()))
+ if (!recursion_state_->PushForm(pXObject.Get()))
+ return;
AddForm(std::move(pXObject), name);
+ m_RecursionState->PopForm();
+ recursion_state_->PopForm();
return;
}
@@ -1,89 +0,0 @@
From 87a497287e02ba8cfa61418c2443e205d5b7e054 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <helmut@januschka.com>
Date: Mon, 28 Apr 2025 16:48:20 -0700
Subject: [PATCH] Add API to retrieve MIME type from PDF attachments
Adds new API to retrieve values from the embedded file stream
dictionary of PDF attachments:
FPDFAttachment_GetSubtype() - Specifically retrieves the MIME type
Bug: 408241034
Change-Id: Ia42813d0423dbdad3105f9ac1c8da4f3976e92c9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/130970
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
---
fpdfsdk/fpdf_attachment.cpp | 27 ++++++++++++++++++
fpdfsdk/fpdf_attachment_embeddertest.cpp | 36 ++++++++++++++++++++++++
fpdfsdk/fpdf_view_c_api_test.c | 1 +
public/fpdf_attachment.h | 17 +++++++++++
4 files changed, 81 insertions(+)
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index c5f251538..eaba2a78f 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -304,3 +304,30 @@ FPDFAttachment_GetFile(FPDF_ATTACHMENT attachment,
static_cast<size_t>(buflen))));
return true;
}
+
+FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFAttachment_GetSubtype(FPDF_ATTACHMENT attachment,
+ FPDF_WCHAR* buffer,
+ unsigned long buflen) {
+ CPDF_Object* file = CPDFObjectFromFPDFAttachment(attachment);
+ if (!file) {
+ return 0;
+ }
+
+ // SAFETY: required from caller.
+ auto buffer_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen));
+ CPDF_FileSpec spec(pdfium::WrapRetain(file));
+ RetainPtr<const CPDF_Stream> file_stream = spec.GetFileStream();
+ if (!file_stream) {
+ return Utf16EncodeMaybeCopyAndReturnLength(WideString(), buffer_span);
+ }
+
+ ByteString subtype = file_stream->GetDict()->GetNameFor("Subtype");
+ if (subtype.IsEmpty()) {
+ // Per API description, return an empty string in these cases.
+ return Utf16EncodeMaybeCopyAndReturnLength(WideString(), buffer_span);
+ }
+
+ return Utf16EncodeMaybeCopyAndReturnLength(
+ PDF_DecodeText(subtype.unsigned_span()), buffer_span);
+}
diff --git a/public/fpdf_attachment.h b/public/fpdf_attachment.h
index d25bddab6..a8a40b34b 100644
--- a/public/fpdf_attachment.h
+++ b/public/fpdf_attachment.h
@@ -172,6 +172,23 @@ FPDFAttachment_GetFile(FPDF_ATTACHMENT attachment,
unsigned long buflen,
unsigned long* out_buflen);
+// Experimental API.
+// Get the MIME type (Subtype) of the embedded file |attachment|. |buffer| is
+// only modified if |buflen| is longer than the length of the MIME type string.
+// If the Subtype is not found or if there is no file stream, an empty string
+// would be copied to |buffer| and the return value would be 2. On other errors,
+// nothing would be added to |buffer| and the return value would be 0.
+//
+// attachment - handle to an attachment.
+// buffer - buffer for holding the MIME type string encoded in UTF-16LE.
+// buflen - length of the buffer in bytes.
+//
+// Returns the length of the MIME type string in bytes.
+FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFAttachment_GetSubtype(FPDF_ATTACHMENT attachment,
+ FPDF_WCHAR* buffer,
+ unsigned long buflen);
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
--
2.43.0