summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/dbm/dbm.c7
-rw-r--r--test/dbm/test_dbm.rb8
2 files changed, 13 insertions, 2 deletions
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index 1fdbaa0aca..03616fd4d8 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -259,8 +259,11 @@ fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
value = dbm_fetch(dbm, key);
if (value.dptr == 0) {
not_found:
- if (ifnone == Qnil && rb_block_given_p())
- return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
+ if (NIL_P(ifnone) && rb_block_given_p()) {
+ keystr = rb_str_dup(keystr);
+ OBJ_TAINT(keystr);
+ return rb_yield(keystr);
+ }
return ifnone;
}
return rb_tainted_str_new(value.dptr, value.dsize);
diff --git a/test/dbm/test_dbm.rb b/test/dbm/test_dbm.rb
index 9f7604be15..083a5c25ba 100644
--- a/test/dbm/test_dbm.rb
+++ b/test/dbm/test_dbm.rb
@@ -58,6 +58,14 @@ if defined? DBM
assert_nil(@dbm_rdonly.delete("bar"))
end
end
+
+ def test_fetch_not_found
+ notfound = nil
+ result = Object.new
+ assert_same(result, @dbm_rdonly.fetch("bar") {|k| notfound = k; result})
+ assert_equal("bar", notfound)
+ assert_predicate(notfound, :tainted?)
+ end
end
class TestDBM < Test::Unit::TestCase