Speculative fix for null deref above ThrowNoDefaultPropertyException

Avoid possibility of an unterminated string or nullptr by avoiding
stringviews, since the non-view classes copy and always provide
a suitable result. Always use %ls and widestrings in wprintf()
variants, since that combination is consistent across our platforms
(%s, %S, etc. have idiosyncracies).

Bug: 870952
Change-Id: Ief62a42c3486e8298f9583b56e9333db1a74972a
Reviewed-on: https://pdfium-review.googlesource.com/39551
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 93f6b07..37d4ecd 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -1381,6 +1381,22 @@
   EXPECT_NE(L"", WideString::Format(L"unsupported char '%c'", 0x00FF00FF));
 }
 
+TEST(WideString, FormatString) {
+  // %ls and wide characters are the reliable combination across platforms.
+  EXPECT_EQ(L"", WideString::Format(L"%ls", L""));
+  EXPECT_EQ(L"", WideString::Format(L"%ls", WideString().c_str()));
+  EXPECT_EQ(L"clams", WideString::Format(L"%ls", L"clams"));
+  EXPECT_EQ(L"cla", WideString::Format(L"%.3ls", L"clams"));
+  EXPECT_EQ(L"\u043e\u043f", WideString(L"\u043e\u043f"));
+
+#if _FX_OS_ != _FX_OS_MACOSX_
+  // See https://bugs.chromium.org/p/pdfium/issues/detail?id=1132
+  EXPECT_EQ(L"\u043e\u043f", WideString::Format(L"\u043e\u043f"));
+  EXPECT_EQ(L"\u043e\u043f", WideString::Format(L"%ls", L"\u043e\u043f"));
+  EXPECT_EQ(L"\u043e", WideString::Format(L"%.1ls", L"\u043e\u043f"));
+#endif
+}
+
 TEST(WideString, Empty) {
   WideString empty_str;
   EXPECT_TRUE(empty_str.IsEmpty());
diff --git a/fxjs/cfxjse_formcalc_context.cpp b/fxjs/cfxjse_formcalc_context.cpp
index cf42fb2..4201059 100644
--- a/fxjs/cfxjse_formcalc_context.cpp
+++ b/fxjs/cfxjse_formcalc_context.cpp
@@ -6199,9 +6199,8 @@
 
 void CFXJSE_FormCalcContext::ThrowNoDefaultPropertyException(
     const ByteStringView& name) const {
-  // TODO(tsepez): check usage of c_str() below.
-  ThrowException(L"%.16S doesn't have a default property.",
-                 name.unterminated_c_str());
+  ThrowException(L"%ls doesn't have a default property.",
+                 WideString::FromUTF8(name).c_str());
 }
 
 void CFXJSE_FormCalcContext::ThrowCompilerErrorException() const {
@@ -6220,14 +6219,14 @@
     const WideString& name,
     const WideString& exp) const {
   ThrowException(
-      L"An attempt was made to reference property '%.16s' of a non-object "
-      L"in SOM expression %.16s.",
+      L"An attempt was made to reference property '%ls' of a non-object "
+      L"in SOM expression %ls.",
       name.c_str(), exp.c_str());
 }
 
 void CFXJSE_FormCalcContext::ThrowParamCountMismatchException(
     const WideString& method) const {
-  ThrowException(L"Incorrect number of parameters calling method '%.16s'.",
+  ThrowException(L"Incorrect number of parameters calling method '%ls'.",
                  method.c_str());
 }
 
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 6984c3a..23e754d 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -193,7 +193,7 @@
 
 void CJX_Object::ThrowParamCountMismatchException(
     const WideString& method) const {
-  ThrowException(L"Incorrect number of parameters calling method '%.16s'.",
+  ThrowException(L"Incorrect number of parameters calling method '%ls'.",
                  method.c_str());
 }