Skip to content

Commit 5355e86

Browse files
authored
Fix an issue detected by OSSFuzz (#1203)
1 parent b354669 commit 5355e86

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

.github/workflows/cifuzz.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CIFuzz
2+
on: [pull_request]
3+
permissions: {}
4+
jobs:
5+
Fuzzing:
6+
runs-on: ubuntu-latest
7+
permissions:
8+
security-events: write
9+
steps:
10+
- name: Build Fuzzers
11+
id: build
12+
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
13+
with:
14+
oss-fuzz-project-name: 'dateparser'
15+
language: python
16+
- name: Run Fuzzers
17+
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
18+
with:
19+
oss-fuzz-project-name: 'dateparser'
20+
language: python
21+
fuzz-seconds: 600
22+
output-sarif: true
23+
- name: Upload Crash
24+
uses: actions/upload-artifact@v3
25+
if: failure() && steps.build.outcome == 'success'
26+
with:
27+
name: artifacts
28+
path: ./out/artifacts
29+
- name: Upload Sarif
30+
if: always() && steps.build.outcome == 'success'
31+
uses: github/codeql-action/upload-sarif@v2
32+
with:
33+
# Path to SARIF file relative to the root of the repository
34+
sarif_file: cifuzz-sarif/results.sarif
35+
checkout_path: cifuzz-sarif

dateparser/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ def _correct_for_time_frame(self, dateobj, tz):
564564
try:
565565
tz = tz or get_timezone_from_tz_string(self.settings.TIMEZONE)
566566
tz_offset = tz.utcoffset(dateobj)
567-
except pytz.UnknownTimeZoneError:
567+
except (pytz.UnknownTimeZoneError, pytz.NonExistentTimeError):
568568
tz_offset = timedelta(hours=0)
569569

570570
if "past" in self.settings.PREFER_DATES_FROM:

tests/test_clean_api.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,69 @@ def test_dates_which_match_locales_are_parsed(
111111
self.when_date_is_parsed(date_string, locales=locales)
112112
self.then_parsed_date_is(expected_date)
113113

114+
@parameterized.expand(
115+
[
116+
param(
117+
date_string="0:4",
118+
locales=["fr-PF"],
119+
languages=["en"],
120+
region="",
121+
date_formats=["%a", "%a", "%a", "%a"],
122+
expected_date=datetime(1969, 12, 31, 14, 4),
123+
)
124+
]
125+
)
126+
def test_dates_parse_utc_offset_does_not_throw(
127+
self, date_string, locales, languages, region, date_formats, expected_date
128+
):
129+
"""
130+
Bug discovered by OSSFuzz that caused an exception in pytz to halt parsing
131+
Regression test to ensure that this is not reintroduced
132+
"""
133+
self.when_date_is_parsed_with_args_and_settings(
134+
date_string,
135+
languages=languages,
136+
locales=locales,
137+
region=region,
138+
date_formats=date_formats,
139+
settings={
140+
"CACHE_SIZE_LIMIT": 1000,
141+
"DATE_ORDER": "YDM",
142+
"DEFAULT_LANGUAGES": [
143+
"mzn",
144+
"as",
145+
"af",
146+
"fur",
147+
"sr-Cyrl",
148+
"kw",
149+
"ne",
150+
"en",
151+
"vi",
152+
"teo",
153+
"sr",
154+
"cgg",
155+
],
156+
"LANGUAGE_DETECTION_CONFIDENCE_THRESHOLD": 0.18823535008398845,
157+
"NORMALIZE": True,
158+
"PARSERS": ["custom-formats", "absolute-time"],
159+
"PREFER_DATES_FROM": "past",
160+
"PREFER_DAY_OF_MONTH": "first",
161+
"PREFER_LOCALE_DATE_ORDER": True,
162+
"PREFER_MONTH_OF_YEAR": "current",
163+
"RELATIVE_BASE": datetime(
164+
year=1970, month=1, day=1, hour=0, minute=0, second=0
165+
),
166+
"REQUIRE_PARTS": [],
167+
"RETURN_AS_TIMEZONE_AWARE": False,
168+
"RETURN_TIME_AS_PERIOD": False,
169+
"SKIP_TOKENS": [],
170+
"STRICT_PARSING": False,
171+
"TIMEZONE": "America/Hermosillo",
172+
"TO_TIMEZONE": "Asia/Almaty",
173+
},
174+
)
175+
self.then_parsed_date_and_time_is(expected_date)
176+
114177
@parameterized.expand(
115178
[
116179
param(date_string="January 24, 2014", locales=["pt-AO"]),
@@ -133,6 +196,24 @@ def when_date_is_parsed(self, date_string, languages=None, locales=None):
133196
def when_date_is_parsed_with_settings(self, date_string, settings=None):
134197
self.result = dateparser.parse(date_string, settings=settings)
135198

199+
def when_date_is_parsed_with_args_and_settings(
200+
self,
201+
date_string,
202+
languages=None,
203+
locales=None,
204+
region=None,
205+
date_formats=None,
206+
settings=None,
207+
):
208+
self.result = dateparser.parse(
209+
date_string,
210+
languages=languages,
211+
locales=locales,
212+
region=region,
213+
date_formats=date_formats,
214+
settings=settings,
215+
)
216+
136217
def then_parsed_date_is(self, expected_date):
137218
self.assertEqual(
138219
self.result, datetime.combine(expected_date, datetime.min.time())

0 commit comments

Comments
 (0)