86 lines
1.8 KiB
Ruby
86 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module ImportExport
|
|
class DecompressedArchiveSizeValidator
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
DEFAULT_MAX_BYTES = 10.gigabytes.freeze
|
|
TIMEOUT_LIMIT = 60.seconds
|
|
|
|
def initialize(archive_path:, max_bytes: self.class.max_bytes)
|
|
@archive_path = archive_path
|
|
@max_bytes = max_bytes
|
|
end
|
|
|
|
def valid?
|
|
strong_memoize(:valid) do
|
|
validate
|
|
end
|
|
end
|
|
|
|
def self.max_bytes
|
|
DEFAULT_MAX_BYTES
|
|
end
|
|
|
|
private
|
|
|
|
def validate
|
|
pgrp = nil
|
|
valid_archive = true
|
|
|
|
Timeout.timeout(TIMEOUT_LIMIT) do
|
|
stdin, stdout, stderr, wait_thr = Open3.popen3(command, pgroup: true)
|
|
stdin.close
|
|
pgrp = Process.getpgid(wait_thr[:pid])
|
|
status = wait_thr.value
|
|
|
|
if status.success?
|
|
result = stdout.readline
|
|
|
|
if result.to_i > @max_bytes
|
|
valid_archive = false
|
|
|
|
log_error('Decompressed archive size limit reached')
|
|
end
|
|
else
|
|
valid_archive = false
|
|
|
|
log_error(stderr.readline)
|
|
end
|
|
|
|
ensure
|
|
stdout.close
|
|
stderr.close
|
|
end
|
|
|
|
valid_archive
|
|
rescue Timeout::Error
|
|
log_error('Timeout reached during archive decompression')
|
|
|
|
Process.kill(-1, pgrp) if pgrp
|
|
|
|
false
|
|
rescue => e
|
|
log_error(e.message)
|
|
|
|
Process.kill(-1, pgrp) if pgrp
|
|
|
|
false
|
|
end
|
|
|
|
def command
|
|
"gzip -dc #{@archive_path} | wc -c"
|
|
end
|
|
|
|
def log_error(error)
|
|
Gitlab::Import::Logger.info(
|
|
message: error,
|
|
import_upload_archive_path: @archive_path,
|
|
import_upload_archive_size: File.size(@archive_path)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|