mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* sprintf.c (rb_f_sprintf): disallow mixed usage of numbered and
unnumbered arguments. [ruby-dev:18531] get rid of memory leak at exception. [ruby-core:00460] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b879196e32
commit
67f14c022b
2 changed files with 36 additions and 15 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Wed Oct 16 22:35:53 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
|
* sprintf.c (rb_f_sprintf): disallow mixed usage of numbered and
|
||||||
|
unnumbered arguments. [ruby-dev:18531]
|
||||||
|
get rid of memory leak at exception. [ruby-core:00460]
|
||||||
|
|
||||||
Wed Oct 16 13:36:29 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
Wed Oct 16 13:36:29 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
* variable.c (rb_global_entry): not add global entry until
|
* variable.c (rb_global_entry): not add global entry until
|
||||||
|
|
45
sprintf.c
45
sprintf.c
|
@ -62,11 +62,13 @@ remove_sign_bits(str, base)
|
||||||
#define FWIDTH 32
|
#define FWIDTH 32
|
||||||
#define FPREC 64
|
#define FPREC 64
|
||||||
|
|
||||||
#define CHECK(l) \
|
#define CHECK(l) do {\
|
||||||
while (blen + (l) >= bsiz) {\
|
while (blen + (l) >= bsiz) {\
|
||||||
REALLOC_N(buf, char, bsiz*2);\
|
|
||||||
bsiz*=2;\
|
bsiz*=2;\
|
||||||
}
|
}\
|
||||||
|
rb_str_resize(result, bsiz);\
|
||||||
|
buf = RSTRING(result)->ptr;\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define PUSH(s, l) do { \
|
#define PUSH(s, l) do { \
|
||||||
CHECK(l);\
|
CHECK(l);\
|
||||||
|
@ -74,8 +76,18 @@ remove_sign_bits(str, base)
|
||||||
blen += (l);\
|
blen += (l);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GETARG() \
|
#define GETARG() (nextvalue != Qundef ? nextvalue : \
|
||||||
((nextarg >= argc) ? (rb_raise(rb_eArgError, "too few argument."), 0) : argv[nextarg++])
|
posarg < 0 ? \
|
||||||
|
(rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered", nextarg), 0) : \
|
||||||
|
(posarg = nextarg++, GETNTHARG(posarg)))
|
||||||
|
|
||||||
|
#define GETPOSARG(n) (posarg > 0 ? \
|
||||||
|
(rb_raise(rb_eArgError, "numbered(%d) after unnumbered(%d)", n, posarg), 0) : \
|
||||||
|
((n < 1) ? (rb_raise(rb_eArgError, "invalid index - %d$", n), 0) : \
|
||||||
|
(posarg = -1, GETNTHARG(n))))
|
||||||
|
|
||||||
|
#define GETNTHARG(nth) \
|
||||||
|
((nth >= argc) ? (rb_raise(rb_eArgError, "too few argument."), 0) : argv[nth])
|
||||||
|
|
||||||
#define GETASTER(val) do { \
|
#define GETASTER(val) do { \
|
||||||
t = p++; \
|
t = p++; \
|
||||||
|
@ -87,10 +99,7 @@ remove_sign_bits(str, base)
|
||||||
rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
|
rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
|
||||||
} \
|
} \
|
||||||
if (*p == '$') { \
|
if (*p == '$') { \
|
||||||
int curarg = nextarg; \
|
tmp = GETPOSARG(n); \
|
||||||
nextarg = n; \
|
|
||||||
tmp = GETARG(); \
|
|
||||||
nextarg = curarg; \
|
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
tmp = GETARG(); \
|
tmp = GETARG(); \
|
||||||
|
@ -110,19 +119,22 @@ rb_f_sprintf(argc, argv)
|
||||||
VALUE result;
|
VALUE result;
|
||||||
|
|
||||||
int width, prec, flags = FNONE;
|
int width, prec, flags = FNONE;
|
||||||
int nextarg = 0;
|
int nextarg = 1;
|
||||||
|
int posarg = 0;
|
||||||
int tainted = 0;
|
int tainted = 0;
|
||||||
|
VALUE nextvalue;
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
fmt = GETARG();
|
fmt = GETNTHARG(0);
|
||||||
if (OBJ_TAINTED(fmt)) tainted = 1;
|
if (OBJ_TAINTED(fmt)) tainted = 1;
|
||||||
StringValue(fmt);
|
StringValue(fmt);
|
||||||
p = RSTRING(fmt)->ptr;
|
p = RSTRING(fmt)->ptr;
|
||||||
end = p + RSTRING(fmt)->len;
|
end = p + RSTRING(fmt)->len;
|
||||||
blen = 0;
|
blen = 0;
|
||||||
bsiz = 120;
|
bsiz = 120;
|
||||||
buf = ALLOC_N(char, bsiz);
|
result = rb_str_buf_new(bsiz);
|
||||||
|
buf = RSTRING(result)->ptr;
|
||||||
|
|
||||||
for (; p < end; p++) {
|
for (; p < end; p++) {
|
||||||
char *t;
|
char *t;
|
||||||
|
@ -137,6 +149,7 @@ rb_f_sprintf(argc, argv)
|
||||||
p = t + 1; /* skip `%' */
|
p = t + 1; /* skip `%' */
|
||||||
|
|
||||||
width = prec = -1;
|
width = prec = -1;
|
||||||
|
nextvalue = Qundef;
|
||||||
retry:
|
retry:
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
default:
|
default:
|
||||||
|
@ -181,7 +194,10 @@ rb_f_sprintf(argc, argv)
|
||||||
rb_raise(rb_eArgError, "malformed format string - %%[0-9]");
|
rb_raise(rb_eArgError, "malformed format string - %%[0-9]");
|
||||||
}
|
}
|
||||||
if (*p == '$') {
|
if (*p == '$') {
|
||||||
nextarg = n;
|
if (nextvalue != Qundef) {
|
||||||
|
rb_raise(rb_eArgError, "value given twice - %d$", n);
|
||||||
|
}
|
||||||
|
nextvalue = GETPOSARG(n);
|
||||||
p++;
|
p++;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
@ -579,8 +595,7 @@ rb_f_sprintf(argc, argv)
|
||||||
rb_raise(rb_eArgError, "too many argument for format string");
|
rb_raise(rb_eArgError, "too many argument for format string");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
result = rb_str_new(buf, blen);
|
rb_str_resize(result, blen);
|
||||||
free(buf);
|
|
||||||
|
|
||||||
if (tainted) OBJ_TAINT(result);
|
if (tainted) OBJ_TAINT(result);
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue