From df49bf8150ee0a6ea2a06b0d2288863b2032c932 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 30 Oct 2022 01:11:32 +0900 Subject: [ruby/date] Consider the length of string to parse https://github.com/ruby/date/commit/3bfed83ce7 --- ext/date/date_strptime.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'ext') diff --git a/ext/date/date_strptime.c b/ext/date/date_strptime.c index 7d61347c31..72d6b8a31e 100644 --- a/ext/date/date_strptime.c +++ b/ext/date/date_strptime.c @@ -60,7 +60,7 @@ num_pattern_p(const char *s) #define NUM_PATTERN_P() num_pattern_p(&fmt[fi + 1]) static long -read_digits(const char *s, VALUE *n, size_t width) +read_digits(const char *s, size_t slen, VALUE *n, size_t width) { size_t l; @@ -68,7 +68,7 @@ read_digits(const char *s, VALUE *n, size_t width) return 0; l = 0; - while (ISDIGIT(s[l])) { + while (l < slen && ISDIGIT(s[l])) { if (++l == width) break; } @@ -116,7 +116,7 @@ do { \ #define READ_DIGITS(n,w) \ do { \ size_t l; \ - l = read_digits(&str[si], &n, w); \ + l = read_digits(&str[si], slen - si, &n, w); \ if (l == 0) \ fail(); \ si += l; \ @@ -156,6 +156,14 @@ date__strptime_internal(const char *str, size_t slen, si = fi = 0; while (fi < flen) { + if (isspace((unsigned char)fmt[fi])) { + while (si < slen && isspace((unsigned char)str[si])) + si++; + while (++fi < flen && isspace((unsigned char)fmt[fi])); + continue; + } + + if (si >= slen) fail(); switch (fmt[fi]) { case '%': @@ -576,7 +584,7 @@ date__strptime_internal(const char *str, size_t slen, b = rb_backref_get(); rb_match_busy(b); - m = f_match(pat, rb_usascii_str_new2(&str[si])); + m = f_match(pat, rb_usascii_str_new(&str[si], slen - si)); if (!NIL_P(m)) { VALUE s, l, o; @@ -608,22 +616,13 @@ date__strptime_internal(const char *str, size_t slen, if (str[si] != '%') fail(); si++; - if (fi < flen) - if (str[si] != fmt[fi]) + if (fi < flen) { + if (si >= slen || str[si] != fmt[fi]) fail(); - si++; + si++; + } goto matched; } - case ' ': - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - while (isspace((unsigned char)str[si])) - si++; - fi++; - break; default: ordinal: if (str[si] != fmt[fi]) -- cgit v1.2.3