diff options
author | Nobuyoshi Nakada <[email protected]> | 2019-07-16 21:47:32 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2019-07-17 08:34:19 +0900 |
commit | f487e5b7a4b13d23a8bb7807e4f5cc3f9b2a30e3 (patch) | |
tree | 4032de8185e293012f8824b45d0700361a5a81ad /time.c | |
parent | ed2f2b4f98800540024b9c4a5ebde98674889013 (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.c | 15 |
1 files changed, 9 insertions, 6 deletions
@@ -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)) { |