1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* sprintf.c (rb_f_sprintf): more checks for format argument.

[ruby-core:11569], [ruby-core:11570], [ruby-core:11571],
  [ruby-core:11573]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@12803 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2007-07-15 20:45:55 +00:00
parent 7da059bddb
commit 12d19d3887
2 changed files with 43 additions and 28 deletions

View file

@ -1,3 +1,9 @@
Mon Jul 16 05:45:53 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
* sprintf.c (rb_f_sprintf): more checks for format argument.
[ruby-core:11569], [ruby-core:11570], [ruby-core:11571],
[ruby-core:11573]
Mon Jul 16 00:26:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> Mon Jul 16 00:26:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
* bignum.c (rb_big_pow): removed invariant variable. [ruby-dev:31236] * bignum.c (rb_big_pow): removed invariant variable. [ruby-dev:31236]

View file

@ -82,6 +82,7 @@ sign_bits(base, p)
#define FSPACE 16 #define FSPACE 16
#define FWIDTH 32 #define FWIDTH 32
#define FPREC 64 #define FPREC 64
#define FPREC0 128
#define CHECK(l) do {\ #define CHECK(l) do {\
while (blen + (l) >= bsiz) {\ while (blen + (l) >= bsiz) {\
@ -110,9 +111,7 @@ sign_bits(base, p)
#define GETNTHARG(nth) \ #define GETNTHARG(nth) \
((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth]) ((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth])
#define GETASTER(val) do { \ #define GETNUM(n, val) \
t = p++; \
n = 0; \
for (; p < end && ISDIGIT(*p); p++) { \ for (; p < end && ISDIGIT(*p); p++) { \
int next_n = 10 * n + (*p - '0'); \ int next_n = 10 * n + (*p - '0'); \
if (next_n / 10 != n) {\ if (next_n / 10 != n) {\
@ -122,7 +121,12 @@ sign_bits(base, p)
} \ } \
if (p >= end) { \ if (p >= end) { \
rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \ rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
} \ }
#define GETASTER(val) do { \
t = p++; \
n = 0; \
GETNUM(n, val); \
if (*p == '$') { \ if (*p == '$') { \
tmp = GETPOSARG(n); \ tmp = GETPOSARG(n); \
} \ } \
@ -257,6 +261,21 @@ rb_f_sprintf(argc, argv)
VALUE tmp; VALUE tmp;
VALUE str; VALUE str;
#define CHECK_FOR_WIDTH(f) \
if ((f) & FWIDTH) { \
rb_raise(rb_eArgError, "width given twice"); \
} \
if ((f) & FPREC0) { \
rb_raise(rb_eArgError, "width after precision"); \
}
#define CHECK_FOR_FLAGS(f) \
if ((f) & FWIDTH) { \
rb_raise(rb_eArgError, "flag after width"); \
} \
if ((f) & FPREC0) { \
rb_raise(rb_eArgError, "flag after precision"); \
}
fmt = GETNTHARG(0); fmt = GETNTHARG(0);
if (OBJ_TAINTED(fmt)) tainted = 1; if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt); StringValue(fmt);
@ -292,43 +311,40 @@ rb_f_sprintf(argc, argv)
break; break;
case ' ': case ' ':
CHECK_FOR_FLAGS(flags);
flags |= FSPACE; flags |= FSPACE;
p++; p++;
goto retry; goto retry;
case '#': case '#':
CHECK_FOR_FLAGS(flags);
flags |= FSHARP; flags |= FSHARP;
p++; p++;
goto retry; goto retry;
case '+': case '+':
CHECK_FOR_FLAGS(flags);
flags |= FPLUS; flags |= FPLUS;
p++; p++;
goto retry; goto retry;
case '-': case '-':
CHECK_FOR_FLAGS(flags);
flags |= FMINUS; flags |= FMINUS;
p++; p++;
goto retry; goto retry;
case '0': case '0':
CHECK_FOR_FLAGS(flags);
flags |= FZERO; flags |= FZERO;
p++; p++;
goto retry; goto retry;
case '1': case '2': case '3': case '4': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
CHECK_FOR_WIDTH(flags);
n = 0; n = 0;
for (; p < end && ISDIGIT(*p); p++) { GETNUM(n, width);
int next_n = 10 * n + (*p - '0');
if (next_n / 10 != n) {
rb_raise(rb_eArgError, "width too big");
}
n = 10 * n + (*p - '0');
}
if (p >= end) {
rb_raise(rb_eArgError, "malformed format string - %%[0-9]");
}
if (*p == '$') { if (*p == '$') {
if (nextvalue != Qundef) { if (nextvalue != Qundef) {
rb_raise(rb_eArgError, "value given twice - %d$", n); rb_raise(rb_eArgError, "value given twice - %d$", n);
@ -342,10 +358,7 @@ rb_f_sprintf(argc, argv)
goto retry; goto retry;
case '*': case '*':
if (flags & FWIDTH) { CHECK_FOR_WIDTH(flags);
rb_raise(rb_eArgError, "width given twice");
}
flags |= FWIDTH; flags |= FWIDTH;
GETASTER(width); GETASTER(width);
if (width < 0) { if (width < 0) {
@ -356,10 +369,10 @@ rb_f_sprintf(argc, argv)
goto retry; goto retry;
case '.': case '.':
if (flags & FPREC) { if (flags & FPREC0) {
rb_raise(rb_eArgError, "precision given twice"); rb_raise(rb_eArgError, "precision given twice");
} }
flags |= FPREC; flags |= FPREC|FPREC0;
prec = 0; prec = 0;
p++; p++;
@ -372,17 +385,12 @@ rb_f_sprintf(argc, argv)
goto retry; goto retry;
} }
for (; p < end && ISDIGIT(*p); p++) { GETNUM(prec, precision);
prec = 10 * prec + (*p - '0');
}
if (p >= end) {
rb_raise(rb_eArgError, "malformed format string - %%.[0-9]");
}
goto retry; goto retry;
case '\n': case '\n':
p--;
case '\0': case '\0':
p--;
case '%': case '%':
if (flags != FNONE) { if (flags != FNONE) {
rb_raise(rb_eArgError, "illegal format character - %%"); rb_raise(rb_eArgError, "illegal format character - %%");
@ -455,7 +463,7 @@ rb_f_sprintf(argc, argv)
{ {
volatile VALUE val = GETARG(); volatile VALUE val = GETARG();
char fbuf[32], nbuf[64], *s, *t; char fbuf[32], nbuf[64], *s, *t;
char *prefix = 0; const char *prefix = 0;
int sign = 0; int sign = 0;
char sc = 0; char sc = 0;
long v = 0; long v = 0;
@ -532,6 +540,7 @@ rb_f_sprintf(argc, argv)
default: default:
base = 10; break; base = 10; break;
} }
if (!bignum) { if (!bignum) {
if (base == 2) { if (base == 2) {
val = rb_int2big(v); val = rb_int2big(v);