diff --git a/src/string.c b/src/string.c index 1bd3f6f8f..966d7c8c9 100644 --- a/src/string.c +++ b/src/string.c @@ -2950,10 +2950,11 @@ str_bytesplice(mrb_state *mrb, mrb_value str, mrb_int idx1, mrb_int len1, mrb_va if (RSTR_LEN(s) < idx1 || RSTRING_LEN(replace) < idx2) { mrb_raise(mrb, E_INDEX_ERROR, "index out of string"); } - if (RSTR_LEN(s) <= idx1+len1) { + mrb_int n; + if (mrb_int_add_overflow(idx1, len1, &n) || RSTR_LEN(s) < n) { len1 = RSTR_LEN(s) - idx1; } - if (RSTRING_LEN(replace) <= idx2+len2) { + if (mrb_int_add_overflow(idx2, len2, &n) || RSTRING_LEN(replace) < n) { len2 = RSTRING_LEN(replace) - idx2; } if (len2 == 0) return str; diff --git a/test/t/string.rb b/test/t/string.rb index 7dbd5bca8..5fe0761f6 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -951,4 +951,8 @@ assert('String#bytesplice') do # check the object type to replace assert_raise(TypeError) { "0123456789".bytesplice(1, 1, Object.new) } + + # check the overflow to index and length (to be pass without crash) + assert_nothing_raised { "0123456789".bytesplice(8, ~(-1 << 31), "ab") } # for MRB_INT32 + assert_nothing_raised { begin; "0123456789".bytesplice(8, ~(-1 << 63), "ab"); rescue ArgumentError, RangeError; end } # for MRB_INT64 end