Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb')
-rw-r--r--lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb b/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb
new file mode 100644
index 00000000000..690a47097c6
--- /dev/null
+++ b/lib/gitlab/ci/build/artifacts/adapters/zip_stream.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Build
+ module Artifacts
+ module Adapters
+ class ZipStream
+ MAX_DECOMPRESSED_SIZE = 100.megabytes
+ MAX_FILES_PROCESSED = 50
+
+ attr_reader :stream
+
+ InvalidStreamError = Class.new(StandardError)
+
+ def initialize(stream)
+ raise InvalidStreamError, "Stream is required" unless stream
+
+ @stream = stream
+ @files_processed = 0
+ end
+
+ def each_blob
+ Zip::InputStream.open(stream) do |zio|
+ while entry = zio.get_next_entry
+ break if at_files_processed_limit?
+ next unless should_process?(entry)
+
+ @files_processed += 1
+
+ yield entry.get_input_stream.read
+ end
+ end
+ end
+
+ private
+
+ def should_process?(entry)
+ file?(entry) && !too_large?(entry)
+ end
+
+ def file?(entry)
+ # Check the file name as a workaround for incorrect
+ # file type detection when using InputStream
+ # https://github.com/rubyzip/rubyzip/issues/533
+ entry.file? && !entry.name.end_with?('/')
+ end
+
+ def too_large?(entry)
+ entry.size > MAX_DECOMPRESSED_SIZE
+ end
+
+ def at_files_processed_limit?
+ @files_processed >= MAX_FILES_PROCESSED
+ end
+ end
+ end
+ end
+ end
+ end
+end