Class: Capsium::Packager
- Inherits:
-
Object
- Object
- Capsium::Packager
- Defined in:
- sig/capsium/packager.rbs,
lib/capsium/packager.rb
Overview
Packs a package directory into a .cap file (generating security.json) and unpacks .cap files with zip-slip protection.
Defined Under Namespace
Classes: FileAlreadyExistsError, UnsafeEntryError
Constant Summary collapse
- DRIVE_LETTER_PATTERN =
%r{\A[A-Za-z]:[/\\]}
Instance Method Summary collapse
- #compress_package(package, cap_file) ⇒ void
- #pack(package, options = {}) ⇒ String
- #relative_path_current(absolute_path) ⇒ String
-
#transform_cap(cap_path) {|dir| ... } ⇒ String
Unpacks a .cap into a temporary directory, yields it for modification, then recompresses the result back over cap_path.
- #unpack(cap_file_path, destination) ⇒ void
-
#with_unpacked_cap(cap_path) {|dir| ... } ⇒ Object
Unpacks a .cap into a temporary directory, yields it for read-only inspection and returns the block's value.
Instance Method Details
#compress_package(package, cap_file) ⇒ void
This method returns an undefined value.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/capsium/packager.rb', line 60 def compress_package(package, cap_file) entries = Dir[File.join(package.path, "**", "**")].reject do |file| File.(file) == File.(cap_file) end Zip::File.open(cap_file, create: true) do |zipfile| entries.each do |file| zipfile.add(file.sub("#{package.path}/", ""), file) end end end |
#pack(package, options = {}) ⇒ String
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/capsium/packager.rb', line 20 def pack(package, = {}) directory = package.path output_file_name = "#{package..name}-#{package..version}.cap" output_directory = File.dirname(directory) cap_file_path = File.join(output_directory, output_file_name) if File.exist?(cap_file_path) && ![:force] raise FileAlreadyExistsError, "Package target already exists, aborting: `#{relative_path_current(cap_file_path)}`" elsif File.exist?(cap_file_path) puts "Package target already exists, overwriting: `#{relative_path_current(cap_file_path)}`" FileUtils.rm_f(cap_file_path) end Dir.mktmpdir do |dir| FileUtils.cp_r("#{directory}/.", dir) strip_security_artifacts(dir) new_package = Package.new(dir) new_package.solidify generate_security(new_package) new_cap_file_path = File.join(dir, output_file_name) compress_package(new_package, new_cap_file_path) puts "Package built at: #{new_cap_file_path}" FileUtils.mv(new_cap_file_path, cap_file_path) puts "Package created: #{relative_path_current(cap_file_path)}" return cap_file_path end end |
#relative_path_current(absolute_path) ⇒ String
96 97 98 |
# File 'lib/capsium/packager.rb', line 96 def relative_path_current(absolute_path) Pathname.new(absolute_path).relative_path_from(Dir.pwd).to_s end |
#transform_cap(cap_path) {|dir| ... } ⇒ String
Unpacks a .cap into a temporary directory, yields it for modification, then recompresses the result back over cap_path. Returns cap_path.
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/capsium/packager.rb', line 84 def transform_cap(cap_path) with_unpacked_cap(cap_path) do |dir| yield dir Dir.mktmpdir do |tmp| tmp_cap = File.join(tmp, File.basename(cap_path)) compress_package(Package.new(dir), tmp_cap) FileUtils.mv(tmp_cap, cap_path) end end cap_path end |
#unpack(cap_file_path, destination) ⇒ void
This method returns an undefined value.
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/capsium/packager.rb', line 49 def unpack(cap_file_path, destination) destination = File.(destination) Zip::File.open(cap_file_path) do |zip_file| zip_file.each do |entry| entry_path = safe_entry_path(destination, entry.name) FileUtils.mkdir_p(File.dirname(entry_path)) entry.extract(entry_path) end end end |
#with_unpacked_cap(cap_path) {|dir| ... } ⇒ Object
Unpacks a .cap into a temporary directory, yields it for read-only inspection and returns the block's value.
73 74 75 76 77 78 |
# File 'lib/capsium/packager.rb', line 73 def with_unpacked_cap(cap_path) Dir.mktmpdir do |dir| unpack(cap_path, dir) yield dir end end |