From de5a85496ac4ae7bd24b5fc7acb8001a5e4d8b7d Mon Sep 17 00:00:00 2001 From: matz Date: Sat, 18 Sep 2004 06:56:38 +0000 Subject: * array.c (rb_ary_equal): element size might change during comparison. [ruby-dev:24254] * array.c (rb_ary_diff): ditto. [ruby-dev:24274] * array.c (rb_ary_select): ditto. [ruby-dev:24278] * array.c (rb_ary_delete): ditto. [ruby-dev:24283] * array.c (rb_ary_rindex): ditto. [ruby-dev:24275] * array.c (rb_ary_initialize): element size might change during initializing block. [ruby-dev:24284] * dir.c (dir_s_chdir): avoid memory leak and unnecessary chdir to the original directory when exception has caused in changing direcotry or within block. thanks to Johan Holmberg [ruby-core:03446] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 45 ++++++++++++++++++++++++++++++++++++++ array.c | 62 ++++++++++++++++++++++++++++------------------------- dir.c | 57 +++++++++++++++++++++++++++++++----------------- ext/digest/digest.c | 14 ++++++------ file.c | 7 ++++-- lib/mkmf.rb | 4 ++-- string.c | 5 +++-- 7 files changed, 132 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5919b9269..ed7f437d94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,41 @@ +Sat Sep 18 15:02:22 2004 Yukihiro Matsumoto + + * array.c (rb_ary_equal): element size might change during + comparison. [ruby-dev:24254] + + * array.c (rb_ary_diff): ditto. [ruby-dev:24274] + + * array.c (rb_ary_select): ditto. [ruby-dev:24278] + + * array.c (rb_ary_delete): ditto. [ruby-dev:24283] + + * array.c (rb_ary_rindex): ditto. [ruby-dev:24275] + + * array.c (rb_ary_initialize): element size might change during + initializing block. [ruby-dev:24284] + +Sat Sep 18 14:10:23 2004 Yukihiro Matsumoto + + * dir.c (dir_s_chdir): avoid memory leak and unnecessary chdir to + the original directory when exception has caused in changing + direcotry or within block. thanks to Johan Holmberg + [ruby-core:03446] + Fri Sep 17 20:20:27 2004 Minero Aoki * lib/fileutils.rb (mkdir_p): backport from CVS HEAD 1.45. [ruby-core:03420] +Fri Sep 17 17:11:08 2004 Yukihiro Matsumoto + + * array.c (rb_ary_delete): element comparison might change array + size. [ruby-dev:24273] + + * file.c (rb_file_truncate): clear stdio buffer before truncating + the file. [ruby-dev:24191] + + * ext/digest/digest.c: use rb_obj_class() instead of CLASS_OF + which might return singleton class. [ruby-dev:24202] + Fri Sep 17 16:07:09 2004 Hidetoshi NAGAI * ext/tk/lib/multi-tk.rb: improve exit operation @@ -32,6 +66,11 @@ Thu Sep 16 18:12:32 2004 GOTOU Yuuzou (WEBrick::HTTPServlet::FileHandler#initialize): should expand the pathname of document root directory. +Thu Sep 16 15:49:28 2004 Yukihiro Matsumoto + + * string.c (rb_str_intern): protect string argument from GC. + [ruby-core:03411] + Wed Sep 15 20:22:23 2004 Hidetoshi NAGAI * ext/tk/sample/tkoptdb-safeTk.rb: fix a bug depend on the changes @@ -160,6 +199,12 @@ Mon Sep 6 11:08:50 2004 Hirokazu Yamamoto * ext/tk/lib/tk/menu.rb(TkOptionMenubutton#insert): call correct method +Mon Sep 6 11:00:47 2004 Yukihiro Matsumoto + + * dir.c (dir_s_chdir): the patch to shut up false warning when + exception occurred within a block. a patch was given from Johan + Holmberg . [ruby-core:03292] + Mon Sep 6 07:51:42 2004 Yukihiro Matsumoto * eval.c (cvar_cbase): singletons should refer outer cvar scope. diff --git a/array.c b/array.c index a3b4b4f642..67da6b8e7e 100644 --- a/array.c +++ b/array.c @@ -304,7 +304,7 @@ rb_ary_initialize(argc, argv, ary) rb_warn("block supersedes default value argument"); } for (i=0; iptr[i] = rb_yield(LONG2NUM(i)); + rb_ary_store(ary, i, rb_yield(LONG2NUM(i))); RARRAY(ary)->len = i + 1; } } @@ -873,6 +873,10 @@ rb_ary_rindex(ary, val) long i = RARRAY(ary)->len; while (i--) { + if (i > RARRAY(ary)->len) { + i = RARRAY(ary)->len; + continue; + } if (rb_equal(RARRAY(ary)->ptr[i], val)) return LONG2NUM(i); } @@ -1771,7 +1775,7 @@ rb_ary_select(argc, argv, ary) result = rb_ary_new2(RARRAY(ary)->len); for (i = 0; i < RARRAY(ary)->len; i++) { if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { - rb_ary_push(result, RARRAY(ary)->ptr[i]); + rb_ary_push(result, rb_ary_entry(ary, i)); } } return result; @@ -1803,9 +1807,12 @@ rb_ary_delete(ary, item) rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { - if (rb_equal(RARRAY(ary)->ptr[i1], item)) continue; + VALUE e = RARRAY(ary)->ptr[i1]; + + if (rb_equal(e, item)) continue; if (i1 != i2) { - RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1]; + if (RARRAY(ary)->len < i2) break; + RARRAY(ary)->ptr[i2] = e; } i2++; } @@ -1816,7 +1823,8 @@ rb_ary_delete(ary, item) return Qnil; } - RARRAY(ary)->len = i2; + if (RARRAY(ary)->len > i2) + RARRAY(ary)->len = i2; if (i2 * 2 < RARRAY(ary)->aux.capa && RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) { REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2); @@ -2073,7 +2081,7 @@ rb_ary_transpose(ary) alen = RARRAY(ary)->len; if (alen == 0) return rb_ary_dup(ary); for (i=0; iptr[i]); + tmp = to_ary(rb_ary_entry(ary, i)); if (elen < 0) { /* first element */ elen = RARRAY(tmp)->len; result = rb_ary_new2(elen); @@ -2086,7 +2094,7 @@ rb_ary_transpose(ary) RARRAY(tmp)->len, elen); } for (j=0; jptr[j], i, RARRAY(tmp)->ptr[j]); + rb_ary_store(rb_ary_entry(result, j), i, rb_ary_entry(tmp, j)); } } return result; @@ -2360,17 +2368,15 @@ VALUE rb_ary_assoc(ary, key) VALUE ary, key; { - VALUE *p, *pend; + long i; + VALUE v; - p = RARRAY(ary)->ptr; - pend = p + RARRAY(ary)->len; - - while (p < pend) { - if (TYPE(*p) == T_ARRAY && - RARRAY(*p)->len > 0 && - rb_equal(RARRAY(*p)->ptr[0], key)) - return *p; - p++; + for (i = 0; i < RARRAY(ary)->len; ++i) { + v = RARRAY(ary)->ptr[i]; + if (TYPE(v) == T_ARRAY && + RARRAY(v)->len > 0 && + rb_equal(RARRAY(v)->ptr[0], key)) + return v; } return Qnil; } @@ -2393,17 +2399,15 @@ VALUE rb_ary_rassoc(ary, value) VALUE ary, value; { - VALUE *p, *pend; - - p = RARRAY(ary)->ptr; - pend = p + RARRAY(ary)->len; + long i; + VALUE v; - while (p < pend) { - if (TYPE(*p) == T_ARRAY - && RARRAY(*p)->len > 1 - && rb_equal(RARRAY(*p)->ptr[1], value)) - return *p; - p++; + for (i = 0; i < RARRAY(ary)->len; ++i) { + v = RARRAY(ary)->ptr[i]; + if (TYPE(v) == T_ARRAY && + RARRAY(v)->len > 1 && + rb_equal(RARRAY(v)->ptr[1], value)) + return v; } return Qnil; } @@ -2435,8 +2439,8 @@ rb_ary_equal(ary1, ary2) } return rb_equal(ary2, ary1); } - if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; for (i=0; ilen; i++) { + if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i])) return Qfalse; } @@ -2605,7 +2609,7 @@ rb_ary_diff(ary1, ary2) for (i=0; ilen; i++) { if (st_lookup(RHASH(hash)->tbl, RARRAY(ary1)->ptr[i], 0)) continue; - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + rb_ary_push(ary3, rb_ary_entry(ary1, i)); } return ary3; } diff --git a/dir.c b/dir.c index f4ec1fa57f..9327022328 100644 --- a/dir.c +++ b/dir.c @@ -542,24 +542,42 @@ dir_close(dir) static void dir_chdir(path) - const char *path; + VALUE path; { - if (chdir(path) < 0) - rb_sys_fail(path); + if (chdir(RSTRING(path)->ptr) < 0) + rb_sys_fail(RSTRING(path)->ptr); } static int chdir_blocking = 0; static VALUE chdir_thread = Qnil; +struct chdir_data { + VALUE old_path, new_path; + int done; +}; + static VALUE -chdir_restore(path) - char *path; +chdir_yield(args) + struct chdir_data *args; { - chdir_blocking--; - if (chdir_blocking == 0) - chdir_thread = Qnil; - dir_chdir(path); - free(path); + dir_chdir(args->new_path); + args->done = Qtrue; + chdir_blocking++; + if (chdir_thread == Qnil) + chdir_thread = rb_thread_current(); + return rb_yield(args->new_path); +} + +static VALUE +chdir_restore(args) + struct chdir_data *args; +{ + if (args->done) { + chdir_blocking--; + if (chdir_blocking == 0) + chdir_thread = Qnil; + dir_chdir(args->old_path); + } return Qnil; } @@ -609,19 +627,18 @@ dir_s_chdir(argc, argv, obj) VALUE obj; { VALUE path = Qnil; - char *dist = ""; rb_secure(2); if (rb_scan_args(argc, argv, "01", &path) == 1) { SafeStringValue(path); - dist = RSTRING(path)->ptr; } else { - dist = getenv("HOME"); + const char *dist = getenv("HOME"); if (!dist) { dist = getenv("LOGDIR"); if (!dist) rb_raise(rb_eArgError, "HOME/LOGDIR not set"); } + path = rb_str_new2(dist); } if (chdir_blocking > 0) { @@ -630,14 +647,14 @@ dir_s_chdir(argc, argv, obj) } if (rb_block_given_p()) { - char *cwd = my_getcwd(); - chdir_blocking++; - if (chdir_thread == Qnil) - chdir_thread = rb_thread_current(); - dir_chdir(dist); - return rb_ensure(rb_yield, path, chdir_restore, (VALUE)cwd); + struct chdir_data args; + + args.old_path = rb_str_new2(my_getcwd()); + args.new_path = path; + args.done = Qfalse; + return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); } - dir_chdir(dist); + dir_chdir(path); return INT2FIX(0); } diff --git a/ext/digest/digest.c b/ext/digest/digest.c index c570055322..70f986327a 100644 --- a/ext/digest/digest.c +++ b/ext/digest/digest.c @@ -149,8 +149,8 @@ rb_digest_base_copy(copy, obj) if (copy == obj) return copy; rb_check_frozen(copy); - algo = get_digest_base_metadata(CLASS_OF(copy)); - if (algo != get_digest_base_metadata(CLASS_OF(obj))) { + algo = get_digest_base_metadata(rb_obj_class(copy)); + if (algo != get_digest_base_metadata(rb_obj_class(obj))) { rb_raise(rb_eTypeError, "wrong argument class"); } Data_Get_Struct(obj, void, pctx1); @@ -168,7 +168,7 @@ rb_digest_base_update(self, str) void *pctx; StringValue(str); - algo = get_digest_base_metadata(CLASS_OF(self)); + algo = get_digest_base_metadata(rb_obj_class(self)); Data_Get_Struct(self, void, pctx); algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len); @@ -201,7 +201,7 @@ rb_digest_base_digest(self) size_t len; VALUE str; - algo = get_digest_base_metadata(CLASS_OF(self)); + algo = get_digest_base_metadata(rb_obj_class(self)); Data_Get_Struct(self, void, pctx1); len = algo->ctx_size; @@ -232,7 +232,7 @@ rb_digest_base_hexdigest(self) size_t len; VALUE str; - algo = get_digest_base_metadata(CLASS_OF(self)); + algo = get_digest_base_metadata(rb_obj_class(self)); Data_Get_Struct(self, void, pctx1); len = algo->ctx_size; @@ -261,10 +261,10 @@ rb_digest_base_equal(self, other) VALUE klass; VALUE str1, str2; - klass = CLASS_OF(self); + klass = rb_obj_class(self); algo = get_digest_base_metadata(klass); - if (CLASS_OF(other) == klass) { + if (rb_obj_class(other) == klass) { void *pctx1, *pctx2; Data_Get_Struct(self, void, pctx1); diff --git a/file.c b/file.c index 7f5452b7c5..a66e444543 100644 --- a/file.c +++ b/file.c @@ -2853,18 +2853,21 @@ rb_file_truncate(obj, len) VALUE obj, len; { OpenFile *fptr; + FILE *f; rb_secure(2); GetOpenFile(obj, fptr); if (!(fptr->mode & FMODE_WRITABLE)) { rb_raise(rb_eIOError, "not opened for writing"); } + f = GetWriteFile(fptr); + fflush(f); #ifdef HAVE_TRUNCATE - if (ftruncate(fileno(fptr->f), NUM2OFFT(len)) < 0) + if (ftruncate(fileno(f), NUM2OFFT(len)) < 0) rb_sys_fail(fptr->path); #else # ifdef HAVE_CHSIZE - if (chsize(fileno(fptr->f), NUM2OFFT(len)) < 0) + if (chsize(fileno(f), NUM2OFFT(len)) < 0) rb_sys_fail(fptr->path); # else rb_notimplement(); diff --git a/lib/mkmf.rb b/lib/mkmf.rb index 316bfe3505..494838e63b 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -474,7 +474,7 @@ def checking_for(m) r end -def have_library(lib, func = nil, &b) +def have_library(lib, func = nil, header=nil, &b) func = "main" if !func or func.empty? lib = with_config(lib+'lib', lib) checking_for "#{func}() in #{LIBARG%lib}" do @@ -482,7 +482,7 @@ def have_library(lib, func = nil, &b) true else libs = append_library($libs, lib) - if try_func(func, libs, &b) + if try_func(func, libs, header, &b) $libs = libs true else diff --git a/string.c b/string.c index 382feb4d84..a2287b8f28 100644 --- a/string.c +++ b/string.c @@ -4313,9 +4313,10 @@ rb_str_crypt(str, salt) */ VALUE -rb_str_intern(str) - VALUE str; +rb_str_intern(s) + VALUE s; { + volatile VALUE str = s; ID id; if (!RSTRING(str)->ptr || RSTRING(str)->len == 0) { -- cgit v1.2.3