Fix botched "CC:" parameter passing in JS_DocmailForm().

Moved onto JS_ExpandKeywordParams(), and added a test which
showed the failure to pass all the data back to the embedder.

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1645413002 .
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index 25783a8..0a9fcd3 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -332,9 +332,9 @@
                                          const FX_WCHAR* Msg) {
   if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_mail) {
     CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
-    CFX_ByteString bsCC = CFX_WideString(Subject).UTF16LE_Encode();
-    CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
     CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
+    CFX_ByteString bsCC = CFX_WideString(CC).UTF16LE_Encode();
+    CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
     CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
     FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
     FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp
index d8be575..28b31cf 100644
--- a/fpdfsdk/src/javascript/app.cpp
+++ b/fpdfsdk/src/javascript/app.cpp
@@ -533,67 +533,51 @@
                      const std::vector<CJS_Value>& params,
                      CJS_Value& vRet,
                      CFX_WideString& sError) {
-  if (params.size() < 1)
-    return FALSE;
-
-  FX_BOOL bUI = TRUE;
-  CFX_WideString cTo = L"";
-  CFX_WideString cCc = L"";
-  CFX_WideString cBcc = L"";
-  CFX_WideString cSubject = L"";
-  CFX_WideString cMsg = L"";
-
   CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Isolate* isolate = pRuntime->GetIsolate();
+  std::vector<CJS_Value> newParams =
+      JS_ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc",
+                             L"cBcc", L"cSubject", L"cMsg");
 
-  if (params[0].GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
+  if (newParams[0].GetType() == CJS_Value::VT_unknown) {
+    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+    return FALSE;
+  }
+  bool bUI = newParams[0].ToBool();
 
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
-    bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
-    cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
-    cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
-    cBcc =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
-    cSubject =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-    cMsg =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+  CFX_WideString cTo;
+  if (newParams[1].GetType() != CJS_Value::VT_unknown) {
+    cTo = newParams[1].ToCFXWideString();
   } else {
-    if (params.size() < 2)
+    if (!bUI) {
+      // cTo parameter required when UI not invoked.
+      sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
       return FALSE;
-
-    bUI = params[0].ToBool();
-    cTo = params[1].ToCFXWideString();
-
-    if (params.size() >= 3)
-      cCc = params[2].ToCFXWideString();
-    if (params.size() >= 4)
-      cBcc = params[3].ToCFXWideString();
-    if (params.size() >= 5)
-      cSubject = params[4].ToCFXWideString();
-    if (params.size() >= 6)
-      cMsg = params[5].ToCFXWideString();
+    }
   }
 
+  CFX_WideString cCc;
+  if (newParams[2].GetType() != CJS_Value::VT_unknown)
+    cCc = newParams[2].ToCFXWideString();
+
+  CFX_WideString cBcc;
+  if (newParams[3].GetType() != CJS_Value::VT_unknown)
+    cBcc = newParams[3].ToCFXWideString();
+
+  CFX_WideString cSubject;
+  if (newParams[4].GetType() != CJS_Value::VT_unknown)
+    cSubject = newParams[4].ToCFXWideString();
+
+  CFX_WideString cMsg;
+  if (newParams[5].GetType() != CJS_Value::VT_unknown)
+    cMsg = newParams[5].ToCFXWideString();
+
   pRuntime->BeginBlock();
-  pContext->GetReaderApp()->JS_docmailForm(NULL, 0, bUI, cTo.c_str(),
+  pContext->GetReaderApp()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(),
                                            cSubject.c_str(), cCc.c_str(),
                                            cBcc.c_str(), cMsg.c_str());
   pRuntime->EndBlock();
-
-  return FALSE;
+  return TRUE;
 }
 
 FX_BOOL app::launchURL(IJS_Context* cc,
@@ -612,7 +596,6 @@
   } else {
     vp << m_bRuntimeHighLight;
   }
-
   return TRUE;
 }
 
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 3ad0e62..31de532 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -211,6 +211,21 @@
   printf("Goto Page: %d\n", pageNumber);
 }
 
+void ExampleDocMail(IPDF_JSPLATFORM*,
+                    void* mailData,
+                    int length,
+                    FPDF_BOOL bUI,
+                    FPDF_WIDESTRING To,
+                    FPDF_WIDESTRING Subject,
+                    FPDF_WIDESTRING CC,
+                    FPDF_WIDESTRING BCC,
+                    FPDF_WIDESTRING Msg) {
+  printf("Mail Msg: %d, to=%ls, cc=%ls, bcc=%ls, subject=%ls, body=%ls\n", bUI,
+         GetPlatformWString(To).c_str(), GetPlatformWString(CC).c_str(),
+         GetPlatformWString(BCC).c_str(), GetPlatformWString(Subject).c_str(),
+         GetPlatformWString(Msg).c_str());
+}
+
 void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) {
   std::string feature = "Unknown";
   switch (type) {
@@ -411,6 +426,7 @@
   platform_callbacks.version = 3;
   platform_callbacks.app_alert = ExampleAppAlert;
   platform_callbacks.Doc_gotoPage = ExampleDocGotoPage;
+  platform_callbacks.Doc_mail = ExampleDocMail;
 
   FPDF_FORMFILLINFO form_callbacks;
   memset(&form_callbacks, '\0', sizeof(form_callbacks));
diff --git a/testing/resources/javascript/app_mailmsg.in b/testing/resources/javascript/app_mailmsg.in
new file mode 100644
index 0000000..990709b
--- /dev/null
+++ b/testing/resources/javascript/app_mailmsg.in
@@ -0,0 +1,72 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /Contents [21 0 R]
+  /MediaBox [0 0 612 792]
+>>
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+% JS program to exexute
+{{object 11 0}} <<
+>>
+stream
+app.alert("This test passes if mailMsg() logs output under the test utility.");
+app.mailMsg(true);
+app.mailMsg(false, "user@example.com");
+app.mailMsg(false, "user@example.com", "cc@example.com",
+            "bcc@example.com", "subject", "body");
+app.mailMsg({"bUI": true});
+app.mailMsg({"bUI": false, "cTo": "user@example.com"});
+app.mailMsg({"bUI": false,
+             "cTo": "user@example.com",
+             "cCc": "cc@example.com",
+             "cBcc": "bcc@example.com",
+             "cSubject": "subject",
+             "cMsg": "body"});
+try {
+  app.mailMsg();
+} catch (e) {
+  app.alert("Caught expected error " + e);
+}
+try {
+  app.mailMsg(false);
+} catch (e) {
+  app.alert("Caught expected error " + e);
+}
+try {
+  app.mailMsg({"color": "red", "size": 42});
+} catch (e) {
+  app.alert("Caught expected error " + e);
+}
+endstream
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/app_mailmsg_expected.txt b/testing/resources/javascript/app_mailmsg_expected.txt
new file mode 100644
index 0000000..59928ae
--- /dev/null
+++ b/testing/resources/javascript/app_mailmsg_expected.txt
@@ -0,0 +1,10 @@
+Alert: This test passes if mailMsg() logs output under the test utility.
+Mail Msg: 1, to=, cc=, bcc=, subject=, body=
+Mail Msg: 0, to=user@example.com, cc=, bcc=, subject=, body=
+Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=subject, body=body
+Mail Msg: 1, to=, cc=, bcc=, subject=, body=
+Mail Msg: 0, to=user@example.com, cc=, bcc=, subject=, body=
+Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=subject, body=body
+Alert: Caught expected error app.mailMsg: Incorrect number of parameters passed to function.
+Alert: Caught expected error app.mailMsg: Incorrect number of parameters passed to function.
+Alert: Caught expected error app.mailMsg: Incorrect number of parameters passed to function.