summaryrefslogtreecommitdiff
path: root/time.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-07-16 21:47:32 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-07-17 08:34:19 +0900
commitf487e5b7a4b13d23a8bb7807e4f5cc3f9b2a30e3 (patch)
tree4032de8185e293012f8824b45d0700361a5a81ad /time.c
parented2f2b4f98800540024b9c4a5ebde98674889013 (diff)
Expanded buf to copy at once
Build dumped string from base packed data and extended year at once. Although currently ruby_marshal_write_long() never writes more than 5 bytes per its format specification, allocate `sizeof(long)+1` for the sanitation.
Diffstat (limited to 'time.c')
-rw-r--r--time.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/time.c b/time.c
index f7808c7674..18f1b246f0 100644
--- a/time.c
+++ b/time.c
@@ -5016,7 +5016,7 @@ time_mdump(VALUE time)
{
struct time_object *tobj;
unsigned long p, s;
- char buf[base_dump_size];
+ char buf[base_dump_size + sizeof(long) + 1];
int i;
VALUE str;
@@ -5083,7 +5083,6 @@ time_mdump(VALUE time)
s = RSHIFT(s, 8);
}
- str = rb_str_new(buf, 8);
if (!NIL_P(year_extend)) {
/*
* Append extended year distance from 1900..(1900+0xffff). In
@@ -5092,18 +5091,22 @@ time_mdump(VALUE time)
* binary (like as Fixnum and Bignum).
*/
size_t ysize = rb_absint_size(year_extend, NULL);
- char *p, buf_year_extend[sizeof(long)+1];
+ char *p, *const buf_year_extend = buf + base_dump_size;
if (ysize > LONG_MAX ||
(i = ruby_marshal_write_long((long)ysize, buf_year_extend)) < 0) {
rb_raise(rb_eArgError, "year too %s to marshal: %"PRIsVALUE" UTC",
(year == 1900 ? "small" : "big"), vtm.year);
}
- rb_str_resize(str, sizeof(buf) + i + ysize);
- p = RSTRING_PTR(str) + sizeof(buf);
- memcpy(p, buf_year_extend, i);
+ i += base_dump_size;
+ str = rb_str_new(NULL, i + ysize);
+ p = RSTRING_PTR(str);
+ memcpy(p, buf, i);
p += i;
rb_integer_pack(year_extend, p, ysize, 1, 0, INTEGER_PACK_LITTLE_ENDIAN);
}
+ else {
+ str = rb_str_new(buf, base_dump_size);
+ }
rb_copy_generic_ivar(str, time);
if (!rb_equal(nano, INT2FIX(0))) {
if (RB_TYPE_P(nano, T_RATIONAL)) {