diff options
| author | Felix Jones <[email protected]> | 2017-02-16 13:33:46 +0000 |
|---|---|---|
| committer | Felix Jones <[email protected]> | 2017-02-16 13:33:46 +0000 |
| commit | d83aad8d570e4bbffa3bd3ce64e210f78afa425f (patch) | |
| tree | 5389a87c135b1bdf3e23a1ba02e02400b7cf80fc /mrbgems/mruby-sprintf | |
| parent | 70aa6dc38d75dd6b1e2c76f290bc576e36e36ea3 (diff) | |
| parent | b165708c8deba00685f9a27926c554aaa7f3b0fb (diff) | |
| download | mruby-d83aad8d570e4bbffa3bd3ce64e210f78afa425f.tar.gz mruby-d83aad8d570e4bbffa3bd3ce64e210f78afa425f.zip | |
Merge branch 'master' into android.rake-ndk-clang
Diffstat (limited to 'mrbgems/mruby-sprintf')
| -rw-r--r-- | mrbgems/mruby-sprintf/src/sprintf.c | 92 | ||||
| -rw-r--r-- | mrbgems/mruby-sprintf/test/sprintf.rb | 25 |
2 files changed, 88 insertions, 29 deletions
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 8d14b0fc5..d02a2aa4d 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -116,8 +116,9 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) #define CHECK(l) do {\ /* int cr = ENC_CODERANGE(result);*/\ - while (blen + (l) >= bsiz) {\ + while ((l) >= bsiz - blen) {\ 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);*/\ @@ -136,29 +137,63 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) blen += (l);\ } while (0) -#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \ - posarg == -1 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \ - posarg == -2 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \ +static void +check_next_arg(mrb_state *mrb, int posarg, int nextarg) +{ + switch (posarg) { + case -1: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)); + break; + case -2: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)); + break; + default: + break; + } +} + +static void +check_pos_arg(mrb_state *mrb, int posarg, int n) +{ + if (posarg > 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", + mrb_fixnum_value(n), mrb_fixnum_value(posarg)); + } + if (posarg == -2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)); + } + if (n < 1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)); + } +} + +static void +check_name_arg(mrb_state *mrb, int posarg, const char *name, int len) +{ + if (posarg > 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", + mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)); + } + if (posarg == -1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))); + } +} + +#define GETNEXTARG() (\ + check_next_arg(mrb, posarg, nextarg),\ (posarg = nextarg++, GETNTHARG(posarg))) -#define GETPOSARG(n) (posarg > 0 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", mrb_fixnum_value(n), mrb_fixnum_value(posarg)), mrb_undef_value()) : \ - posarg == -2 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)), mrb_undef_value()) : \ - ((n < 1) ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)), mrb_undef_value()) : \ - (posarg = -1, GETNTHARG(n)))) +#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : GETNEXTARG()) + +#define GETPOSARG(n) (\ + check_pos_arg(mrb, posarg, n),\ + (posarg = -1, GETNTHARG(n))) #define GETNTHARG(nth) \ ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth]) -#define GETNAMEARG(id, name, len) ( \ - posarg > 0 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)), mrb_undef_value()) : \ - posarg == -1 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))), mrb_undef_value()) : \ +#define GETNAMEARG(id, name, len) (\ + check_name_arg(mrb, posarg, name, len),\ (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value()))) #define GETNUM(n, val) \ @@ -182,7 +217,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) tmp_v = GETPOSARG(n); \ } \ else { \ - tmp_v = GETARG(); \ + tmp_v = GETNEXTARG(); \ p = t; \ } \ num = mrb_fixnum(tmp_v); \ @@ -675,6 +710,7 @@ retry: else { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); } + mrb_check_type(mrb, tmp, MRB_TT_STRING); c = RSTRING_PTR(tmp); n = RSTRING_LEN(tmp); if (!(flags & FWIDTH)) { @@ -686,10 +722,10 @@ retry: CHECK(n); memcpy(buf+blen, c, n); blen += n; - FILL(' ', width-1); + if (width>0) FILL(' ', width-1); } else { - FILL(' ', width-1); + if (width>0) FILL(' ', width-1); CHECK(n); memcpy(buf+blen, c, n); blen += n; @@ -843,20 +879,20 @@ retry: strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf)); break; case 8: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRIo, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v); break; case 10: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRId, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); break; case 16: - snprintf(nbuf, sizeof(nbuf), "%"MRB_PRIx, v); + snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v); break; } s = nbuf; } else { s = nbuf; - if (v < 0) { + if (base != 10 && v < 0) { dots = 1; } switch (base) { @@ -864,13 +900,13 @@ retry: strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); break; case 8: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRIo, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); break; case 10: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRId, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v); break; case 16: - snprintf(++s, sizeof(nbuf)-1, "%"MRB_PRIx, v); + snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v); break; } if (v < 0) { diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb index 454c226e1..ccbd95d51 100644 --- a/mrbgems/mruby-sprintf/test/sprintf.rb +++ b/mrbgems/mruby-sprintf/test/sprintf.rb @@ -5,5 +5,28 @@ assert('String#%') do assert_equal "one=1", "one=%d" % 1 assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01 ] assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" } - assert_equal 16, ("%b" % (1<<15)).size + assert_equal 15, ("%b" % (1<<14)).size +end + +assert("String#% with invalid chr") do + begin + class Fixnum + alias_method :chr_, :chr if method_defined?(:chr) + + def chr + nil + end + end + + assert_raise TypeError do + "%c" % 0 + end + ensure + class Fixnum + if method_defined?(:chr_) + alias_method :chr, :chr_ + remove_method :chr_ + end + end + end end |
