Make WideString's FromUTF16LE(), FromUTF16BE() take bytes, not wchar_t

This allows callers to pass-in UTF-16 data that's possibly not
2-byte aligned, and seems to be what most of the callers want too.

With this, we'll be able to use this in PDF_DecodeText.

No intended behavior change.

Change-Id: I2095c49b98646a33b21342fe4289c0436f8447b9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/113950
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Auto-Submit: Nico Weber <thakis@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index 075e43e..a063f16 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -154,8 +154,8 @@
   if (nActualLen <= 0 || nActualLen > nRequiredLen)
     return WideString();
 
-  return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
-                                 nActualLen / sizeof(uint16_t));
+  return WideString::FromUTF16LE(
+      {pBuff.data(), static_cast<size_t>(nActualLen)});
 #else   // PDF_ENABLE_XFA
   return WideString();
 #endif  // PDF_ENABLE_XFA
@@ -176,8 +176,8 @@
   if (nActualLen <= 0 || nActualLen > nRequiredLen)
     return WideString();
 
-  return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
-                                 nActualLen / sizeof(uint16_t));
+  return WideString::FromUTF16LE(
+      {pBuff.data(), static_cast<size_t>(nActualLen)});
 #else   // PDF_ENABLE_XFA
   return WideString();
 #endif  // PDF_ENABLE_XFA
@@ -570,8 +570,8 @@
       AsFPDFWideString(&bsHeader), &response);
 
   WideString wsRet =
-      WideString::FromUTF16LE(reinterpret_cast<FPDF_WIDESTRING>(response.str),
-                              response.len / sizeof(FPDF_WCHAR));
+      WideString::FromUTF16LE({reinterpret_cast<const uint8_t*>(response.str),
+                               static_cast<size_t>(response.len)});
 
   FPDF_BStr_Clear(&response);
   return wsRet;
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index c548420..4d5020f 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -210,8 +210,8 @@
 }
 
 WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
-  return WideString::FromUTF16LE(wide_string,
-                                 WideString::WStringLength(wide_string));
+  return WideString::FromUTF16LE({reinterpret_cast<const uint8_t*>(wide_string),
+                                  WideString::WStringLength(wide_string) * 2});
 }
 
 #ifdef PDF_ENABLE_XFA
diff --git a/fpdfsdk/fpdf_formfill_embeddertest.cpp b/fpdfsdk/fpdf_formfill_embeddertest.cpp
index 71bede8..c35c785 100644
--- a/fpdfsdk/fpdf_formfill_embeddertest.cpp
+++ b/fpdfsdk/fpdf_formfill_embeddertest.cpp
@@ -133,12 +133,12 @@
     ASSERT_NE(actual_len, 0U);
     ASSERT_LT(actual_len, 1000U);
 
-    std::vector<unsigned short> buf(actual_len);
+    std::vector<uint8_t> buf(actual_len);
     ASSERT_EQ(actual_len, FORM_GetSelectedText(form_handle(), page_, buf.data(),
                                                actual_len));
 
-    int num_chars = (actual_len / sizeof(unsigned short)) - 1;
-    EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
+    EXPECT_EQ(expected_string,
+              WideString::FromUTF16LE({buf.data(), actual_len - 2}));
   }
 
   void FocusOnPoint(const CFX_PointF& point) {
@@ -151,12 +151,12 @@
     ASSERT_NE(actual_len, 0U);
     ASSERT_LT(actual_len, 1000U);
 
-    std::vector<unsigned short> buf(actual_len);
+    std::vector<uint8_t> buf(actual_len);
     ASSERT_EQ(actual_len, FORM_GetFocusedText(form_handle(), page_, buf.data(),
                                               actual_len));
 
-    int num_chars = (actual_len / sizeof(unsigned short)) - 1;
-    EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
+    EXPECT_EQ(expected_string,
+              WideString::FromUTF16LE({buf.data(), actual_len - 2}));
   }
 
   void CheckCanUndo(bool expected_result) {
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 1271fbd..75f9e06 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -364,17 +364,16 @@
     return WideString();
 
   constexpr int kMaxWideChars = 1024;
-  FixedZeroedDataVector<uint16_t> buffer(kMaxWideChars);
-  pdfium::span<uint16_t> buffer_span = buffer.writable_span();
+  constexpr int kMaxBytes = kMaxWideChars * sizeof(uint16_t);
+  FixedZeroedDataVector<uint8_t> buffer(kMaxBytes);
+  pdfium::span<uint8_t> buffer_span = buffer.writable_span();
   int byte_length = m_pFormFillEnv->JS_appResponse(
-      wsQuestion, wsTitle, wsDefaultAnswer, WideString(), bMark,
-      pdfium::as_writable_bytes(buffer_span));
+      wsQuestion, wsTitle, wsDefaultAnswer, WideString(), bMark, buffer_span);
   if (byte_length <= 0)
     return WideString();
 
-  buffer_span = buffer_span.first(
-      std::min<size_t>(kMaxWideChars, byte_length / sizeof(uint16_t)));
-  return WideString::FromUTF16LE(buffer_span.data(), buffer_span.size());
+  buffer_span = buffer_span.first(std::min<size_t>(kMaxBytes, byte_length));
+  return WideString::FromUTF16LE(buffer_span);
 }
 
 RetainPtr<IFX_SeekableReadStream> CPDFXFA_Context::DownloadURL(
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index ff93008..8800a0c 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -503,9 +503,7 @@
         continue;
       }
       if (i == pArray->size() - 1) {
-        WideString wPath = WideString::FromUTF16LE(
-            reinterpret_cast<const unsigned short*>(bs.c_str()),
-            bs.GetLength() / sizeof(unsigned short));
+        WideString wPath = WideString::FromUTF16LE(bs.raw_span());
         ByteString bPath = wPath.ToUTF8();
         static const char kFormat[] =
             "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";