diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | ext/syck/rubyext.c | 25 | ||||
-rw-r--r-- | version.h | 2 |
3 files changed, 33 insertions, 13 deletions
@@ -1,3 +1,22 @@ +Fri May 6 15:01:11 2011 URABE Shyouhei <shyouhei@ruby-lang.org> + + * ext/syck/rubyext.c (mktime_do): avoid buffer overrun, by + silently ignoring lesser significant digits. Required buffer + length can be computable so you might at first think of + allocating enough memory space on the fly using alloca(). That + is a wrong idea because when using alloca there is always risk + of integer overflow. A function that accepts outer-process + resources like this should not blindly trust its inputs. In + this particular case we just want to generate miliseconds + resolution by strtod() so the string in question needs no more + length than what we originally have. Ignoring lesser + significant digits should suffice I believe. + +Fri May 6 14:25:53 2011 Tinco Andringa <mail@tinco.nl> + + * ext/syck/rubyext.c (mktime_do): YAML.load time correctly parse + usecs smaller than 1 fixes #4571 + Thu May 5 17:36:31 2011 CHIKANAGA Tomoyuki <nagachika00@gmail.com> * eval.c (frame_func_id): store result of method_entry_of_iseq() to diff --git a/ext/syck/rubyext.c b/ext/syck/rubyext.c index af52976ff1..1be472e040 100644 --- a/ext/syck/rubyext.c +++ b/ext/syck/rubyext.c @@ -225,7 +225,7 @@ mktime_do(struct mktime_arg *arg) VALUE hour = INT2FIX(0); VALUE min = INT2FIX(0); VALUE sec = INT2FIX(0); - long usec; + double usec; /* Year*/ if ( ptr[0] != '\0' && len > 0 ) { @@ -271,19 +271,20 @@ mktime_do(struct mktime_arg *arg) ptr += 2; if ( len > ptr - str && *ptr == '.' ) { - char padded[] = "000000"; - char *end = ptr + 1; - char *p = end; + char padded[] = "000000.000000"; + const int padding = 6; + const int offset = padding + 1; + const char *end = ptr + 1; + const char *begin = end; + int length; while ( isdigit( *end ) ) end++; - if (end - p < sizeof(padded)) { - MEMCPY(padded, ptr + 1, char, end - (ptr + 1)); - p = padded; - } - usec = strtol(p, NULL, 10); + length = (int)(end - begin) <= padding ? (int)(end - begin) : padding; + MEMCPY(padded, begin, char, length); + usec = strtod(padded, NULL); } else { - usec = 0; + usec = 0.0; } /* Time Zone*/ @@ -311,12 +312,12 @@ mktime_do(struct mktime_arg *arg) time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec); tmp = rb_funcall(time, s_to_i, 0); tmp = rb_funcall(tmp, '-', 1, LONG2FIX(tz_offset)); - return rb_funcall(rb_cTime, s_at, 2, tmp, LONG2NUM(usec)); + return rb_funcall(rb_cTime, s_at, 2, tmp, rb_float_new(usec)); } else { /* Make UTC time*/ - return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, LONG2NUM(usec)); + return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, rb_float_new(usec)); } } @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_PATCHLEVEL 248 +#define RUBY_PATCHLEVEL 249 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 9 #define RUBY_VERSION_TEENY 1 |