Coverage Report

Created: 2026-08-14 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/fuzz-test-suite/fuzztimefunctions.cpp
Line
Count
Source
1
/*
2
 Copyright (C) 2026 David Korczynski
3
4
 This file is part of QuantLib, a free-software/open-source library
5
 for financial quantitative analysts and developers - http://quantlib.org/
6
7
 QuantLib is free software: you can redistribute it and/or modify it
8
 under the terms of the QuantLib license.  You should have received a
9
 copy of the license along with this program; if not, please email
10
 <quantlib-dev@lists.sf.net>. The license is also available online at
11
 <https://www.quantlib.org/license.shtml>.
12
13
 This program is distributed in the hope that it will be useful, but WITHOUT
14
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15
 FOR A PARTICULAR PURPOSE.  See the license for more details.
16
*/
17
18
#include <ql/time/asx.hpp>
19
#include <ql/time/calendar.hpp>
20
#include <ql/time/calendars/argentina.hpp>
21
#include <ql/time/calendars/australia.hpp>
22
#include <ql/time/calendars/brazil.hpp>
23
#include <ql/time/calendars/canada.hpp>
24
#include <ql/time/calendars/china.hpp>
25
#include <ql/time/calendars/germany.hpp>
26
#include <ql/time/calendars/india.hpp>
27
#include <ql/time/calendars/japan.hpp>
28
#include <ql/time/calendars/southkorea.hpp>
29
#include <ql/time/calendars/target.hpp>
30
#include <ql/time/calendars/unitedkingdom.hpp>
31
#include <ql/time/calendars/unitedstates.hpp>
32
#include <ql/time/daycounters/actual360.hpp>
33
#include <ql/time/daycounters/actual365fixed.hpp>
34
#include <ql/time/daycounters/actualactual.hpp>
35
#include <ql/time/daycounters/business252.hpp>
36
#include <ql/time/daycounters/thirty360.hpp>
37
#include <ql/time/ecb.hpp>
38
#include <ql/time/imm.hpp>
39
#include <ql/time/schedule.hpp>
40
#include <ql/utilities/dataparsers.hpp>
41
#include <fuzzer/FuzzedDataProvider.h>
42
#include <string>
43
44
using namespace QuantLib;
45
46
6.12k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
47
6.12k
    FuzzedDataProvider fdp(data, size);
48
49
6.12k
    try {
50
        // --- Calendar operations with fuzz-selected calendar ---
51
6.12k
        Calendar calendars[] = {
52
6.12k
            TARGET(),
53
6.12k
            UnitedStates(UnitedStates::GovernmentBond),
54
6.12k
            UnitedStates(UnitedStates::NYSE),
55
6.12k
            UnitedStates(UnitedStates::FederalReserve),
56
6.12k
            UnitedKingdom(),
57
6.12k
            Germany(Germany::Eurex),
58
6.12k
            Germany(Germany::FrankfurtStockExchange),
59
6.12k
            Japan(),
60
6.12k
            China(China::SSE),
61
6.12k
            Canada(),
62
6.12k
            Australia(),
63
6.12k
            Brazil(),
64
6.12k
            India(),
65
6.12k
            SouthKorea(SouthKorea::KRX),
66
6.12k
            Argentina(),
67
6.12k
        };
68
6.12k
        auto calIdx = fdp.ConsumeIntegralInRange<int>(0, 14);
69
6.12k
        Calendar cal = calendars[calIdx];
70
71
        // Build dates from fuzz input
72
6.12k
        auto year1 = fdp.ConsumeIntegralInRange<int>(1901, 2199);
73
6.12k
        auto month1 = fdp.ConsumeIntegralInRange<int>(1, 12);
74
6.12k
        auto day1 = fdp.ConsumeIntegralInRange<int>(1, 28);
75
6.12k
        auto year2 = fdp.ConsumeIntegralInRange<int>(1901, 2199);
76
6.12k
        auto month2 = fdp.ConsumeIntegralInRange<int>(1, 12);
77
6.12k
        auto day2 = fdp.ConsumeIntegralInRange<int>(1, 28);
78
79
6.12k
        Date d1(day1, static_cast<Month>(month1), year1);
80
6.12k
        Date d2(day2, static_cast<Month>(month2), year2);
81
82
        // Exercise calendar functions
83
6.12k
        (void)cal.isBusinessDay(d1);
84
6.12k
        (void)cal.isHoliday(d1);
85
6.12k
        (void)cal.isEndOfMonth(d1);
86
6.12k
        (void)cal.endOfMonth(d1);
87
6.12k
        (void)cal.name();
88
89
6.12k
        BusinessDayConvention convs[] = {
90
6.12k
            Following, ModifiedFollowing, Preceding,
91
6.12k
            ModifiedPreceding, Unadjusted, Nearest,
92
6.12k
            HalfMonthModifiedFollowing};
93
6.12k
        auto convIdx = fdp.ConsumeIntegralInRange<int>(0, 6);
94
6.12k
        BusinessDayConvention conv = convs[convIdx];
95
96
6.12k
        (void)cal.adjust(d1, conv);
97
98
6.12k
        auto advanceDays = fdp.ConsumeIntegralInRange<int>(-365, 365);
99
6.12k
        (void)cal.advance(d1, advanceDays, Days, conv);
100
101
6.12k
        auto advanceMonths = fdp.ConsumeIntegralInRange<int>(-24, 24);
102
6.12k
        (void)cal.advance(d1, advanceMonths, Months, conv, true);
103
104
6.12k
        if (d1 < d2) {
105
2.59k
            (void)cal.businessDaysBetween(d1, d2);
106
2.59k
            (void)cal.holidayList(d1, d2);
107
2.59k
        }
108
109
        // --- Day counter operations ---
110
6.12k
        DayCounter dayCounters[] = {
111
6.12k
            Actual360(), Actual365Fixed(),
112
6.12k
            Thirty360(Thirty360::BondBasis),
113
6.12k
            Thirty360(Thirty360::EurobondBasis),
114
6.12k
            ActualActual(ActualActual::ISMA),
115
6.12k
            ActualActual(ActualActual::ISDA),
116
6.12k
            ActualActual(ActualActual::AFB),
117
6.12k
            Business252(cal)};
118
6.12k
        auto dcIdx = fdp.ConsumeIntegralInRange<int>(0, 7);
119
6.12k
        DayCounter dc = dayCounters[dcIdx];
120
121
6.12k
        if (d1 < d2) {
122
2.59k
            (void)dc.dayCount(d1, d2);
123
2.59k
            (void)dc.yearFraction(d1, d2);
124
2.59k
        }
125
126
        // --- IMM / ASX / ECB date functions ---
127
6.12k
        (void)IMM::isIMMdate(d1);
128
6.12k
        (void)IMM::nextDate(d1);
129
6.12k
        (void)ASX::isASXdate(d1);
130
6.12k
        (void)ASX::nextDate(d1);
131
6.12k
        (void)ECB::nextDate(d1);
132
133
        // --- Schedule generation ---
134
6.12k
        Frequency freqs[] = {Annual, Semiannual, Quarterly,
135
6.12k
                             Monthly, Weekly, Biweekly};
136
6.12k
        auto freqIdx = fdp.ConsumeIntegralInRange<int>(0, 5);
137
6.12k
        Frequency freq = freqs[freqIdx];
138
139
6.12k
        DateGeneration::Rule rules[] = {
140
6.12k
            DateGeneration::Backward, DateGeneration::Forward,
141
6.12k
            DateGeneration::Zero, DateGeneration::ThirdWednesday,
142
6.12k
            DateGeneration::Twentieth};
143
6.12k
        auto ruleIdx = fdp.ConsumeIntegralInRange<int>(0, 4);
144
6.12k
        DateGeneration::Rule rule = rules[ruleIdx];
145
146
6.12k
        if (d1 < d2) {
147
2.41k
            Date start = d1;
148
2.41k
            Date end = d2;
149
            // Cap the range to avoid extremely long schedules
150
2.41k
            if (end - start > 365 * 40)
151
1.42k
                end = start + 365 * 40;
152
153
2.41k
            Schedule schedule(start, end, Period(freq), cal,
154
2.41k
                              conv, conv, rule, false);
155
2.41k
            (void)schedule.size();
156
2.41k
            (void)schedule.dates();
157
2.41k
            if (schedule.size() > 0) {
158
2.32k
                (void)schedule.startDate();
159
2.32k
                (void)schedule.endDate();
160
2.32k
            }
161
2.41k
        }
162
163
        // --- Period parsing from fuzz strings ---
164
6.12k
        auto periodStr = fdp.ConsumeRandomLengthString(20);
165
6.12k
        (void)PeriodParser::parse(periodStr);
166
167
        // --- Date parsing from fuzz strings ---
168
6.12k
        auto dateStr = fdp.ConsumeRandomLengthString(30);
169
6.12k
        (void)DateParser::parseISO(dateStr);
170
6.12k
        (void)DateParser::parseFormatted(dateStr, "%Y-%m-%d");
171
172
6.12k
    } catch (const std::exception&) {
173
6.11k
    }
174
6.12k
    return 0;
175
6.12k
}