6565 dst[off_inout] = ch; \
6666 off_inout += 1 ;
6767
68- #define ABR_TO_INT (a, b, c ) (((a) << 24 ) | ((b) << 16 ) | ((c) << 8 ))
68+ #define ABR_TO_INT (a, b, c ) (((a) << 24 ) | ((b) << 16 ) | ((c) << 8 ))
6969#define ABR_TO_INT4 (a, b, c, d ) (((a) << 24 ) | ((b) << 16 ) | ((c) << 8 ) | ((d)))
7070
7171inline bool
@@ -153,7 +153,9 @@ ptime_b_int(struct exttm* dst, const char* str, off_t off)
153153}
154154
155155#define PTIME_CHECK_b (dst, str, off ) \
156- if (!ptime_b_int(dst, str, off)) { \
156+ if (str[off + 3 ] == ' .' || isalpha(str[off + 3 ]) \
157+ || !ptime_b_int(dst, str, off)) \
158+ { \
157159 off_t tmp_off = off; \
158160 if (!ptime_b_slow (dst, str, tmp_off, len)) { \
159161 off_inout = off; \
@@ -166,7 +168,17 @@ ptime_b_int(struct exttm* dst, const char* str, off_t off)
166168inline bool
167169ptime_b (exttm* dst, const char * str, off_t & off_inout, ssize_t len)
168170{
169- if (off_inout + 3 < len) {
171+ // fast path to detect english abbreviated months
172+ //
173+ // only detect english abbreviated months if they end at a word
174+ // boundary. if the abbreviated month in the current locale is longer
175+ // than 3 letters, and starts with the same letters as an english locale
176+ // month abbreviation, then the computation of off_inout is incorrect.
177+ //
178+ // Ex: in fr_FR november is `nov.`. Parsing `nov. 29` as `%b %d` fails
179+ // if this fast path is taken as later we will attempt to parse `. 29`
180+ // as ` %d`.
181+ if (off_inout + 3 < len && isspace (str[off_inout + 3 ])) {
170182 if (ptime_b_int (dst, str, off_inout)) {
171183 off_inout += 3 ;
172184 return true ;
0 commit comments