Skip to content

Commit e0cf7fa

Browse files
authored
Merge pull request #7746 from amatsuda/integer-radix-check
mruby-kernel-ext: Integer() with exception: false still raises on an illegal radix
2 parents 88416fc + 418e714 commit e0cf7fa

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

‎mrbgems/mruby-kernel-ext/src/kernel.c‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,27 @@ no_exception_p(mrb_state *mrb, const mrb_value *kw_values)
214214
return !mrb_undef_p(kw_values[0]) && !mrb_test(kw_values[0]);
215215
}
216216

217+
/* An illegal radix is a mistake in the call, not a conversion that failed,
218+
so exception: false does not turn it into nil: the same error the string
219+
conversion would raise, raised before the guard. What that conversion
220+
takes: 0 and -1 let the string's prefix choose the radix, and a negative
221+
radix is the positive one with no prefix allowed. */
222+
static void
223+
check_radix(mrb_state *mrb, mrb_int base)
224+
{
225+
mrb_int b = base;
226+
227+
if (b == 0 || b == -1) return;
228+
if (b < -MRB_INT_MAX) {
229+
/* MRB_INT_MIN: negating it would overflow mrb_int */
230+
mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
231+
}
232+
if (b < 0) b = -b;
233+
if (b < 2 || 36 < b) {
234+
mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", b);
235+
}
236+
}
237+
217238
static mrb_value
218239
mrb_f_integer(mrb_state *mrb, mrb_value self)
219240
{
@@ -226,6 +247,8 @@ mrb_f_integer(mrb_state *mrb, mrb_value self)
226247
mrb_get_args(mrb, "o|i:", &a.val, &a.base, &kwargs);
227248
if (no_exception_p(mrb, kw_values)) {
228249
mrb_bool error;
250+
251+
if (mrb_string_p(a.val)) check_radix(mrb, a.base);
229252
mrb_value ret = mrb_protect_error(mrb, integer_body, &a, &error);
230253
if (error) {
231254
mrb->exc = NULL;

‎mrbgems/mruby-kernel-ext/test/kernel.rb‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,23 @@ def m1; __callee__ end
214214
assert_equal 12, Integer("12", exception: false)
215215
assert_nil Integer("x", exception: false)
216216
assert_nil Integer(nil, exception: false)
217-
assert_nil Integer("12", 1, exception: false)
217+
assert_nil Integer("12", 2, exception: false)
218+
assert_equal 7, Integer("111", -2, exception: false)
219+
assert_equal 12, Integer("12", 0, exception: false)
220+
assert_equal 12, Integer("12", -1, exception: false)
218221
assert_equal 12, Integer("12", exception: true)
219222
assert_raise(ArgumentError) { Integer("x", exception: true) }
220223
end
221224

225+
assert('Kernel#Integer with exception: false still raises on an illegal radix') do
226+
assert_raise(ArgumentError) { Integer("12", 1, exception: false) }
227+
assert_raise(ArgumentError) { Integer("12", 37, exception: false) }
228+
assert_raise(ArgumentError) { Integer("12", -37, exception: false) }
229+
# a radix given for a non-String is a conversion that fails
230+
assert_nil Integer(12, 1, exception: false)
231+
assert_nil Integer(12, 10, exception: false)
232+
end
233+
222234
assert('Kernel#Float with exception: false') do
223235
skip unless Object.const_defined?(:Float)
224236
assert_equal 1.5, Float("1.5", exception: false)

0 commit comments

Comments
 (0)