diff options
author | stas <stas@FreeBSD.org> | 2008-06-21 18:34:53 +0800 |
---|---|---|
committer | stas <stas@FreeBSD.org> | 2008-06-21 18:34:53 +0800 |
commit | c2cd88b373bed057f6f4a8270e81d92bae0c33c7 (patch) | |
tree | 55552b49fb43e7d9c14ae33a68bb51d2b1e97110 /lang | |
parent | 282b5c001ce85cc711e24e3e9fedf7aaae9f9281 (diff) | |
download | freebsd-ports-gnome-c2cd88b373bed057f6f4a8270e81d92bae0c33c7.tar.gz freebsd-ports-gnome-c2cd88b373bed057f6f4a8270e81d92bae0c33c7.tar.zst freebsd-ports-gnome-c2cd88b373bed057f6f4a8270e81d92bae0c33c7.zip |
- Fix possible memory corruption when using String;
- fix integer overflow in Array;
- fix overflow in String;
- bump PORTREVISION.
Obtained from: ruby VCS
Diffstat (limited to 'lang')
-rw-r--r-- | lang/ruby18/files/patch-array.c | 68 | ||||
-rw-r--r-- | lang/ruby18/files/patch-intern.h | 10 | ||||
-rw-r--r-- | lang/ruby18/files/patch-sprintf.c | 28 | ||||
-rw-r--r-- | lang/ruby18/files/patch-string.c | 137 |
4 files changed, 243 insertions, 0 deletions
diff --git a/lang/ruby18/files/patch-array.c b/lang/ruby18/files/patch-array.c new file mode 100644 index 000000000000..d585bd70b7c1 --- /dev/null +++ b/lang/ruby18/files/patch-array.c @@ -0,0 +1,68 @@ +--- array.c.orig 2008-06-21 12:28:01.000000000 +0400 ++++ array.c 2008-06-21 12:37:24.000000000 +0400 +@@ -20,6 +20,7 @@ + static ID id_cmp; + + #define ARY_DEFAULT_SIZE 16 ++#define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE)) + + void + rb_mem_clear(mem, size) +@@ -120,7 +121,7 @@ + if (len < 0) { + rb_raise(rb_eArgError, "negative array size (or size too big)"); + } +- if (len > 0 && len * sizeof(VALUE) <= len) { ++ if (len > ARY_MAX_SIZE) { + rb_raise(rb_eArgError, "array size too big"); + } + if (len == 0) len++; +@@ -293,7 +294,7 @@ + if (len < 0) { + rb_raise(rb_eArgError, "negative array size"); + } +- if (len > 0 && len * (long)sizeof(VALUE) <= len) { ++ if (len > ARY_MAX_SIZE) { + rb_raise(rb_eArgError, "array size too big"); + } + if (len > RARRAY(ary)->aux.capa) { +@@ -359,6 +360,10 @@ + } + } + ++ if (idx >= ARY_MAX_SIZE) { ++ rb_raise(rb_eIndexError, "index %ld too big", idx); ++ } ++ + rb_ary_modify(ary); + if (idx >= RARRAY(ary)->aux.capa) { + long new_capa = RARRAY(ary)->aux.capa / 2; +@@ -366,6 +371,9 @@ + if (new_capa < ARY_DEFAULT_SIZE) { + new_capa = ARY_DEFAULT_SIZE; + } ++ if (new_capa >= ARY_MAX_SIZE - idx) { ++ new_capa = (ARY_MAX_SIZE - idx) / 2; ++ } + new_capa += idx; + if (new_capa * (long)sizeof(VALUE) <= new_capa) { + rb_raise(rb_eArgError, "index too big"); +@@ -975,6 +983,9 @@ + rb_ary_modify(ary); + + if (beg >= RARRAY(ary)->len) { ++ if (beg > ARY_MAX_SIZE - rlen) { ++ rb_raise(rb_eIndexError, "index %ld too big", beg); ++ } + len = beg + rlen; + if (len >= RARRAY(ary)->aux.capa) { + REALLOC_N(RARRAY(ary)->ptr, VALUE, len); +@@ -2378,7 +2389,7 @@ + if (len < 0) { + rb_raise(rb_eArgError, "negative argument"); + } +- if (LONG_MAX/len < RARRAY(ary)->len) { ++ if (ARY_MAX_SIZE/len < RARRAY(ary)->len) { + rb_raise(rb_eArgError, "argument too big"); + } + len *= RARRAY(ary)->len; diff --git a/lang/ruby18/files/patch-intern.h b/lang/ruby18/files/patch-intern.h new file mode 100644 index 000000000000..02bb9ff09ba1 --- /dev/null +++ b/lang/ruby18/files/patch-intern.h @@ -0,0 +1,10 @@ +--- intern.h.orig 2008-06-21 12:49:23.000000000 +0400 ++++ intern.h 2008-06-21 12:49:29.000000000 +0400 +@@ -400,6 +400,7 @@ + void ruby_default_signal _((int)); + /* sprintf.c */ + VALUE rb_f_sprintf _((int, VALUE*)); ++VALUE rb_str_format _((int, VALUE*, VALUE)); + /* string.c */ + VALUE rb_str_new _((const char*, long)); + VALUE rb_str_new2 _((const char*)); diff --git a/lang/ruby18/files/patch-sprintf.c b/lang/ruby18/files/patch-sprintf.c new file mode 100644 index 000000000000..21d485558fcc --- /dev/null +++ b/lang/ruby18/files/patch-sprintf.c @@ -0,0 +1,28 @@ +--- sprintf.c.orig 2008-06-21 12:50:30.000000000 +0400 ++++ sprintf.c 2008-06-21 12:50:46.000000000 +0400 +@@ -247,7 +247,15 @@ + int argc; + VALUE *argv; + { ++ return rb_str_format(argc - 1, argv + 1, GETNTHARG(0)); ++} ++ ++VALUE ++rb_str_format(argc, argv, fmt) ++ int argc; ++ VALUE *argv; + VALUE fmt; ++{ + const char *p, *end; + char *buf; + int blen, bsiz; +@@ -276,7 +284,8 @@ + rb_raise(rb_eArgError, "flag after precision"); \ + } + +- fmt = GETNTHARG(0); ++ ++argc; ++ --argv; + if (OBJ_TAINTED(fmt)) tainted = 1; + StringValue(fmt); + fmt = rb_str_new4(fmt); diff --git a/lang/ruby18/files/patch-string.c b/lang/ruby18/files/patch-string.c new file mode 100644 index 000000000000..8eb0e590daaf --- /dev/null +++ b/lang/ruby18/files/patch-string.c @@ -0,0 +1,137 @@ +--- string.c.orig 2008-06-21 12:38:53.000000000 +0400 ++++ string.c 2008-06-21 12:49:20.000000000 +0400 +@@ -452,22 +452,16 @@ + */ + + static VALUE +-rb_str_format(str, arg) ++rb_str_format_m(str, arg) + VALUE str, arg; + { +- VALUE *argv; ++ VALUE tmp = rb_check_array_type(arg); + +- if (TYPE(arg) == T_ARRAY) { +- argv = ALLOCA_N(VALUE, RARRAY(arg)->len + 1); +- argv[0] = str; +- MEMCPY(argv+1, RARRAY(arg)->ptr, VALUE, RARRAY(arg)->len); +- return rb_f_sprintf(RARRAY(arg)->len+1, argv); ++ if (!NIL_P(tmp)) { ++ return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str); + } + +- argv = ALLOCA_N(VALUE, 2); +- argv[0] = str; +- argv[1] = arg; +- return rb_f_sprintf(2, argv); ++ return rb_str_format(1, &arg, str); + } + + static int +@@ -694,18 +688,14 @@ + return str; + } + +-VALUE +-rb_str_buf_cat(str, ptr, len) ++static VALUE ++str_buf_cat(str, ptr, len) + VALUE str; + const char *ptr; + long len; + { + long capa, total; + +- if (len == 0) return str; +- if (len < 0) { +- rb_raise(rb_eArgError, "negative string size (or size too big)"); +- } + rb_str_modify(str); + if (FL_TEST(str, STR_ASSOC)) { + FL_UNSET(str, STR_ASSOC); +@@ -714,9 +704,16 @@ + else { + capa = RSTRING(str)->aux.capa; + } ++ if (RSTRING(str)->len >= LONG_MAX - len) { ++ rb_raise(rb_eArgError, "string sizes too big"); ++ } + total = RSTRING(str)->len+len; + if (capa <= total) { + while (total > capa) { ++ if (capa + 1 >= LONG_MAX / 2) { ++ capa = total; ++ break; ++ } + capa = (capa + 1) * 2; + } + RESIZE_CAPA(str, capa); +@@ -729,6 +726,19 @@ + } + + VALUE ++rb_str_buf_cat(str, ptr, len) ++ VALUE str; ++ const char *ptr; ++ long len; ++{ ++ if (len == 0) return str; ++ if (len < 0) { ++ rb_raise(rb_eArgError, "negative string size (or size too big)"); ++ } ++ return str_buf_cat(str, ptr, len); ++} ++ ++VALUE + rb_str_buf_cat2(str, ptr) + VALUE str; + const char *ptr; +@@ -747,7 +757,7 @@ + } + if (FL_TEST(str, STR_ASSOC)) { + rb_str_modify(str); +- REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len); ++ REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len+1); + memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len); + RSTRING(str)->len += len; + RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */ +@@ -769,29 +779,8 @@ + rb_str_buf_append(str, str2) + VALUE str, str2; + { +- long capa, len; +- +- rb_str_modify(str); +- if (FL_TEST(str, STR_ASSOC)) { +- FL_UNSET(str, STR_ASSOC); +- capa = RSTRING(str)->aux.capa = RSTRING(str)->len; +- } +- else { +- capa = RSTRING(str)->aux.capa; +- } +- len = RSTRING(str)->len+RSTRING(str2)->len; +- if (capa <= len) { +- while (len > capa) { +- capa = (capa + 1) * 2; +- } +- RESIZE_CAPA(str, capa); +- } +- memcpy(RSTRING(str)->ptr + RSTRING(str)->len, +- RSTRING(str2)->ptr, RSTRING(str2)->len); +- RSTRING(str)->len += RSTRING(str2)->len; +- RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */ ++ str_buf_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + OBJ_INFECT(str, str2); +- + return str; + } + +@@ -4657,7 +4646,7 @@ + rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1); + rb_define_method(rb_cString, "+", rb_str_plus, 1); + rb_define_method(rb_cString, "*", rb_str_times, 1); +- rb_define_method(rb_cString, "%", rb_str_format, 1); ++ rb_define_method(rb_cString, "%", rb_str_format_m, 1); + rb_define_method(rb_cString, "[]", rb_str_aref_m, -1); + rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1); + rb_define_method(rb_cString, "insert", rb_str_insert, 2); |