Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
7adf81f
Add tests for reentrant node calculations.
tsepez Nov 3, 2026
145911a
Roll third_party/freetype/src/ 891f904e2..25167984d (36 commits)
leizleiz Nov 3, 2026
582f587
Roll third_party/libunwind/src/ eb1ca4993..9e44ea2ff (5 commits)
leizleiz Nov 3, 2026
caed91b
Roll third_party/libc++abi/src/ 09351f6ec..ce814c994 (6 commits)
leizleiz Nov 3, 2026
ba50ddf
Use GCed container wrappers for stack-local node collections
tsepez Nov 3, 2026
777f768
Update gn_version to 972691e86ce4828aaca38b5e44d7efe947fd1fd9
leizleiz Nov 3, 2026
d67c952
Add unit tests for FaxModule, IccTransform, FlateModule, and RLE
tsepez Nov 3, 2026
3fe8d08
Update siso_version to dfc32e4edca158cff2b64a1658ee3940f0116b3a
leizleiz Nov 4, 2026
02829e8
Hold CXFA_Event pointers via Persistent vector
tsepez Nov 4, 2026
08d3057
Avoid an assert() in skia/BUILD.gn for riscv
leizleiz Nov 4, 2026
711dc44
Introduce FxDataPartitionType concept
tsepez Nov 4, 2026
1799c8d
Seed ObjectTreeTraverser from both trailer and catalog
tsepez Nov 5, 2026
6d46478
Use CJS_Runtime::BlockingScope to handle nested blocking calls
tsepez Nov 5, 2026
892b0f3
Support in-class IsDataPartitionSafe member in FxDataPartitionType
tsepez Nov 5, 2026
c75f0bd
Rework FX_DATA_PARTITION_EXCEPTION macro
tsepez Nov 5, 2026
13af78b
Fix riscv64 build error for cstretchengine_hwy.cpp
kxxt Nov 5, 2026
9976ca5
Add BlockingScope in AlertIfPossible()
tsepez Nov 5, 2026
77b522a
Use FixedSizeDataVector in cfx_dibbase_skia.cpp
leizleiz Nov 5, 2026
82a14a9
Remove src_left and src_top from CFX_DIBBase::ConvertBuffer()
leizleiz Nov 5, 2026
c7348a4
Guard JSPLATFORM dialog call-outs with in_active_ffi_callback_
tsepez Nov 5, 2026
b3c6c6f
Fix UNSAFE_TODO() in CreateSkiaImageFromTransformedDib()
leizleiz Nov 5, 2026
5a31c5c
Improve libyuv path in CFX_DIBBase::SwapXY()
leizleiz Nov 5, 2026
4f93283
Enforce geometry invariants in LibjpegScanlineDecoder::Rewind
tsepez Nov 5, 2026
9cbde18
Expand unit tests for xfa/fgas/crt
tsepez Nov 5, 2026
b153066
Improve unit tests for core/fxge
tsepez Nov 5, 2026
21d5499
Fix CFGAS_Decimal::ToDouble() precision and ParseDateTime() arguments
tsepez Nov 5, 2026
87989d7
Replace CFGAS_Decimal::operator/ with DivBy10 and DivBy100
tsepez Nov 6, 2026
30b2a20
Fix Lab ICC profile handling in IccTransform
tsepez Nov 6, 2026
3351236
Fix NameRecord parsing in CFX_CTTNameTable
tsepez Nov 6, 2026
b2887eb
Add unit tests for TIFF progressive decoding and JPX YUV conversion
tsepez Nov 6, 2026
184a2a6
Add unit test for GetMirrorChar() with supplementary-plane characters
Nov 6, 2026
03ad822
Fix GetMirrorChar() for supplementary-plane characters
Nov 6, 2026
b6ef863
Add unit tests for core/fxcrt
tsepez Nov 7, 2026
6688c57
Add embedder test for FPDF_AddInstalledFont
tsepez Nov 7, 2026
0036036
Sync S17: merge upstream PDFium up to 6688c576f (Nov 6 2026)
bobsingor Nov 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

import("//build/dotfile_settings.gni")

# This enables check_includes_strict_exceptions, which is necessary for V8 to
# pass `gn check` with `check_includes_strict = true`.
# TODO(thestig): Remove once V8 supports `check_includes_strict = true`.
import("//build/strict_deps_failures.gni")
buildconfig = "//build/config/BUILDCONFIG.gn"

# The python interpreter to use by default. On Windows, this will look
Expand Down
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Justin Pierce <brkfstmnchr@gmail.com>
Ke Liu <stackexploit@gmail.com>
Kei Kamikawa <x00.x7f.x86@gmail.com>
LN Liberda <lauren@selfisekai.rocks>
Levi Zim <rsworktech@outlook.com>
Luật Nguyễn <manhluat93.php@gmail.com>
Manuel Geißer <geisserml@gmail.com>
Matt Jolly <kangie@gentoo.org>
Expand Down
10 changes: 5 additions & 5 deletions DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling freetype
# and whatever else without interference from each other.
'freetype_revision': '891f904e2e7b4289f615598cd4b69832f87d2f3a',
'freetype_revision': '25167984d2435930f9178e8d9d2ca3bdfa71a4e7',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling GN CIPD package version
# and whatever else without interference from each other.
'gn_version': 'git_revision:841e072bef419ae1116477dc75e8c5a662c0212c',
'gn_version': 'git_revision:98f6dd2be85d0eba8f31ee3ad1def5402383cff3',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling goldctl CIPD package version
# and whatever else without interference from each other.
Expand Down Expand Up @@ -188,15 +188,15 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling libc++abi
# and whatever else without interference from each other.
'libcxxabi_revision': '09351f6ec00c2b65f2d03585ae6da07098b024dc',
'libcxxabi_revision': 'ce814c994055b107c631c310b1c668e3714c0704',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling libpng
# and whatever else without interference from each other.
'libpng_revision': '0179a807421cf96731cdfa10008bba04fda243c1',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling libunwind
# and whatever else without interference from each other.
'libunwind_revision': 'eb1ca4993b534b7d565daee144bbc7f9072b967b',
'libunwind_revision': '9e44ea2ff4f53a60c2a3d2b6f511d7bab9ab12f0',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling libyuv
# and whatever else without interference from each other.
Expand Down Expand Up @@ -240,7 +240,7 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling siso
# and whatever else without interference from each other.
'siso_version': 'git_revision:c574896b272b40aac6e44c228ee0b471ea7e3d7d',
'siso_version': 'git_revision:dfc32e4edca158cff2b64a1658ee3940f0116b3a',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling skia
# and whatever else without interference from each other.
Expand Down
10 changes: 4 additions & 6 deletions core/fpdfapi/page/cpdf_colorspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,15 +906,13 @@ void CPDF_LabCS::TranslateImageLine(pdfium::span<uint8_t> dest_span,
fxcrt::reinterpret_span<const FX_LAB_STRUCT<uint8_t>>(src_span).first(
static_cast<size_t>(pixels));
for (auto [lab_ref, bgr_ref] : fxcrt::Zip(lab_span, bgr_span)) {
const float lab[3] = {
static_cast<float>(lab_ref.lightness_star * 100) / 255.0f,
static_cast<float>(lab_ref.a_star - 128),
static_cast<float>(lab_ref.b_star - 128),
};
const FX_LAB_STRUCT<float> decoded = DecodeLab(lab_ref);
auto float_span =
fxcrt::reinterpret_span<const float>(pdfium::span_from_ref(decoded));
// Better code than the equivalent GetRGBOrZerosOnError() since that
// is implemented in a base class and can't devirtualize the GetRGB()
// call despite this class being marked final.
auto rgb = GetRGB(lab).value_or(FX_RGB_STRUCT<float>{});
auto rgb = GetRGB(float_span).value_or(FX_RGB_STRUCT<float>{});
bgr_ref.blue = static_cast<int32_t>(rgb.blue * 255);
bgr_ref.green = static_cast<int32_t>(rgb.green * 255);
bgr_ref.red = static_cast<int32_t>(rgb.red * 255);
Expand Down
4 changes: 2 additions & 2 deletions core/fpdfapi/page/cpdf_indexedcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@

#include "core/fpdfapi/page/cpdf_basedcs.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/retain_ptr.h"

class CPDF_Document;

struct IndexedColorMinMax {
static constexpr bool kIsDataPartitionSafe = true;

float min;
float max;
};
FX_DATA_PARTITION_EXCEPTION(IndexedColorMinMax);

class CPDF_IndexedCS final : public CPDF_BasedCS {
public:
Expand Down
44 changes: 30 additions & 14 deletions core/fpdfapi/parser/object_tree_traversal_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,10 @@ class ObjectTreeTraverser {
: document_(document), resolve_mode_(resolve_mode) {
const CPDF_Parser* parser = document_->GetParser();
const CPDF_Dictionary* trailer = parser ? parser->GetTrailer() : nullptr;
const CPDF_Dictionary* root = trailer ? trailer : document_->GetRoot();
const uint32_t root_object_number =
trailer ? parser->GetTrailerObjectNumber() : root->GetObjNum();
// If `root` is a trailer, then it may not have an object number, as many
// trailers are inlined.
if (root_object_number) {
referenced_objects_[root_object_number] = 1;
object_number_map_[root] = root_object_number;
if (trailer) {
EnqueueRoot(pdfium::WrapRetain(trailer),
parser->GetTrailerObjectNumber());
}

object_queue_.push(pdfium::WrapRetain(root));
seen_objects_.insert(root);
}
~ObjectTreeTraverser() = default;

Expand All @@ -58,8 +50,19 @@ class ObjectTreeTraverser {
uint32_t referenced_object_number;
};

std::vector<ReferenceEntry> GetReferenceEntries() {
std::vector<ReferenceEntry> reference_entries;
void EnqueueRoot(RetainPtr<const CPDF_Dictionary> root,
uint32_t root_object_number) {
if (!root || !seen_objects_.insert(root.Get()).second) {
return;
}
if (root_object_number) {
referenced_objects_[root_object_number] = 1;
object_number_map_[root.Get()] = root_object_number;
}
object_queue_.push(std::move(root));
}

void DrainObjectQueue(std::vector<ReferenceEntry>* reference_entries) {
while (!object_queue_.empty()) {
RetainPtr<const CPDF_Object> current_object = object_queue_.front();
object_queue_.pop();
Expand Down Expand Up @@ -104,7 +107,7 @@ class ObjectTreeTraverser {
// Unlike the other object types, CPDF_Reference can point at nullptr.
if (referenced_object) {
CHECK(referenced_object_number);
reference_entries.push_back(
reference_entries->push_back(
{ref_object_number, referenced_object_number});
PushNewObject(ref_object, referenced_object);
}
Expand All @@ -125,6 +128,19 @@ class ObjectTreeTraverser {
}
}
}
}

std::vector<ReferenceEntry> GetReferenceEntries() {
std::vector<ReferenceEntry> reference_entries;
DrainObjectQueue(&reference_entries);

// Also traverse the catalog if it was not reached from the trailer
// (e.g. if the trailer's `/Root` was missing, null, or diverged).
const CPDF_Dictionary* catalog = document_->GetRoot();
if (catalog && !pdfium::Contains(seen_objects_, catalog)) {
EnqueueRoot(pdfium::WrapRetain(catalog), catalog->GetObjNum());
DrainObjectQueue(&reference_entries);
}
return reference_entries;
}

Expand Down
5 changes: 2 additions & 3 deletions core/fpdfapi/parser/object_tree_traversal_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ enum class ObjectTreeReferenceResolveMode {
kEffectiveDocument,
};

// Traverses `document` starting with its trailer, if it has one, or starting at
// the catalog, which always exists. The trailer should have a reference to the
// catalog. The traversal avoids cycles.
// Traverses `document` starting with its trailer, if it has one, and also from
// the catalog if not reached from the trailer. The traversal avoids cycles.
//
// In `kReferenceHolder` mode, references are followed through their
// CPDF_IndirectObjectHolder. In `kEffectiveDocument` mode, references are
Expand Down
21 changes: 21 additions & 0 deletions core/fpdfapi/parser/object_tree_traversal_util_embeddertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <set>

#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_null.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "testing/embedder_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
Expand Down Expand Up @@ -110,3 +112,22 @@ TEST_F(ObjectTreeTraversalUtilEmbedderTest,
std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
EXPECT_TRUE(referenced_objects.empty());
}

TEST_F(ObjectTreeTraversalUtilEmbedderTest,
GetObjectsWithReferencesTrailerWithoutRoot) {
ASSERT_TRUE(OpenDocument("hello_world.pdf"));
CPDF_Document* doc = GetCPDFDocument(document());
doc->GetParser()->GetMutableTrailerForTesting()->SetNewFor<CPDF_Null>("Root");
std::set<uint32_t> referenced_objects = GetObjectsWithReferences(doc);
EXPECT_THAT(referenced_objects,
UnorderedElementsAreArray({1, 2, 3, 4, 5, 6}));
}

TEST_F(ObjectTreeTraversalUtilEmbedderTest,
GetObjectsWithMultipleReferencesTrailerWithoutRoot) {
ASSERT_TRUE(OpenDocument("hello_world_2_pages.pdf"));
CPDF_Document* doc = GetCPDFDocument(document());
doc->GetParser()->GetMutableTrailerForTesting()->SetNewFor<CPDF_Null>("Root");
std::set<uint32_t> referenced_objects = GetObjectsWithMultipleReferences(doc);
EXPECT_THAT(referenced_objects, UnorderedElementsAreArray({5, 6, 7}));
}
5 changes: 2 additions & 3 deletions core/fpdftext/cpdf_textpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxcrt/widestring.h"
#include "core/fxcrt/widetext_buffer.h"
Expand All @@ -26,12 +25,12 @@ class CPDF_Page;
class CPDF_TextObject;

struct TextPageCharSegment {
static constexpr bool kIsDataPartitionSafe = true;

int index;
int count;
};

FX_DATA_PARTITION_EXCEPTION(TextPageCharSegment);

class CPDF_TextPage {
public:
enum class CharType : uint8_t {
Expand Down
2 changes: 2 additions & 0 deletions core/fxcodec/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ pdfium_unittest_source_set("unittests") {
sources = [
"basic/a85_unittest.cpp",
"basic/rle_unittest.cpp",
"fax/faxmodule_unittest.cpp",
"flate/flatemodule_unittest.cpp",
"icc/icc_transform_unittest.cpp",
"image_predictors_unittest.cpp",
"jbig2/jbig2_bit_stream_unittest.cpp",
"jbig2/jbig2_image_unittest.cpp",
Expand Down
25 changes: 25 additions & 0 deletions core/fxcodec/basic/rle_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcodec/basic/basicmodule.h"
#include "core/fxcodec/data_and_bytes_consumed.h"
#include "core/fxcodec/scanlinedecoder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/span.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

Expand Down Expand Up @@ -98,3 +100,26 @@ TEST(fxcodec, RLEFullLengthInputs) {
EXPECT_THAT(result.data, ElementsAreArray(src_buf_4));
}
}

// Check that trailing leftover unmatched characters following matched runs
// are encoded properly.
TEST(fxcodec, RLELeftoverCharacter) {
const uint8_t src_buf[] = {1, 1, 2};
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf);
DataAndBytesConsumed result = RunLengthDecode(dest_buf);
EXPECT_THAT(result.data, ElementsAreArray(src_buf));
}

TEST(fxcodec, RLEScanlineDecoder) {
const uint8_t src_buf[] = {1, 1, 2};
DataVector<uint8_t> encoded = BasicModule::RunLengthEncode(src_buf);
std::unique_ptr<ScanlineDecoder> decoder =
BasicModule::CreateRunLengthDecoder(encoded, 3, 1, 1, 8);
ASSERT_TRUE(decoder);
EXPECT_EQ(3, decoder->GetWidth());
EXPECT_EQ(1, decoder->GetHeight());
pdfium::span<const uint8_t> line = decoder->GetScanline(0);
ASSERT_FALSE(line.empty());
EXPECT_THAT(line.first(3u), ElementsAreArray(src_buf));
EXPECT_GT(decoder->GetSrcOffset(), 0u);
}
Loading