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): 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:
nobu 2002-10-16 13:44:19 +00:00
parent b879196e32
commit 67f14c022b
2 changed files with 36 additions and 15 deletions

View file

@ -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

View file

@ -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;