Skip to content

fix parsing dates with months abbreviated in some locales #1344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/ptimec.hh
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,17 @@ bool ptime_b_slow(struct exttm* dst,
inline bool
ptime_b(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len)
{
if (off_inout + 3 < len) {
// fast path to detect english abbreviated months
//
// only detect english abbreviated months if they end at a word boundary.
// if the abbreviated month in the current locale is longer than 3 letters,
// and starts with the same letters as an english locale month abbreviation,
// then the computation of off_inout is incorrect.
//
// Ex: in fr_FR november is `nov.`. Parsing `nov. 29` as `%b %d` fails if
// this fast path is taken as later we will attempt to parse `. 29` as
// ` %d`.
if (off_inout + 3 < len && isspace(str[off_inout+3])) {
auto month_start = (unsigned char*) &str[off_inout];
uint32_t month_int = ABR_TO_INT(month_start[0] & ~0x20UL,
month_start[1] & ~0x20UL,
Expand Down
4 changes: 4 additions & 0 deletions test/test_date_time_scanner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ TEST_CASE("date_time_scanner")
{
const char* en_date = "Jan 1 12:00:00";
const char* fr_date = "août 19 11:08:37";
const char* fr_date2 = "nov. 29 20:23:37";
struct timeval en_tv, fr_tv;
struct exttm en_tm, fr_tm;
date_time_scanner dts;
Expand All @@ -213,6 +214,9 @@ TEST_CASE("date_time_scanner")
dts.clear();
assert(dts.scan(fr_date, strlen(fr_date), nullptr, &fr_tm, fr_tv)
!= nullptr);
dts.clear();
assert(dts.scan(fr_date2, strlen(fr_date), nullptr, &fr_tm, fr_tv)
!= nullptr);
}
}

Expand Down