Fix encoding problem in FPDFAnnot_SetStringValue().
BUG=pdfium:1212
Change-Id: Ia0e58bfe7f60f8d75955b9dbb86b8333c6716ad8
Reviewed-on: https://pdfium-review.googlesource.com/c/47691
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index c288d24..2b5b3ee 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -181,6 +181,11 @@
.ToUTF8();
}
+WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
+ return WideString::FromUTF16LE(wide_string,
+ WideString::WStringLength(wide_string));
+}
+
#ifdef PDF_ENABLE_XFA
RetainPtr<IFX_SeekableStream> MakeSeekableStream(
FPDF_FILEHANDLER* pFilehandler) {
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index c4e8109..30687bf 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -208,6 +208,8 @@
ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
+WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
+
#ifdef PDF_ENABLE_XFA
inline FPDF_WIDGET FPDFWidgetFromCXFAFFWidget(CXFA_FFWidget* widget) {
return reinterpret_cast<FPDF_WIDGET>(widget);
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 43685b2..2660ccc 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -735,8 +735,7 @@
if (!pAnnotDict)
return false;
- pAnnotDict->SetNewFor<CPDF_String>(
- key, CFXByteStringFromFPDFWideString(value), false);
+ pAnnotDict->SetNewFor<CPDF_String>(key, WideStringFromFPDFWideString(value));
return true;
}
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 459d915..4c9a7f1 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
#include <cwchar>
#include <memory>
#include <string>
@@ -1544,3 +1545,63 @@
UnloadPage(page);
}
+
+TEST_F(FPDFAnnotEmbedderTest, BUG_1212) {
+ ASSERT_TRUE(OpenDocument("hello_world.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+ EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
+
+ static const char kTestKey[] = "test";
+ static constexpr wchar_t kData[] = L"\xf6\xe4";
+ std::vector<char> buf(12);
+
+ {
+ // Add a text annotation to the page.
+ ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
+ ASSERT_TRUE(annot);
+ EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
+ EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
+
+ // Make sure there is no test key, add set a value there, and read it back.
+ std::fill(buf.begin(), buf.end(), 'x');
+ ASSERT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
+ buf.size()));
+ EXPECT_STREQ(L"", BufferToWString(buf).c_str());
+
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
+ GetFPDFWideString(kData);
+ EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), kTestKey, text.get()));
+
+ std::fill(buf.begin(), buf.end(), 'x');
+ ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
+ buf.size()));
+ EXPECT_STREQ(kData, BufferToWString(buf).c_str());
+ }
+
+ UnloadPage(page);
+
+ {
+ // Save a copy, open the copy, and check the annotation again.
+ // Note that it renders the rotation.
+ EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+ OpenSavedDocument(nullptr);
+ FPDF_PAGE saved_page = LoadSavedPage(0);
+ ASSERT_TRUE(saved_page);
+
+ EXPECT_EQ(1, FPDFPage_GetAnnotCount(saved_page));
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
+ ASSERT_TRUE(annot);
+ EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
+
+ std::fill(buf.begin(), buf.end(), 'x');
+ ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
+ buf.size()));
+ EXPECT_STREQ(kData, BufferToWString(buf).c_str());
+ }
+
+ CloseSavedPage(saved_page);
+ CloseSavedDocument();
+ }
+}