summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-sprintf
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-07-17 10:35:41 +0900
committerGitHub <[email protected]>2019-07-17 10:35:41 +0900
commitd605b72c1d6fa4564a0a5e88535504b6850463b5 (patch)
tree774fc0de56002abb3bb2b1c3387ff08f91876d17 /mrbgems/mruby-sprintf
parent2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff)
parent9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff)
downloadmruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz
mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'mrbgems/mruby-sprintf')
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c27
-rw-r--r--mrbgems/mruby-sprintf/test/sprintf.rb9
2 files changed, 20 insertions, 16 deletions
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 7eea1a1f3..985ffe276 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -119,13 +119,11 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
#define FPREC0 128
#define CHECK(l) do {\
-/* int cr = ENC_CODERANGE(result);*/\
while ((l) >= bsiz - blen) {\
+ if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
bsiz*=2;\
- if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
}\
mrb_str_resize(mrb, result, bsiz);\
-/* ENC_CODERANGE_SET(result, cr);*/\
buf = RSTRING_PTR(result);\
} while (0)
@@ -202,11 +200,10 @@ check_name_arg(mrb_state *mrb, int posarg, const char *name, mrb_int len)
#define GETNUM(n, val) \
for (; p < end && ISDIGIT(*p); p++) {\
- mrb_int next_n = 10 * n + (*p - '0'); \
- if (next_n / 10 != n) {\
+ if (n > (MRB_INT_MAX - (*p - '0'))/10) {\
mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \
} \
- n = next_n; \
+ n = 10 * n + (*p - '0'); \
} \
if (p >= end) { \
mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %*[0-9]"); \
@@ -236,7 +233,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv)
if (argc != 2) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
}
- tmp = mrb_check_convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash");
+ tmp = mrb_check_hash_type(mrb, argv[1]);
if (mrb_nil_p(tmp)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
}
@@ -555,7 +552,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm
++argc;
--argv;
- fmt = mrb_str_to_str(mrb, fmt);
+ mrb_to_str(mrb, fmt);
p = RSTRING_PTR(fmt);
end = p + RSTRING_LEN(fmt);
blen = 0;
@@ -1059,18 +1056,22 @@ retry:
if (i > 0)
need = BIT_DIGITS(i);
}
+ if (need > MRB_INT_MAX - ((flags&FPREC) ? prec : 6)) {
+ too_big_width:
+ mrb_raise(mrb, E_ARGUMENT_ERROR,
+ (width > prec ? "width too big" : "prec too big"));
+ }
need += (flags&FPREC) ? prec : 6;
if ((flags&FWIDTH) && need < width)
need = width;
- need += 20;
- if (need <= 0) {
- mrb_raise(mrb, E_ARGUMENT_ERROR,
- (width > prec ? "width too big" : "prec too big"));
+ if (need > MRB_INT_MAX - 20) {
+ goto too_big_width;
}
+ need += 20;
CHECK(need);
n = snprintf(&buf[blen], need, fbuf, fval);
- if (n < 0) {
+ if (n < 0 || n >= need) {
mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
}
blen += n;
diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb
index a5fd4e638..137812ae7 100644
--- a/mrbgems/mruby-sprintf/test/sprintf.rb
+++ b/mrbgems/mruby-sprintf/test/sprintf.rb
@@ -4,12 +4,14 @@
assert('String#%') do
assert_equal "one=1", "one=%d" % 1
assert_equal "1 one", "%d %s" % [ 1, "one" ]
- assert_equal "1.0", "%3.1f" % 1.01 if class_defined?("Float")
assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" }
assert_equal 15, ("%b" % (1<<14)).size
+ skip unless Object.const_defined?(:Float)
+ assert_equal "1.0", "%3.1f" % 1.01
end
assert('String#% with inf') do
+ skip unless Object.const_defined?(:Float)
inf = Float::INFINITY
assert_equal "Inf", "%f" % inf
@@ -35,9 +37,10 @@ assert('String#% with inf') do
assert_equal " Inf", "% 3f" % inf
assert_equal " Inf", "% 4f" % inf
assert_equal " Inf", "% 5f" % inf
-end if class_defined?("Float")
+end
assert('String#% with nan') do
+ skip unless Object.const_defined?(:Float)
nan = Float::NAN
assert_equal "NaN", "%f" % nan
@@ -63,7 +66,7 @@ assert('String#% with nan') do
assert_equal " NaN", "% 3f" % nan
assert_equal " NaN", "% 4f" % nan
assert_equal " NaN", "% 5f" % nan
-end if class_defined?("Float")
+end
assert("String#% with invalid chr") do
begin