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