• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "xfa/fgas/crt/cfgas_stringformatter.h"
6 
7 #include <stdint.h>
8 
9 #include <iterator>
10 
11 #include "core/fxcrt/cfx_datetime.h"
12 #include "core/fxcrt/compiler_specific.h"
13 #include "core/fxcrt/fx_string.h"
14 #include "public/fpdfview.h"
15 #include "testing/fuzzers/pdfium_fuzzer_util.h"
16 #include "testing/fuzzers/xfa_process_state.h"
17 #include "v8/include/cppgc/heap.h"
18 #include "v8/include/cppgc/persistent.h"
19 #include "xfa/fxfa/parser/cxfa_localemgr.h"
20 
21 namespace {
22 
23 const wchar_t* const kLocales[] = {L"en", L"fr", L"jp", L"zh"};
24 const CFGAS_StringFormatter::DateTimeType kTypes[] = {
25     CFGAS_StringFormatter::DateTimeType::kDate,
26     CFGAS_StringFormatter::DateTimeType::kTime,
27     CFGAS_StringFormatter::DateTimeType::kDateTime,
28     CFGAS_StringFormatter::DateTimeType::kTimeDate};
29 
30 }  // namespace
31 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)32 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
33   if (size < 5 || size > 128)  // Big strings are unlikely to help.
34     return 0;
35 
36   auto* state = static_cast<XFAProcessState*>(FPDF_GetFuzzerPerProcessState());
37   cppgc::Heap* heap = state->GetHeap();
38 
39   uint8_t test_selector = data[0] % 10;
40   uint8_t locale_selector = data[1] % std::size(kLocales);
41   uint8_t type_selector = data[2] % std::size(kTypes);
42   data += 3;
43   size -= 3;
44 
45   size_t pattern_len = size / 2;
46   size_t value_len = size - pattern_len;
47   WideString pattern =
48       WideString::FromLatin1(UNSAFE_TODO(ByteStringView(data, pattern_len)));
49   WideString value = WideString::FromLatin1(
50       UNSAFE_TODO(ByteStringView(data + pattern_len, value_len)));
51 
52   auto fmt = std::make_unique<CFGAS_StringFormatter>(pattern);
53 
54   WideString result;
55   CFX_DateTime dt;
56   switch (test_selector) {
57     case 0:
58       fmt->FormatText(value, &result);
59       break;
60     case 1: {
61       auto* mgr = cppgc::MakeGarbageCollected<CXFA_LocaleMgr>(
62           heap->GetAllocationHandle(), heap, nullptr,
63           kLocales[locale_selector]);
64       fmt->FormatNum(mgr, value, &result);
65       break;
66     }
67     case 2: {
68       auto* mgr = cppgc::MakeGarbageCollected<CXFA_LocaleMgr>(
69           heap->GetAllocationHandle(), heap, nullptr,
70           kLocales[locale_selector]);
71       fmt->FormatDateTime(mgr, value, kTypes[type_selector], &result);
72       break;
73     }
74     case 3: {
75       fmt->FormatNull(&result);
76       break;
77     }
78     case 4: {
79       fmt->FormatZero(&result);
80       break;
81     }
82     case 5: {
83       fmt->ParseText(value, &result);
84       break;
85     }
86     case 6: {
87       auto* mgr = cppgc::MakeGarbageCollected<CXFA_LocaleMgr>(
88           heap->GetAllocationHandle(), heap, nullptr,
89           kLocales[locale_selector]);
90       fmt->ParseNum(mgr, value, &result);
91       break;
92     }
93     case 7: {
94       auto* mgr = cppgc::MakeGarbageCollected<CXFA_LocaleMgr>(
95           heap->GetAllocationHandle(), heap, nullptr,
96           kLocales[locale_selector]);
97       fmt->ParseDateTime(mgr, value, kTypes[type_selector], &dt);
98       break;
99     }
100     case 8: {
101       fmt->ParseNull(value);
102       break;
103     }
104     case 9: {
105       fmt->ParseZero(value);
106       break;
107     }
108   }
109   state->ForceGCAndPump();
110   return 0;
111 }
112