aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2023-02-10 10:33:53 -0800
committerJeremy Evans <code@jeremyevans.net>2023-03-24 12:29:00 -0700
commit6c60006de5cfd75f10a1b4a3d822e2de41d22db6 (patch)
tree846c8feffac56b046d35059a001d095c2283bda9
parent836e9a192ba4fdc56a2d3d94f5840869f77fd3bf (diff)
downloadruby-6c60006de5cfd75f10a1b4a3d822e2de41d22db6.tar.gz
Raise ArgumentError if IO.read is provided negative offset
Fixes [Bug #19380]
-rw-r--r--io.c4
-rw-r--r--spec/ruby/core/io/read_spec.rb15
-rw-r--r--test/ruby/test_io.rb3
3 files changed, 19 insertions, 3 deletions
diff --git a/io.c b/io.c
index a3dfa027d4..a023039209 100644
--- a/io.c
+++ b/io.c
@@ -12125,9 +12125,13 @@ static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE opt, offset;
+ long off;
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
+ if (!NIL_P(offset) && (off = NUM2LONG(offset)) < 0) {
+ rb_raise(rb_eArgError, "negative offset %ld given", off);
+ }
open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb
index 0184c88f44..8bffd50876 100644
--- a/spec/ruby/core/io/read_spec.rb
+++ b/spec/ruby/core/io/read_spec.rb
@@ -128,9 +128,18 @@ describe "IO.read" do
-> { IO.read @fname, -1 }.should raise_error(ArgumentError)
end
- it "raises an Errno::EINVAL when not passed a valid offset" do
- -> { IO.read @fname, 0, -1 }.should raise_error(Errno::EINVAL)
- -> { IO.read @fname, -1, -1 }.should raise_error(Errno::EINVAL)
+ ruby_version_is ''...'3.3' do
+ it "raises an Errno::EINVAL when not passed a valid offset" do
+ -> { IO.read @fname, 0, -1 }.should raise_error(Errno::EINVAL)
+ -> { IO.read @fname, -1, -1 }.should raise_error(Errno::EINVAL)
+ end
+ end
+
+ ruby_version_is '3.3' do
+ it "raises an ArgumentError when not passed a valid offset" do
+ -> { IO.read @fname, 0, -1 }.should raise_error(ArgumentError)
+ -> { IO.read @fname, -1, -1 }.should raise_error(ArgumentError)
+ end
end
it "uses the external encoding specified via the :external_encoding option" do
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 0716dd7bf9..f57dee4261 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2866,6 +2866,9 @@ class TestIO < Test::Unit::TestCase
assert_equal("foo\nbar\nbaz\n", File.read(t.path))
assert_equal("foo\nba", File.read(t.path, 6))
assert_equal("bar\n", File.read(t.path, 4, 4))
+
+ assert_raise(ArgumentError) { File.read(t.path, -1) }
+ assert_raise(ArgumentError) { File.read(t.path, 1, -1) }
}
end