xref: /aosp_15_r20/external/pdfium/testing/fuzzers/pdf_cfgas_stringformatter_fuzzer.cc (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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