summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2025-09-13 07:34:53 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-09-16 17:17:32 +0900
commit12aa9e7457458245c9452ca5f786f6191742edf2 (patch)
treef2abd175b69f8c5316a28bab8827c178eeacc9bd
parent6b0af3135264351d0bbaaf5cf6b207a9c84b6e76 (diff)
[rubygems/rubygems] Use `IO.copy_stream` with IO object directly
Before this patch we would use `IO.copy_stream` with the tar entry object rather than just straight to the IO. That means every time copy_stream wanted data, we would have to proxy the call. The reason we did this is because every tar entry object _shares_ the same IO object, and previous to https://github.com/rubygems/rubygems/commit/8927533b0a47 we would call `IO.copy_stream` _without_ a size. Without passing a size, copy_stream will just read until there is nothing left to read, so these proxy object emulate finding "the end of the file" (where "end of file" means "end of tar chunk"). Without emulating this "end of file" behavior, copy_stream would just keep reading past the end of the tar chunk. However, now that we're passing the size to copy_stream, we can bypass the proxy object overhead and just use the IO object directly because copy_stream knows exactly the number of bytes it needs to read and will stop when it reaches the goal. https://github.com/rubygems/rubygems/commit/857002c135
-rw-r--r--lib/rubygems/package.rb2
-rw-r--r--lib/rubygems/package/tar_reader.rb2
2 files changed, 3 insertions, 1 deletions
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
index 0873040206..a8eba81ea0 100644
--- a/lib/rubygems/package.rb
+++ b/lib/rubygems/package.rb
@@ -452,7 +452,7 @@ EOM
if entry.file?
File.open(destination, "wb") do |out|
- copy_stream(entry, out, entry.size)
+ copy_stream(tar.io, out, entry.size)
# Flush needs to happen before chmod because there could be data
# in the IO buffer that needs to be written, and that could be
# written after the chmod (on close) which would mess up the perms
diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb
index 25f9b2f945..b66a8a62bc 100644
--- a/lib/rubygems/package/tar_reader.rb
+++ b/lib/rubygems/package/tar_reader.rb
@@ -30,6 +30,8 @@ class Gem::Package::TarReader
nil
end
+ attr_reader :io # :nodoc:
+
##
# Creates a new tar file reader on +io+ which needs to respond to #pos,
# #eof?, #read, #getc and #pos=