From c09d250ca148c0efc0167d55885bd20da87b43f7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 19 Sep 2018 20:53:32 +0900 Subject: Remove implicit conversion using `to_int` method. The ISO standard does not include implicit type conversion using `to_int`. This implicit conversion often causes vulnerability. There will be no more attacks like #4120. In addition, we have added internal convenience method `__to_int` which does type check and conversion (from floats). --- src/object.c | 57 ++++++++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) (limited to 'src/object.c') diff --git a/src/object.c b/src/object.c index 8724c5416..ba6fa3947 100644 --- a/src/object.c +++ b/src/object.c @@ -322,19 +322,6 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho return mrb_funcall_argv(mrb, val, m, 0, 0); } -MRB_API mrb_value -mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method) -{ - mrb_value v; - - if (mrb_fixnum_p(val)) return val; - v = convert_type(mrb, val, "Integer", method, FALSE); - if (mrb_nil_p(v) || !mrb_fixnum_p(v)) { - return mrb_nil_value(); - } - return v; -} - MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method) { @@ -505,25 +492,22 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) return FALSE; } -static mrb_value -mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method) -{ - mrb_value v; - - if (mrb_fixnum_p(val)) return val; - v = convert_type(mrb, val, "Integer", method, TRUE); - if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) { - mrb_value type = inspect_type(mrb, val); - mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)", - type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v)); - } - return v; -} - MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val) { - return mrb_to_integer(mrb, val, "to_int"); + + if (!mrb_fixnum_p(val)) { + mrb_value type; + +#ifndef MRB_WITHOUT_FLOAT + if (mrb_float_p(val)) { + return mrb_flo_to_fixnum(mrb, val); + } +#endif + type = inspect_type(mrb, val); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer", type); + } + return val; } MRB_API mrb_value @@ -533,18 +517,12 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) if (mrb_nil_p(val)) { if (base != 0) goto arg_error; - mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); + mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); } switch (mrb_type(val)) { #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: if (base != 0) goto arg_error; - else { - mrb_float f = mrb_float(val); - if (FIXABLE_FLOAT(f)) { - break; - } - } return mrb_flo_to_fixnum(mrb, val); #endif @@ -568,11 +546,8 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) arg_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); } - tmp = convert_type(mrb, val, "Integer", "to_int", FALSE); - if (mrb_nil_p(tmp) || !mrb_fixnum_p(tmp)) { - tmp = mrb_to_integer(mrb, val, "to_i"); - } - return tmp; + /* to raise TypeError */ + return mrb_to_int(mrb, val); } MRB_API mrb_value -- cgit v1.2.3