diff --git a/ChangeLog b/ChangeLog index d9b09db774..a4608fe106 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Jul 30 07:59:53 2010 Nobuyoshi Nakada + + * util.c (ruby_add_suffix): fixed a bug returning uninitialized + value. + Fri Jul 30 07:48:04 2010 Hidetoshi NAGAI * ext/tk/extconf.rb: use TK_XINCLUDES on tkConfig.sh when not empty, diff --git a/ext/-test-/add_suffix/bug.c b/ext/-test-/add_suffix/bug.c new file mode 100644 index 0000000000..882832ed34 --- /dev/null +++ b/ext/-test-/add_suffix/bug.c @@ -0,0 +1,21 @@ +#include "ruby.h" +#include "ruby/defines.h" +#ifndef HAVE_RUBY_ADD_SUFFIX +#define _WIN32 1 +#include "util.c" +#endif + +static VALUE +add_suffix(VALUE self, VALUE path, VALUE suffix) +{ + StringValueCStr(path); + ruby_add_suffix(path, StringValueCStr(suffix)); + return path; +} + +void +Init_bug(void) +{ + VALUE mBug = rb_define_module("Bug"); + rb_define_module_function(mBug, "add_suffix", add_suffix, 2); +} diff --git a/ext/-test-/add_suffix/depend b/ext/-test-/add_suffix/depend new file mode 100644 index 0000000000..9c5d34192e --- /dev/null +++ b/ext/-test-/add_suffix/depend @@ -0,0 +1 @@ +bug.o: $(hdrdir)/util.h $(top_srcdir)/util.c io.h diff --git a/ext/-test-/add_suffix/extconf.rb b/ext/-test-/add_suffix/extconf.rb new file mode 100644 index 0000000000..bffd1550f3 --- /dev/null +++ b/ext/-test-/add_suffix/extconf.rb @@ -0,0 +1,4 @@ +unless have_func("ruby_add_suffix", "ruby/util.h") + $INCFLAGS << " -I$(top_srcdir)" +end +create_makefile("-test-/add_suffix/bug") diff --git a/ext/-test-/add_suffix/io.h b/ext/-test-/add_suffix/io.h new file mode 100644 index 0000000000..6d8d110a24 --- /dev/null +++ b/ext/-test-/add_suffix/io.h @@ -0,0 +1,3 @@ +#define _open open +#define _close close +#define _unlink unlink diff --git a/test/-ext-/test_add_suffix.rb b/test/-ext-/test_add_suffix.rb new file mode 100644 index 0000000000..6d73612875 --- /dev/null +++ b/test/-ext-/test_add_suffix.rb @@ -0,0 +1,46 @@ +require 'test/unit' +require "-test-/add_suffix/bug" + +class Test_AddSuffix < Test::Unit::TestCase + Dir = "/dev/null/".freeze + Style_1 = (Dir+"foo").freeze + + def test_style_0 + assert_equal("a.x.y", Bug.add_suffix("a.x", ".y")) + end + + def test_style_1 + assert_equal(Style_1+".y", Bug.add_suffix(Style_1+".c", ".y")) + suffix = ".bak".freeze + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1.dup, suffix)) + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1+".bar", suffix)) + assert_equal(Style_1+".$$$", Bug.add_suffix(Style_1+suffix, suffix)) + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1+".$$$", suffix)) + assert_equal(Style_1+".~~~", Bug.add_suffix(Style_1+".$$$", ".$$$")) + assert_equal(Dir+"makefile"+suffix, Bug.add_suffix(Dir+"makefile", suffix)) + end + + def test_style_2 + suffix = "~" + assert_equal(Style_1+"~", Bug.add_suffix(Style_1.dup, suffix)) + assert_equal(Style_1+".c~", Bug.add_suffix(Style_1+".c", suffix)) + assert_equal(Style_1+".c~~", Bug.add_suffix(Style_1+".c~", suffix)) + assert_equal(Style_1+"~.c~~", Bug.add_suffix(Style_1+".c~~", suffix)) + assert_equal(Style_1+"~~.c~~", Bug.add_suffix(Style_1+"~.c~~", suffix)) + assert_equal(Style_1+"~~~~~.cc~", Bug.add_suffix(Style_1+"~~~~~.ccc", suffix)) + assert_equal(Style_1+"~~~~~.$$$", Bug.add_suffix(Style_1+"~~~~~.c~~", suffix)) + assert_equal(Dir+"foo~.pas", Bug.add_suffix(Dir+"foo.pas", suffix)) + assert_equal(Dir+"makefile.~", Bug.add_suffix(Dir+"makefile", suffix)) + assert_equal(Dir+"longname.fi~", Bug.add_suffix(Dir+"longname.fil", suffix)) + assert_equal(Dir+"longnam~.fi~", Bug.add_suffix(Dir+"longname.fi~", suffix)) + assert_equal(Dir+"longnam~.$$$", Bug.add_suffix(Dir+"longnam~.fi~", suffix)) + end + + def test_style_3 + base = "a"*1000 + suffix = "-"+"b"*1000 + assert_equal(base+".~~~", Bug.add_suffix(base, suffix)) + assert_equal(base+".~~~", Bug.add_suffix(base+".$$$", suffix)) + assert_equal(base+".$$$", Bug.add_suffix(base+".~~~", suffix)) + end +end diff --git a/util.c b/util.c index d6d1eb0e39..ac009d057a 100644 --- a/util.c +++ b/util.c @@ -163,9 +163,8 @@ extern const char *ruby_find_extname(const char *, long *); void ruby_add_suffix(VALUE str, const char *suffix) { - int baselen; - int extlen = strlen(suffix); - char *p, *q; + long baselen; + long extlen = strlen(suffix); long slen; char buf[1024]; const char *name; @@ -189,26 +188,31 @@ ruby_add_suffix(VALUE str, const char *suffix) if (*suffix == '.') { /* Style 1 */ if (ext) { - if (strEQ(ext, suffix)) goto fallback; + if (strEQ(ext, suffix)) { + extlen = sizeof(suffix1) - 1; /* suffix2 must be same length */ + suffix = strEQ(suffix, suffix1) ? suffix2 : suffix1; + } slen = ext - name; } rb_str_resize(str, slen); rb_str_cat(str, suffix, extlen); } else { + char *p = buf, *q; strncpy(buf, name, slen); if (ext) - p = buf + (ext - name); + p += (ext - name); else - p = buf + slen; + p += slen; p[len] = '\0'; if (suffix[1] == '\0') { /* Style 2 */ + q = (char *)ruby_find_basename(buf, &baselen, 0); if (len <= 3) { + if (len == 0 && baselen >= 8 && p + 3 <= buf + sizeof(buf)) p[len++] = '.'; /* DOSISH */ p[len] = *suffix; p[++len] = '\0'; } - else if ((q = (char *)ruby_find_basename(buf, &baselen, 0)) && - baselen < 8) { + else if (q && baselen < 8) { q += baselen; *q++ = *suffix; if (ext) { @@ -229,9 +233,9 @@ ruby_add_suffix(VALUE str, const char *suffix) fallback: (void)memcpy(p, !ext || strEQ(ext, suffix1) ? suffix2 : suffix1, 5); } + rb_str_resize(str, strlen(buf)); + memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str)); } - rb_str_resize(str, strlen(buf)); - memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str)); } #if defined(__CYGWIN32__) || defined(_WIN32)