summaryrefslogtreecommitdiff
path: root/time.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2023-06-22 14:31:57 -0700
committerJeremy Evans <code@jeremyevans.net>2023-07-13 16:49:39 -0700
commit5d4fff845602872eef072e7611558b5f8762efe0 (patch)
tree9d0ddd140cd7c50ed2c8b292da3845034d8376d6 /time.c
parentd814722fb8299c4baace3e76447a55a3d5478e3a (diff)
Tighten Time.new(string) parsing
Disallow: * Only year-month * Only year-month-day * Preceding whitespace * Trailing whitespace Fixes [Bug #19293]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7974
Diffstat (limited to 'time.c')
-rw-r--r--time.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/time.c b/time.c
index d3eb4be682..f4faaf3fcf 100644
--- a/time.c
+++ b/time.c
@@ -2545,7 +2545,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
size_t ndigits;
size_t prec = NIL_P(precision) ? SIZE_MAX : NUM2SIZET(precision);
- while ((ptr < end) && ISSPACE(*ptr)) ptr++;
+ if ((ptr < end) && (ISSPACE(*ptr) || ISSPACE(*(end-1)))) {
+ rb_raise(rb_eArgError, "can't parse: %+"PRIsVALUE, str);
+ }
year = parse_int(ptr, end, &ptr, &ndigits, true);
if (NIL_P(year)) {
rb_raise(rb_eArgError, "can't parse: %+"PRIsVALUE, str);
@@ -2553,6 +2555,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
else if (ndigits < 4) {
rb_raise(rb_eArgError, "year must be 4 or more digits: %.*s", (int)ndigits, ptr - ndigits);
}
+ else if (ptr == end) {
+ goto only_year;
+ }
do {
#define peekable_p(n) ((ptrdiff_t)(n) < (end - ptr))
#define peek_n(c, n) (peekable_p(n) && ((unsigned char)ptr[n] == (c)))
@@ -2613,6 +2618,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
if (zend > zstr) {
zone = rb_str_subseq(str, zstr - begin, zend - zstr);
}
+ else if (hour == -1) {
+ rb_raise(rb_eArgError, "no time information");
+ }
if (!NIL_P(subsec)) {
/* subseconds is the last using ndigits */
static const size_t TIME_SCALE_NUMDIGITS =
@@ -2629,6 +2637,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
}
}
+only_year:
+ ;
+
struct vtm vtm = {
.wday = VTM_WDAY_INITVAL,
.yday = 0,