Convert floats to string better in CPDF_Number::WriteTo()
The existing implementation of CPDF_Number::WriteTo() for floats results
in strings that cannot be represented as a float (due to precision
error) and has certain restrictions (constrained within integer min/max
bounds, only a certain number of significant digits). These restrictions
are unnecessary for writing to PDFs and are not part of the PDF
specification. They are also causing slight miscalculations in PDFs.
Change to use WriteFloat() instead, which will write the float value to
string as-is with all necessary digits.
To use WriteFloat() in core/fpdfapi/parser, split it into its own build
target to avoid circular dependencies.
Some tests have floats in PDFs that change slightly with the new string
representation, so modify their checksums or values. The overall PDF
should not have any noticeable change.
Bug: 352496170
Change-Id: I93539341dc2eee9739db02dd8923d5ed857b8601
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/124272
Commit-Queue: Andy Phan <andyphan@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index abf055f..1d1acce 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -70,6 +70,7 @@
"../constants",
"../core/fdrm",
"../core/fpdfapi/edit",
+ "../core/fpdfapi/edit:contentstream_write_utils",
"../core/fpdfapi/font",
"../core/fpdfapi/page",
"../core/fpdfapi/parser",
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 147d6fa..21fd3c7 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -1177,17 +1177,17 @@
const char* md5_new_annot = []() {
if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
#if BUILDFLAG(IS_WIN)
- return "2fb4dde3342a5bec5acb2999bf3add15";
+ return "9ca0a274d1ae0db09ad814ee455dd88c";
#elif BUILDFLAG(IS_APPLE)
- return "0ca554e90329a46fc26f637c5218ebeb";
+ return "71c8fb8eee9720c19851c48745dde152";
#else
- return "6556da390ee2f3ca95ff9a6b8506ca74";
+ return "f522e1262f487cc1976bb3fc585ef469";
#endif
}
#if BUILDFLAG(IS_APPLE)
- return "55dab4f158fdc284e439b88c4306373c";
+ return "e6015f42eb81ed6003224cb2f27dcb51";
#else
- return "cc08493b1f079803930388ecc703be9d";
+ return "2e567a33390cd2ebad9dc33d82a8b054";
#endif
}();
@@ -1403,17 +1403,17 @@
const char* md5_modified_image = []() {
if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
#if BUILDFLAG(IS_WIN)
- return "1c9c1d10d541a40bf65ea4df514d21aa";
+ return "aeb7cfb0bf6ac2bcdef4412276f3bad4";
#elif BUILDFLAG(IS_APPLE)
- return "78b93a22fa6c5e43dcd857e761146078";
+ return "5beae8949ee6b5c99fe17475e90aea02";
#else
- return "355af7d15348cef766fa5bc6bd1f108b";
+ return "cfa8aa132250a1c0fec505bd13c15916";
#endif
}
#if BUILDFLAG(IS_APPLE)
- return "ce68959f74242d588af7fb82be5ba0ab";
+ return "25bf5ec7c197cf9ff3d12b41fc336b25";
#else
- return "425646a517a23104b9ef22881a19b3e2";
+ return "dcb492d8e32528dd81bb60fa5bc900f8";
#endif
}();
@@ -1655,17 +1655,17 @@
const char* md5 = []() {
if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
#if BUILDFLAG(IS_WIN)
- return "3b64690a2b112f79513a2229c684f3c2";
+ return "25b2a610cab9d656b9ab5f72746c9e2e";
#elif BUILDFLAG(IS_APPLE)
- return "f54ac1bff1711de04498692beb5650dd";
+ return "0f6501f8e22441630bdd535363c93e59";
#else
- return "e9fcb7a0f6c16c7f6ecab4d2165808f3";
+ return "1814140b1a9a9776546af7894e21d17f";
#endif
}
#if BUILDFLAG(IS_APPLE)
- return "52e93c54796f7f7167edf64e81d12bd7";
+ return "0521eaa52fe2aa43aafd3e4495f63f0b";
#else
- return "5143f9a98beb7b00ff40b89110a1089f";
+ return "5f19ddad9d48f5b7b87ee7d92f577db6";
#endif
}();
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index b43e209..9025e6b 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -594,24 +594,33 @@
EXPECT_TRUE(FPDFPath_BezierTo(blue_path, 375, 330, 390, 360, 400, 400));
EXPECT_TRUE(FPDFPath_Close(blue_path));
FPDFPage_InsertObject(page, blue_path);
- const char* last_checksum = []() {
- if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
- return "ed14c60702b1489c597c7d46ece7f86d";
- }
- return "9823e1a21bd9b72b6a442ba4f12af946";
- }();
{
+ const char* blue_path_checksum = []() {
+ if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
+ return "ed14c60702b1489c597c7d46ece7f86d";
+ }
+ return "9823e1a21bd9b72b6a442ba4f12af946";
+ }();
ScopedFPDFBitmap page_bitmap = RenderPage(page);
- CompareBitmap(page_bitmap.get(), 612, 792, last_checksum);
+ CompareBitmap(page_bitmap.get(), 612, 792, blue_path_checksum);
}
- // Now save the result, closing the page and document
+ // Now save the result, closing the page and document.
EXPECT_TRUE(FPDFPage_GenerateContent(page));
EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
FPDF_ClosePage(page);
- // Render the saved result
- VerifySavedDocument(612, 792, last_checksum);
+ // Render the saved result. The checksum will change due to floating point
+ // precision error.
+ {
+ const char* last_checksum = []() {
+ if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
+ return "423b20c18c177e78c93d8b67594e49f1";
+ }
+ return "111c38e9bf9e2ba0a57b875cca596fff";
+ }();
+ VerifySavedDocument(612, 792, last_checksum);
+ }
}
TEST_F(FPDFEditEmbedderTest, ClipPath) {
diff --git a/fpdfsdk/fpdf_save_embeddertest.cpp b/fpdfsdk/fpdf_save_embeddertest.cpp
index e404e79..e3d8947 100644
--- a/fpdfsdk/fpdf_save_embeddertest.cpp
+++ b/fpdfsdk/fpdf_save_embeddertest.cpp
@@ -152,7 +152,7 @@
EXPECT_THAT(GetString(), HasSubstr("36 0 obj"));
EXPECT_THAT(GetString(), Not(HasSubstr("37 0 obj")));
EXPECT_THAT(GetString(), Not(HasSubstr("38 0 obj")));
- EXPECT_EQ(7908u, GetString().size());
+ EXPECT_EQ(7996u, GetString().size());
// Make sure new document renders the same as the old one.
ASSERT_TRUE(OpenSavedDocument());