Speed up stringformatter fuzzer.

Fix locale name (zh, not cz).
Limit string size as big strings are unlikely to help.
Create invariant resources once at startup rather than per input.
Switch on test case, this may be more efficient that running all
tests on all input, allowing the coverage guidance to be more specific.

In particular, having a static set of locale managers gives about a
10x speedup.

Change-Id: I7034e60adac0a4d056862d4307e1fee73a13c503
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52251
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/testing/fuzzers/pdf_cfgas_stringformatter_fuzzer.cc b/testing/fuzzers/pdf_cfgas_stringformatter_fuzzer.cc
index 8c71bcf..bb1d064 100644
--- a/testing/fuzzers/pdf_cfgas_stringformatter_fuzzer.cc
+++ b/testing/fuzzers/pdf_cfgas_stringformatter_fuzzer.cc
@@ -13,7 +13,7 @@
 
 namespace {
 
-const wchar_t* const kLocales[] = {L"en", L"fr", L"jp", L"cz"};
+const wchar_t* const kLocales[] = {L"en", L"fr", L"jp", L"zh"};
 const FX_DATETIMETYPE kTypes[] = {FX_DATETIMETYPE_Date, FX_DATETIMETYPE_Time,
                                   FX_DATETIMETYPE_DateTime,
                                   FX_DATETIMETYPE_TimeDate};
@@ -21,13 +21,21 @@
 }  // namespace
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  if (size < 4)
+  if (size < 5 || size > 128)  // Big strings are unlikely to help.
     return 0;
 
-  uint8_t locale_selector = data[0] % FX_ArraySize(kLocales);
-  uint8_t type_selector = data[1] % FX_ArraySize(kTypes);
-  data += 2;
-  size -= 2;
+  // Static for speed.
+  static std::vector<std::unique_ptr<CXFA_LocaleMgr>> mgrs;
+  if (mgrs.empty()) {
+    for (const auto* locale : kLocales)
+      mgrs.push_back(pdfium::MakeUnique<CXFA_LocaleMgr>(nullptr, locale));
+  }
+
+  uint8_t test_selector = data[0] % 3;
+  uint8_t locale_selector = data[1] % FX_ArraySize(kLocales);
+  uint8_t type_selector = data[2] % FX_ArraySize(kTypes);
+  data += 3;
+  size -= 3;
 
   size_t pattern_len = size / 2;
   size_t value_len = size - pattern_len;
@@ -36,11 +44,18 @@
   WideString value =
       WideString::FromLatin1(ByteStringView(data + pattern_len, value_len));
   WideString result;
-  auto mgr =
-      pdfium::MakeUnique<CXFA_LocaleMgr>(nullptr, kLocales[locale_selector]);
-  auto fmt = pdfium::MakeUnique<CFGAS_StringFormatter>(mgr.get(), pattern);
-  fmt->FormatText(value, &result);
-  fmt->FormatNum(value, &result);
-  fmt->FormatDateTime(value, kTypes[type_selector], &result);
+  auto fmt = pdfium::MakeUnique<CFGAS_StringFormatter>(
+      mgrs[locale_selector].get(), pattern);
+  switch (test_selector) {
+    case 0:
+      fmt->FormatText(value, &result);
+      break;
+    case 1:
+      fmt->FormatNum(value, &result);
+      break;
+    case 2:
+      fmt->FormatDateTime(value, kTypes[type_selector], &result);
+      break;
+  }
   return 0;
 }