Skip to content

Commit 1a759bf

Browse files
committed
Do not always taint the result of File#path
The result should only be tainted if the path given to the method was tainted. The code to always taint the result was added in a4934a4 (svn revision 4892) in 2003 by matz. However, the change wasn't mentioned in the commit message, and it may have been committed by accident. Skip part of a readline test that uses Reline. Reline in general would pass the test, but Reline's test mode doesn't raise a SecurityError if passing a tainted prompt and $SAFE >= 1. This was hidden earlier because File#path was always returning a tainted string. Fixes [Bug ruby#14485]
1 parent aa97410 commit 1a759bf

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ rb_file_path(VALUE obj)
475475
rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
476476
}
477477

478-
return rb_obj_taint(rb_str_dup(fptr->pathv));
478+
return rb_str_dup(fptr->pathv);
479479
}
480480

481481
static size_t

test/readline/test_readline.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ def test_readline
4141
assert_equal("> ", stdout.read(2))
4242
assert_equal(1, Readline::HISTORY.length)
4343
assert_equal("hello", Readline::HISTORY[0])
44+
45+
# Work around lack of SecurityError in Reline
46+
# test mode with tainted prompt
47+
return if kind_of?(TestRelineAsReadline)
48+
4449
Thread.start {
4550
$SAFE = 1
4651
assert_raise(SecurityError) do

test/ruby/test_file_exhaustive.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,22 @@ class << o; self; end.class_eval do
187187
end
188188
end
189189

190+
def test_path_taint
191+
[regular_file, utf8_file].each do |file|
192+
assert_equal(false, File.open(file) {|f| f.path}.tainted?)
193+
assert_equal(true, File.open(file.dup.taint) {|f| f.path}.tainted?)
194+
o = Object.new
195+
class << o; self; end.class_eval do
196+
define_method(:to_path) { file }
197+
end
198+
assert_equal(false, File.open(o) {|f| f.path}.tainted?)
199+
class << o; self; end.class_eval do
200+
define_method(:to_path) { file.dup.taint }
201+
end
202+
assert_equal(true, File.open(o) {|f| f.path}.tainted?)
203+
end
204+
end
205+
190206
def assert_integer(n)
191207
assert_kind_of(Integer, n)
192208
end

0 commit comments

Comments
 (0)