| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-18 15:11:11 -08:00
										 |  |  | RSpec.describe UnpackStrategy do | 
					
						
							| 
									
										
										
										
											2018-07-16 19:00:49 +02:00
										 |  |  |   describe "#extract_nestedly" do | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |     subject(:strategy) { described_class.detect(path) } | 
					
						
							| 
									
										
										
										
											2018-07-16 19:00:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     let(:unpack_dir) { mktmpdir } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |     context "when extracting a GZIP nested in a BZIP2" do | 
					
						
							|  |  |  |       let(:file_name) { "file" } | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       let(:path) do | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |         dir = mktmpdir | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         (dir/"file").write "This file was inside a GZIP inside a BZIP2." | 
					
						
							|  |  |  |         system "gzip", dir.children.first | 
					
						
							|  |  |  |         system "bzip2", dir.children.first | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dir.children.first | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "can extract nested archives" do | 
					
						
							|  |  |  |         strategy.extract_nestedly(to: unpack_dir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(File.read(unpack_dir/file_name)).to eq("This file was inside a GZIP inside a BZIP2.") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-16 19:00:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |     context "when extracting a directory with nested directories" do | 
					
						
							|  |  |  |       let(:directories) { "A/B/C" } | 
					
						
							| 
									
										
										
										
											2023-02-21 12:36:58 +01:00
										 |  |  |       let(:executable) { "#{directories}/executable" } | 
					
						
							| 
									
										
										
										
											2023-02-21 01:02:15 +01:00
										 |  |  |       let(:writable) { true } | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       let(:path) do | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |         (mktmpdir/"file.tar").tap do |path| | 
					
						
							| 
									
										
										
										
											2023-02-21 12:36:58 +01:00
										 |  |  |           Dir.mktmpdir do |dir| | 
					
						
							|  |  |  |             dir = Pathname(dir) | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |             (dir/directories).mkpath | 
					
						
							| 
									
										
										
										
											2023-02-21 12:36:58 +01:00
										 |  |  |             FileUtils.touch dir/executable | 
					
						
							|  |  |  |             FileUtils.chmod 0555, dir/executable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             FileUtils.chmod "-w", dir/directories unless writable | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               system "tar", "--create", "--file", path, "--directory", dir, "A/" | 
					
						
							|  |  |  |             ensure | 
					
						
							|  |  |  |               FileUtils.chmod "+w", dir/directories unless writable | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-07-16 20:56:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "does not recurse into nested directories" do | 
					
						
							|  |  |  |         strategy.extract_nestedly(to: unpack_dir) | 
					
						
							|  |  |  |         expect(Pathname.glob(unpack_dir/"**/*")).to include unpack_dir/directories | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-02-21 01:02:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       context "which are not writable" do | 
					
						
							|  |  |  |         let(:writable) { false } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it "makes them writable but not world-writable" do | 
					
						
							|  |  |  |           strategy.extract_nestedly(to: unpack_dir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(unpack_dir/directories).to be_writable | 
					
						
							|  |  |  |           expect(unpack_dir/directories).not_to be_world_writable | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-02-21 12:36:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it "does not make other files writable" do | 
					
						
							|  |  |  |           strategy.extract_nestedly(to: unpack_dir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 03:06:47 +00:00
										 |  |  |           # We don't check `writable?` here as that's always true as root. | 
					
						
							|  |  |  |           expect((unpack_dir/executable).stat.mode & 0222).to be_zero | 
					
						
							| 
									
										
										
										
											2023-02-21 12:36:58 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-02-21 01:02:15 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-07-16 19:00:49 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-19 12:45:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     context "when extracting a nested archive" do | 
					
						
							|  |  |  |       let(:basename) { "file.xyz" } | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       let(:path) do | 
					
						
							| 
									
										
										
										
											2018-07-19 12:45:35 +02:00
										 |  |  |         (mktmpdir/basename).tap do |path| | 
					
						
							|  |  |  |           mktmpdir do |dir| | 
					
						
							|  |  |  |             FileUtils.touch dir/"file.txt" | 
					
						
							| 
									
										
										
										
											2021-04-15 12:17:55 +01:00
										 |  |  |             system "tar", "--create", "--file", path, "--directory", dir, "file.txt" | 
					
						
							| 
									
										
										
										
											2018-07-19 12:45:35 +02:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-07-19 12:45:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "does not pass down the basename of the archive" do | 
					
						
							| 
									
										
										
										
											2024-03-07 16:20:20 +00:00
										 |  |  |         strategy.extract_nestedly(to: unpack_dir, basename:) | 
					
						
							| 
									
										
										
										
											2018-07-19 12:45:35 +02:00
										 |  |  |         expect(unpack_dir/"file.txt").to be_a_file | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-16 19:00:49 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | end |