summaryrefslogtreecommitdiff
path: root/sprintf.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-10 07:26:35 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-10 07:26:35 +0000
commit99fd04b46fd863a348ee03e328bf65af69d7f11b (patch)
treedd85e7ed8b9d8f83051bf402cc213e65f91ff9da /sprintf.c
parent9a269ab175a432b861f613c0d3ac59c72428868a (diff)
rb_str_format: check overflow
* sprintf.c (rb_str_format): check overflow at too long name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'sprintf.c')
-rw-r--r--sprintf.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sprintf.c b/sprintf.c
index c34d906310..13d999f3ae 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -566,6 +566,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
const char *start = p;
char term = (*p == '<') ? '>' : '}';
+ int len;
for (; p < end && *p != term; ) {
p += rb_enc_mbclen(p, end, enc);
@@ -573,14 +574,23 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (p >= end) {
rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
}
+#if SIZEOF_INT < SIZEOF_SIZE_T
+ if ((size_t)(p - start) >= INT_MAX) {
+ const int message_limit = 20;
+ len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
+ rb_raise(rb_eArgError, "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
+ (size_t)(p - start - 2), len, start, term);
+ }
+#endif
+ len = (int)(p - start + 1); /* including parenthesis */
if (id) {
rb_raise(rb_eArgError, "name%.*s after <%s>",
- (int)(p - start + 1), start, rb_id2name(id));
+ len, start, rb_id2name(id));
}
- id = rb_intern3(start + 1, p - start - 1, enc);
- nextvalue = GETNAMEARG(ID2SYM(id), start, (int)(p - start + 1));
+ id = rb_intern3(start + 1, len - 2 /* without parenthesis */, enc);
+ nextvalue = GETNAMEARG(ID2SYM(id), start, len);
if (nextvalue == Qundef) {
- rb_raise(rb_eKeyError, "key%.*s not found", (int)(p - start + 1), start);
+ rb_raise(rb_eKeyError, "key%.*s not found", len, start);
}
if (term == '}') goto format_s;
p++;