summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--ext/syck/rubyext.c25
-rw-r--r--version.h2
3 files changed, 33 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 19dc0c64aa..4ee38babc6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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));
}
}
diff --git a/version.h b/version.h
index 17db633e47..af471be86a 100644
--- a/version.h
+++ b/version.h
@@ -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