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();
+  }
+}