diff options
| -rw-r--r-- | src/pack.c | 20 | ||||
| -rw-r--r-- | test/pack.rb | 4 |
2 files changed, 18 insertions, 6 deletions
diff --git a/src/pack.c b/src/pack.c index 8c76b2638..ba561249e 100644 --- a/src/pack.c +++ b/src/pack.c @@ -77,7 +77,7 @@ check_little_endian(void) static unsigned int hex2int(unsigned char ch) { - if (ch >= '0' && ch <= '9') + if (ch >= '0' && ch <= '9') return ch - '0'; else if (ch >= 'A' && ch <= 'F') return 10 + (ch - 'A'); @@ -414,8 +414,12 @@ pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count, { char utf8[4]; int len; - - unsigned long c = mrb_fixnum(o); + unsigned long c = 0; + + if (mrb_float_p(o)) { + goto range_error; + } + c = mrb_fixnum(o); /* Unicode character */ /* from mruby-compiler gem */ @@ -434,17 +438,21 @@ pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count, utf8[2] = (char)(0x80 | ( c & 0x3F)); len = 3; } - else { + else if (c < 0x200000) { utf8[0] = (char)(0xF0 | (c >> 18) ); utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F)); utf8[2] = (char)(0x80 | ((c >> 6) & 0x3F)); utf8[3] = (char)(0x80 | ( c & 0x3F)); len = 4; } - + else { +range_error: + mrb_raise(mrb, E_RANGE_ERROR, "pack(U): value out of range"); + } + str = str_len_ensure(mrb, str, sidx + len); memcpy(RSTRING_PTR(str) + sidx, utf8, len); - + return len; } diff --git a/test/pack.rb b/test/pack.rb index e9f5fb040..f518ca4fa 100644 --- a/test/pack.rb +++ b/test/pack.rb @@ -158,4 +158,8 @@ assert 'pack/unpack "U"' do assert_equal "こんにちは世界", [12371, 12435, 12395, 12385, 12399, 19990, 30028].pack("U*") assert_equal "\000", [0].pack("U") + + assert_raise(RangeError) { [-0x40000000].pack("U") } + assert_raise(RangeError) { [-1].pack("U") } + assert_raise(RangeError) { [0x40000000].pack("U") } end |
