You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
search_dates() raises IndexError: list index out of range for the zh-Hans, zh-Hant and yue locales. It is reachable through the plainest possible call, with no languages= argument at all:
zh, ja and every other locale are unaffected, and dateparser.parse() does not crash (for these locales it returns None instead — that half is #1277).
Traceback:
dateparser/search/__init__.py:70 -> search/search.py:357
-> search/search.py:184
-> search/search.py:45
-> languages/locale.py:310
[original_tokens[i], original_tokens[i + 1]],
IndexError: list index out of range
Root cause
Two things combine in Locale.translate_search() (dateparser/languages/locale.py):
locale.py:277 — word_joint_unsupported_languages = ["zh", "ja"]. Exactly zh and ja carry a simplifications block that rewrites 年/月/日 into separators before this point; zh-Hans, zh-Hant and yue do not, so they reach the word-joining branch at locale.py:302-312 with raw CJK tokens, which the other two never do.
locale.py:291 computes next_word defensively — simplified_tokens[i + 1] if i < last_token_index else "" — but the branch it guards reads original_tokens[i + 1] at locale.py:310 with no equivalent bounds check. On the final token, current_and_next_joined can still match a dictionary entry (the joined form equals the bare word, since next_word is ""), the branch is taken, and the index overflows.
Introduced in c5f0fa4 (#953, 2021-08-09); git show c5f0fa4^:dateparser/languages/locale.py contains no i + 1 index at all.
Proposal
Add the missing bounds check to the condition at locale.py:302:
the full suite is unchanged — 24186 passed, 18 skipped, 1 xfailed, identical to baseline;
search_dates("聽日") and search_dates("舊年") now return correct results rather than merely not crashing.
Scope and considerations
Please do not fix this by adding the three locales to word_joint_unsupported_languages. I tried that: it stops the crash, but search_dates("2020年3月4日", languages=["zh-Hans"]) then returns datetime(6, 5, 27) — silent garbage — because translate_search yields "2020yearmarch4day". That trades a loud crash for a wrong date.
Regression tests cover zh-Hans, zh-Hant and yue in tests/test_search.py, which currently contains zero references to any of the three (grep -c 'zh-Han\|yue' tests/test_search.py → 0) — which is how this survived four and a half years.
Problem
search_dates()raisesIndexError: list index out of rangefor thezh-Hans,zh-Hantandyuelocales. It is reachable through the plainest possible call, with nolanguages=argument at all:It also fires whenever one of the three locales is requested explicitly, including in a mixed language list, and including for plain ASCII input:
zh,jaand every other locale are unaffected, anddateparser.parse()does not crash (for these locales it returnsNoneinstead — that half is #1277).Traceback:
Root cause
Two things combine in
Locale.translate_search()(dateparser/languages/locale.py):locale.py:277—word_joint_unsupported_languages = ["zh", "ja"]. Exactlyzhandjacarry asimplificationsblock that rewrites年/月/日into separators before this point;zh-Hans,zh-Hantandyuedo not, so they reach the word-joining branch atlocale.py:302-312with raw CJK tokens, which the other two never do.locale.py:291computesnext_worddefensively —simplified_tokens[i + 1] if i < last_token_index else ""— but the branch it guards readsoriginal_tokens[i + 1]atlocale.py:310with no equivalent bounds check. On the final token,current_and_next_joinedcan still match a dictionary entry (the joined form equals the bare word, sincenext_wordis""), the branch is taken, and the index overflows.Introduced in c5f0fa4 (#953, 2021-08-09);
git show c5f0fa4^:dateparser/languages/locale.pycontains noi + 1index at all.Proposal
Add the missing bounds check to the condition at
locale.py:302:I verified this locally:
24186 passed, 18 skipped, 1 xfailed, identical to baseline;search_dates("聽日")andsearch_dates("舊年")now return correct results rather than merely not crashing.Scope and considerations
word_joint_unsupported_languages. I tried that: it stops the crash, butsearch_dates("2020年3月4日", languages=["zh-Hans"])then returnsdatetime(6, 5, 27)— silent garbage — becausetranslate_searchyields"2020yearmarch4day". That trades a loud crash for a wrong date.zh-Hansvszhlocale data) and Issue parsing ZH-Hant locale #875 (zh-Hant). Those are data gaps that makeparse()returnNone; this is a code defect that survives them. I applied Aren't "zh" (Chinese) and "zh-Hans" (Chinese, traditional script) the same language? #1277's proposed change in-memory andsearch_dates()still raises for今天,昨天,上个月and00Z. Sensible sequencing is the bounds guard first (crash →None, matchingparse()), the data fix second (None→ correct date).2020年3月4日underzh-HansreturnsNonerather than a date. That is Aren't "zh" (Chinese) and "zh-Hans" (Chinese, traditional script) the same language? #1277's territory, not a regression from this change.Acceptance criteria
IndexError.zh-Hans,zh-Hantandyueintests/test_search.py, which currently contains zero references to any of the three (grep -c 'zh-Han\|yue' tests/test_search.py→0) — which is how this survived four and a half years.