summaryrefslogtreecommitdiffhomepage
path: root/mrbgems
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2018-09-19 20:53:32 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2018-11-19 11:28:51 +0900
commitafca99a40b8a3415b3a9a0e8fc41c93ddcbb11d8 (patch)
tree6ecbeb3c8a562ce64713ccd4d2d6b1d12e6b5fa2 /mrbgems
parent426c1f9e0b77a27d5384ccdee7f7a49eef0e2ed0 (diff)
downloadmruby-afca99a40b8a3415b3a9a0e8fc41c93ddcbb11d8.tar.gz
mruby-afca99a40b8a3415b3a9a0e8fc41c93ddcbb11d8.zip
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).
Diffstat (limited to 'mrbgems')
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb27
-rw-r--r--mrbgems/mruby-enumerator/mrblib/enumerator.rb8
-rw-r--r--mrbgems/mruby-enumerator/test/enumerator.rb6
-rw-r--r--mrbgems/mruby-kernel-ext/src/kernel.c5
-rw-r--r--mrbgems/mruby-numeric-ext/src/numeric_ext.c17
-rw-r--r--mrbgems/mruby-pack/src/pack.c6
-rw-r--r--mrbgems/mruby-random/src/random.c12
-rw-r--r--mrbgems/mruby-random/test/random.rb12
-rw-r--r--mrbgems/mruby-range-ext/mrblib/range.rb5
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb12
10 files changed, 32 insertions, 78 deletions
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb
index ba92decee..fedf8b1ae 100644
--- a/mrbgems/mruby-enum-ext/mrblib/enum.rb
+++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb
@@ -13,10 +13,9 @@ module Enumerable
# a.drop(3) #=> [4, 5, 0]
def drop(n)
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+ n = n.__to_int
raise ArgumentError, "attempt to drop negative size" if n < 0
- n = n.to_int
ary = []
self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 }
ary
@@ -57,8 +56,8 @@ module Enumerable
# a.take(3) #=> [1, 2, 3]
def take(n)
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
- i = n.to_int
+ n = n.__to_int
+ i = n.to_i
raise ArgumentError, "attempt to take negative size" if i < 0
ary = []
return ary if i == 0
@@ -113,12 +112,12 @@ module Enumerable
# [8, 9, 10]
def each_cons(n, &block)
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+ n = n.__to_int
raise ArgumentError, "invalid size" if n <= 0
return to_enum(:each_cons,n) unless block
ary = []
- n = n.to_int
+ n = n.to_i
self.each do |*val|
ary.shift if ary.size == n
ary << val.__svalue
@@ -141,12 +140,12 @@ module Enumerable
# [10]
def each_slice(n, &block)
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+ n = n.__to_int
raise ArgumentError, "invalid slice size" if n <= 0
return to_enum(:each_slice,n) unless block
ary = []
- n = n.to_int
+ n = n.to_i
self.each do |*val|
ary << val.__svalue
if ary.size == n
@@ -223,9 +222,7 @@ module Enumerable
end
return nil
when 1
- n = args[0]
- raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
- i = n.to_int
+ i = args[0].__to_int
raise ArgumentError, "attempt to take negative size" if i < 0
ary = []
return ary if i == 0
@@ -673,13 +670,7 @@ module Enumerable
if nv.nil?
n = -1
else
- unless nv.respond_to?(:to_int)
- raise TypeError, "no implicit conversion of #{nv.class} into Integer"
- end
- n = nv.to_int
- unless n.kind_of?(Integer)
- raise TypeError, "no implicit conversion of #{nv.class} into Integer"
- end
+ n = nv.__to_int
return nil if n <= 0
end
diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb
index dbc7d3004..6dd971f3a 100644
--- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb
+++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb
@@ -157,12 +157,10 @@ class Enumerator
def with_index(offset=0, &block)
return to_enum :with_index, offset unless block
- offset = if offset.nil?
- 0
- elsif offset.respond_to?(:to_int)
- offset.to_int
+ if offset.nil?
+ offset = 0
else
- raise TypeError, "no implicit conversion of #{offset.class} into Integer"
+ offset = offset.__to_int
end
n = offset - 1
diff --git a/mrbgems/mruby-enumerator/test/enumerator.rb b/mrbgems/mruby-enumerator/test/enumerator.rb
index ef4970883..f3bd1bdba 100644
--- a/mrbgems/mruby-enumerator/test/enumerator.rb
+++ b/mrbgems/mruby-enumerator/test/enumerator.rb
@@ -54,12 +54,6 @@ assert 'Enumerator#with_index' do
assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a
end
-assert 'Enumerator#with_index nonnum offset' do
- s = Object.new
- def s.to_int; 1 end
- assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a)
-end
-
assert 'Enumerator#with_index string offset' do
assert_raise(TypeError){ @obj.to_enum(:foo, 1, 2, 3).with_index('1').to_a }
end
diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c
index 32d86376a..a60e9a210 100644
--- a/mrbgems/mruby-kernel-ext/src/kernel.c
+++ b/mrbgems/mruby-kernel-ext/src/kernel.c
@@ -93,9 +93,8 @@ mrb_f_method(mrb_state *mrb, mrb_value self)
* (<code>0</code>, <code>0b</code>, and <code>0x</code>) are honored.
* In any case, strings should be strictly conformed to numeric
* representation. This behavior is different from that of
- * <code>String#to_i</code>. Non string values will be converted using
- * <code>to_int</code>, and <code>to_i</code>. Passing <code>nil</code>
- * raises a TypeError.
+ * <code>String#to_i</code>. Non string values will be treated as integers.
+ * Passing <code>nil</code> raises a TypeError.
*
* Integer(123.999) #=> 123
* Integer("0x1a") #=> 26
diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c
index 1d6a07769..cd8bbf187 100644
--- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c
+++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c
@@ -2,13 +2,10 @@
#include <mruby.h>
static inline mrb_int
-to_int(mrb_value x)
+to_int(mrb_state *mrb, mrb_value x)
{
- double f;
-
- if (mrb_fixnum_p(x)) return mrb_fixnum(x);
- f = mrb_float(x);
- return (mrb_int)f;
+ x = mrb_to_int(mrb, x);
+ return mrb_fixnum(x);
}
/*
@@ -28,7 +25,7 @@ mrb_int_chr(mrb_state *mrb, mrb_value x)
mrb_int chr;
char c;
- chr = to_int(x);
+ chr = to_int(mrb, x);
if (chr >= (1 << CHAR_BIT)) {
mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x);
}
@@ -48,8 +45,8 @@ mrb_int_allbits(mrb_state *mrb, mrb_value self)
{
mrb_int n, m;
- n = to_int(self);
mrb_get_args(mrb, "i", &m);
+ n = to_int(mrb, self);
return mrb_bool_value((n & m) == m);
}
@@ -64,8 +61,8 @@ mrb_int_anybits(mrb_state *mrb, mrb_value self)
{
mrb_int n, m;
- n = to_int(self);
mrb_get_args(mrb, "i", &m);
+ n = to_int(mrb, self);
return mrb_bool_value((n & m) != 0);
}
@@ -80,8 +77,8 @@ mrb_int_nobits(mrb_state *mrb, mrb_value self)
{
mrb_int n, m;
- n = to_int(self);
mrb_get_args(mrb, "i", &m);
+ n = to_int(mrb, self);
return mrb_bool_value((n & m) == 0);
}
diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c
index 796ba4d34..5caf7b62b 100644
--- a/mrbgems/mruby-pack/src/pack.c
+++ b/mrbgems/mruby-pack/src/pack.c
@@ -1124,14 +1124,16 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
o = mrb_ary_ref(mrb, ary, aidx);
if (type == PACK_TYPE_INTEGER) {
o = mrb_to_int(mrb, o);
+ }
#ifndef MRB_WITHOUT_FLOAT
- } else if (type == PACK_TYPE_FLOAT) {
+ else if (type == PACK_TYPE_FLOAT) {
if (!mrb_float_p(o)) {
mrb_float f = mrb_to_flo(mrb, o);
o = mrb_float_value(mrb, f);
}
+ }
#endif
- } else if (type == PACK_TYPE_STRING) {
+ else if (type == PACK_TYPE_STRING) {
if (!mrb_string_p(o)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into String", mrb_class_path(mrb, mrb_obj_class(mrb, o)));
}
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
index 5b926a228..68209840a 100644
--- a/mrbgems/mruby-random/src/random.c
+++ b/mrbgems/mruby-random/src/random.c
@@ -79,12 +79,12 @@ get_opt(mrb_state* mrb)
mrb_get_args(mrb, "|o", &arg);
if (!mrb_nil_p(arg)) {
- arg = mrb_check_convert_type(mrb, arg, MRB_TT_FIXNUM, "Fixnum", "to_int");
- if (mrb_nil_p(arg)) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");
- }
- if (mrb_fixnum(arg) < 0) {
- arg = mrb_fixnum_value(0 - mrb_fixnum(arg));
+ mrb_int i;
+
+ arg = mrb_to_int(mrb, arg);
+ i = mrb_fixnum(arg);
+ if (i < 0) {
+ arg = mrb_fixnum_value(0 - i);
}
}
return arg;
diff --git a/mrbgems/mruby-random/test/random.rb b/mrbgems/mruby-random/test/random.rb
index 1c59be3a6..1653ae4a6 100644
--- a/mrbgems/mruby-random/test/random.rb
+++ b/mrbgems/mruby-random/test/random.rb
@@ -74,15 +74,3 @@ assert('Array#shuffle!(random)') do
ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
end
-
-assert('Array#sample checks input length after reading arguments') do
- $ary = [1, 2, 3]
- class ArrayChange
- def to_i
- $ary << 4
- 4
- end
- end
-
- assert_equal [1, 2, 3, 4], $ary.sample(ArrayChange.new).sort
-end
diff --git a/mrbgems/mruby-range-ext/mrblib/range.rb b/mrbgems/mruby-range-ext/mrblib/range.rb
index e5d1fb079..de7925ba7 100644
--- a/mrbgems/mruby-range-ext/mrblib/range.rb
+++ b/mrbgems/mruby-range-ext/mrblib/range.rb
@@ -15,10 +15,7 @@ class Range
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1
nv = args[0]
- raise TypeError, "no implicit conversion from nil to integer" if nv.nil?
- raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int)
- n = nv.to_int
- raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer)
+ n = nv.__to_int
raise ArgumentError, "negative array size (or size too big)" unless 0 <= n
ary = []
each do |i|
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index f0f8be6b3..781506949 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -31,18 +31,6 @@ assert('String#setbyte') do
assert_equal("Hello", str1)
end
-assert("String#setbyte raises IndexError if arg conversion resizes String") do
- $s = "01234\n"
- class Tmp
- def to_i
- $s.chomp! ''
- 95
- end
- end
- tmp = Tmp.new
- assert_raise(IndexError) { $s.setbyte(5, tmp) }
-end
-
assert('String#byteslice') do
str1 = "hello"
assert_equal("e", str1.byteslice(1))