Better test for AFSpecial_KeystrokeEx.

Fix potential read past end of string along the way.

Change-Id: Ic17c63f51c90c69b4277b5c81248dd2556ac54b5
Reviewed-on: https://pdfium-review.googlesource.com/c/44890
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index fcafea4..e412c70 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -1400,13 +1400,19 @@
     if (valEvent.IsEmpty())
       return CJS_Result::Success();
 
-    size_t iIndexMask = 0;
-    for (; iIndexMask < valEvent.GetLength(); ++iIndexMask) {
-      if (!MaskSatisfied(valEvent[iIndexMask], wstrMask[iIndexMask]))
+    if (valEvent.GetLength() > wstrMask.GetLength()) {
+      AlertIfPossible(pContext,
+                      JSGetStringFromID(JSMessage::kParamTooLongError));
+      pEvent->Rc() = false;
+      return CJS_Result::Success();
+    }
+
+    size_t iIndex = 0;
+    for (iIndex = 0; iIndex < valEvent.GetLength(); ++iIndex) {
+      if (!MaskSatisfied(valEvent[iIndex], wstrMask[iIndex]))
         break;
     }
-    if (iIndexMask != wstrMask.GetLength() ||
-        (iIndexMask != valEvent.GetLength() && wstrMask.GetLength() != 0)) {
+    if (iIndex != wstrMask.GetLength()) {
       AlertIfPossible(pContext,
                       JSGetStringFromID(JSMessage::kInvalidInputError));
       pEvent->Rc() = false;
diff --git a/testing/resources/javascript/public_methods.in b/testing/resources/javascript/public_methods.in
index 0779767..61505be 100644
--- a/testing/resources/javascript/public_methods.in
+++ b/testing/resources/javascript/public_methods.in
@@ -217,7 +217,12 @@
       app.alert("**********************");
 
       expectError(undefined, "AFSpecial_KeystrokeEx()", undefined);
-      expectEventValue("12", "AFSpecial_KeystrokeEx('999999')", "12");
+      expectEventValue("12345", "AFSpecial_KeystrokeEx('')", "12345");      // No notification.
+      expectEventValue("123", "AFSpecial_KeystrokeEx('9999')", "123");      // Notifies invalid.
+      expectEventValue("12345", "AFSpecial_KeystrokeEx('9999')", "12345");  // Notifies too long.
+      expectEventValue("abcd", "AFSpecial_KeystrokeEx('9999')", "abcd");    // Notifies invalid.
+      expectEventValue("1234", "AFSpecial_KeystrokeEx('9999')", "1234");
+      expectEventValue("abcd", "AFSpecial_KeystrokeEx('XXXX')", "abcd");
 
       app.alert("**********************");
 
diff --git a/testing/resources/javascript/public_methods_expected.txt b/testing/resources/javascript/public_methods_expected.txt
index 48928f5..36df38c 100644
--- a/testing/resources/javascript/public_methods_expected.txt
+++ b/testing/resources/javascript/public_methods_expected.txt
@@ -91,8 +91,15 @@
 Alert: PASS: AFSpecial_Keystroke(65) = abc
 Alert: **********************
 Alert: PASS: AFSpecial_KeystrokeEx() threw AFSpecial_KeystrokeEx: Incorrect number of parameters passed to function.
+Alert: PASS: AFSpecial_KeystrokeEx('') = 12345
 [icon=3,type=0]: The input value is invalid.
-Alert: PASS: AFSpecial_KeystrokeEx('999999') = 12
+Alert: PASS: AFSpecial_KeystrokeEx('9999') = 123
+[icon=3,type=0]: The input value is too long.
+Alert: PASS: AFSpecial_KeystrokeEx('9999') = 12345
+[icon=3,type=0]: The input value is invalid.
+Alert: PASS: AFSpecial_KeystrokeEx('9999') = abcd
+Alert: PASS: AFSpecial_KeystrokeEx('9999') = 1234
+Alert: PASS: AFSpecial_KeystrokeEx('XXXX') = abcd
 Alert: **********************
 Alert: PASS: AFTime_Format() threw AFTime_Format: Incorrect number of parameters passed to function.
 Alert: PASS: AFTime_Format(1, 2) threw AFTime_Format: Incorrect number of parameters passed to function.