mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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).
This commit is contained in:
@@ -830,6 +830,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value);
|
||||
|
||||
void
|
||||
mrb_init_kernel(mrb_state *mrb)
|
||||
{
|
||||
@@ -871,6 +872,7 @@ mrb_init_kernel(mrb_state *mrb)
|
||||
mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */
|
||||
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
|
||||
mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */
|
||||
mrb_define_method(mrb, krn, "__to_int", mrb_to_int, MRB_ARGS_NONE()); /* internal */
|
||||
|
||||
mrb_define_method(mrb, krn, "class_defined?", mrb_krn_class_defined, MRB_ARGS_REQ(1));
|
||||
|
||||
|
||||
@@ -674,7 +674,6 @@ flo_round(mrb_state *mrb, mrb_value num)
|
||||
/*
|
||||
* call-seq:
|
||||
* flt.to_i -> integer
|
||||
* flt.to_int -> integer
|
||||
* flt.truncate -> integer
|
||||
*
|
||||
* Returns <i>flt</i> truncated to an <code>Integer</code>.
|
||||
@@ -714,7 +713,6 @@ flo_nan_p(mrb_state *mrb, mrb_value num)
|
||||
/*
|
||||
* call-seq:
|
||||
* int.to_i -> integer
|
||||
* int.to_int -> integer
|
||||
*
|
||||
* As <i>int</i> is already an <code>Integer</code>, all these
|
||||
* methods simply return the receiver.
|
||||
@@ -1513,7 +1511,6 @@ mrb_init_numeric(mrb_state *mrb)
|
||||
MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM);
|
||||
mrb_undef_class_method(mrb, integer, "new");
|
||||
mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */
|
||||
mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE());
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
|
||||
mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
|
||||
@@ -1565,7 +1562,6 @@ mrb_init_numeric(mrb_state *mrb)
|
||||
mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */
|
||||
mrb_define_method(mrb, fl, "to_f", flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */
|
||||
mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */
|
||||
mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */
|
||||
mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, fl, "eql?", flo_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
|
||||
|
||||
+16
-41
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user