Skip to content

Commit

Permalink
(PA-2849) Raise EOFError we download fewer than Content-Length bytes
Browse files Browse the repository at this point in the history
Net::HTTP has a bug where it will silently ignore EOF if it downloads
fewer than <Content-Length> bytes[1]. Patch ruby 2.4 and 2.5 on all
platforms. This is the same as the upstream PR[2].

[1] https://bugs.ruby-lang.org/issues/14972
[2] ruby/ruby#2074
  • Loading branch information
joshcooper committed Aug 12, 2019
1 parent f5187ae commit b01a836
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 0 deletions.
2 changes: 2 additions & 0 deletions configs/components/ruby-2.4.5.rb
Expand Up @@ -45,6 +45,8 @@
# Patches for rubygems security fixes from March 2019.
# See RE-12095 for more details.
pkg.apply_patch "#{base}/cve-2019-8320_to_8325_r2.4.patch"
# Patch for https://bugs.ruby-lang.org/issues/14972
pkg.apply_patch "#{base}/net_http_eof_14972.patch"

if platform.is_cross_compiled?
pkg.apply_patch "#{base}/uri_generic_remove_safe_nav_operator_r2.4.patch"
Expand Down
2 changes: 2 additions & 0 deletions configs/components/ruby-2.5.3.rb
Expand Up @@ -43,6 +43,8 @@
# Patches for rubygems security fixes from March 2019.
# See RE-12095 for more details.
pkg.apply_patch "#{base}/cve-2019-8320_to_8325_r2.5.patch"
# Patch for https://bugs.ruby-lang.org/issues/14972
pkg.apply_patch "#{base}/net_http_eof_14972.patch"

if platform.is_cross_compiled?
pkg.apply_patch "#{base}/uri_generic_remove_safe_nav_operator_r2.5.patch"
Expand Down
49 changes: 49 additions & 0 deletions resources/patches/ruby_245/net_http_eof_14972.patch
@@ -0,0 +1,49 @@
commit 615565a92519a83ff8433e7667c620505ba57f66
Author: Josh Cooper <josh@puppet.com>
Date: Tue Jan 22 15:24:55 2019 -0800

Raise EOF if response body content length is known

If response body content length is known, then read the complete
response body or raise EOF if it is truncated.

[Bug #14972][ruby-core:88324]

diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index 66132985d9..7c744d02f4 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -290,7 +290,7 @@ def read_body_0(dest)

clen = content_length()
if clen
- @socket.read clen, dest, true # ignore EOF
+ @socket.read clen, dest
return
end
clen = range_length()
diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb
index a03bb2e152..9d00276514 100644
--- a/test/net/http/test_httpresponse.rb
+++ b/test/net/http/test_httpresponse.rb
@@ -457,6 +457,20 @@ def test_inspect_response
assert_equal '#<Net::HTTPUnknownResponse ??? test response readbody=true>', res.inspect
end

+ def test_raise_eof
+ io = dummy_io(<<EOS)
+HTTP/1.1 200
+Content-Length: 5
+Connection: close
+
+h
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ assert_raise EOFError do
+ res.reading_body(io, true) {}
+ end
+ end
private

def dummy_io(str)
49 changes: 49 additions & 0 deletions resources/patches/ruby_253/net_http_eof_14972.patch
@@ -0,0 +1,49 @@
commit 615565a92519a83ff8433e7667c620505ba57f66
Author: Josh Cooper <josh@puppet.com>
Date: Tue Jan 22 15:24:55 2019 -0800

Raise EOF if response body content length is known

If response body content length is known, then read the complete
response body or raise EOF if it is truncated.

[Bug #14972][ruby-core:88324]

diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index 66132985d9..7c744d02f4 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -290,7 +290,7 @@ def read_body_0(dest)

clen = content_length()
if clen
- @socket.read clen, dest, true # ignore EOF
+ @socket.read clen, dest
return
end
clen = range_length()
diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb
index a03bb2e152..9d00276514 100644
--- a/test/net/http/test_httpresponse.rb
+++ b/test/net/http/test_httpresponse.rb
@@ -457,6 +457,20 @@ def test_inspect_response
assert_equal '#<Net::HTTPUnknownResponse ??? test response readbody=true>', res.inspect
end

+ def test_raise_eof
+ io = dummy_io(<<EOS)
+HTTP/1.1 200
+Content-Length: 5
+Connection: close
+
+h
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ assert_raise EOFError do
+ res.reading_body(io, true) {}
+ end
+ end
private

def dummy_io(str)

0 comments on commit b01a836

Please sign in to comment.