diff --git a/ChangeLog b/ChangeLog index 3487af7fd5..345a98be33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Jan 10 10:41:11 2012 Nobuyoshi Nakada + + * ext/readline/readline.c (readline_attempted_completion_function): + empty completion result does not mean memory error. + Tue Jan 10 02:19:22 2012 CHIKANAGA Tomoyuki * test/ruby/test_io.rb (test_autoclose_true_closed_by_finalizer, diff --git a/ext/readline/readline.c b/ext/readline/readline.c index fa164aec9f..c3c23e4f0a 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -667,10 +667,10 @@ readline_attempted_completion_function(const char *text, int start, int end) #endif case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold)); ary = rb_funcall(proc, rb_intern("call"), 1, rb_locale_str_new_cstr(text)); - if (TYPE(ary) != T_ARRAY) + if (!RB_TYPE_P(ary, T_ARRAY)) { ary = rb_Array(ary); matches = RARRAY_LEN(ary); - if (matches == NULL) rb_memerror(); + if (matches == 0) return NULL; result = (char**)malloc((matches + 2)*sizeof(char*)); if (result == NULL) rb_raise(rb_eNoMemError, "failed to allocate memory"); for (i = 0; i < matches; i++) { diff --git a/test/readline/test_readline.rb b/test/readline/test_readline.rb index 0d5efeac01..4ef696f25f 100644 --- a/test/readline/test_readline.rb +++ b/test/readline/test_readline.rb @@ -85,9 +85,7 @@ class TestReadline < Test::Unit::TestCase if !/EditLine/n.match(Readline::VERSION) def test_readline - stdin = Tempfile.new("test_readline_stdin") - stdout = Tempfile.new("test_readline_stdout") - begin + with_temp_stdio do |stdin, stdout| stdin.write("hello\n") stdin.close stdout.close @@ -114,9 +112,6 @@ class TestReadline < Test::Unit::TestCase replace_stdio(stdin.path, stdout.path) { Readline.readline("> ") } }.join end - ensure - stdin.close(true) - stdout.close(true) end end @@ -130,9 +125,7 @@ class TestReadline < Test::Unit::TestCase return end - stdin = Tempfile.new("test_readline_stdin") - stdout = Tempfile.new("test_readline_stdout") - begin + with_temp_stdio do |stdin, stdout| actual_text = nil actual_line_buffer = nil actual_point = nil @@ -176,9 +169,6 @@ class TestReadline < Test::Unit::TestCase assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding) assert_equal(true, Readline.line_buffer.tainted?) assert_equal(21, Readline.point) - ensure - stdin.close(true) - stdout.close(true) end end end @@ -213,6 +203,19 @@ class TestReadline < Test::Unit::TestCase end end + def test_completion_proc_empty_result + with_temp_stdio do |stdin, stdout| + stdin.write("first\t") + stdin.flush + actual_text = nil + Readline.completion_proc = ->(text) {[]} + line = replace_stdio(stdin.path, stdout.path) { + Readline.readline("> ") + } + assert_equal("first", line) + end + end + def test_get_screen_size begin res = Readline.get_screen_size @@ -336,6 +339,15 @@ class TestReadline < Test::Unit::TestCase } end + def with_temp_stdio + stdin = Tempfile.new("test_readline_stdin") + stdout = Tempfile.new("test_readline_stdout") + yield stdin, stdout + ensure + stdin.close(true) if stdin + stdout.close(true) if stdout + end + def get_default_internal_encoding return Encoding.default_internal || Encoding.find("locale") end