annotate bin/unzip @ 11866:088b9d939e57 draft

<ais523> ` sed -i -e \'s/unzip(@_)/unzip(@ARGV)/\' bin/unzip
author HackEso <hackeso@esolangs.org>
date Tue, 16 Jul 2019 21:37:33 +0000
parents d054de7f80f2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11861
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
1 #!/usr/bin/perl
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
2 # example perl code, this may not actually run without tweaking, especially on Windows
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
3
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
4 use strict;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
5 use warnings;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
6
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
7 =pod
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
8
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
9 IO::Uncompress::Unzip works great to process zip files; but, it doesn't include a routine to actually
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
10 extract an entire zip file.
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
11
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
12 Other modules like Archive::Zip include their own unzip routines, which aren't as robust as IO::Uncompress::Unzip;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
13 eg. they don't work on zip64 archive files.
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
14
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
15 So, the following is code to actually use IO::Uncompress::Unzip to extract a zip file.
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
16
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
17 =cut
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
18
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
19 use File::Spec::Functions qw(splitpath);
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
20 use IO::File;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
21 use IO::Uncompress::Unzip qw($UnzipError);
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
22 use File::Path qw(mkpath);
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
23
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
24 # example code to call unzip:
11866
088b9d939e57 <ais523> ` sed -i -e \'s/unzip(@_)/unzip(@ARGV)/\' bin/unzip
HackEso <hackeso@esolangs.org>
parents: 11864
diff changeset
25 unzip(@ARGV);
11861
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
26
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
27 =head2 unzip
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
28
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
29 Extract a zip file, using IO::Uncompress::Unzip.
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
30
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
31 Arguments: file to extract, destination path
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
32
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
33 unzip('stuff.zip', '/tmp/unzipped');
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
34
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
35 =cut
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
36
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
37 sub unzip {
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
38 my ($file, $dest) = @_;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
39
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
40 die 'Need a file argument' unless defined $file;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
41 $dest = "." unless defined $dest;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
42
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
43 my $u = IO::Uncompress::Unzip->new($file)
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
44 or die "Cannot open $file: $UnzipError";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
45
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
46 my $status;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
47 for ($status = 1; $status > 0; $status = $u->nextStream()) {
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
48 my $header = $u->getHeaderInfo();
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
49 my (undef, $path, $name) = splitpath($header->{Name});
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
50 my $destdir = "$dest/$path";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
51
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
52 unless (-d $destdir) {
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
53 mkpath($destdir) or die "Couldn't mkdir $destdir: $!";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
54 }
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
55
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
56 if ($name =~ m!/$!) {
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
57 last if $status < 0;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
58 next;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
59 }
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
60
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
61 my $destfile = "$dest/$path/$name";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
62 # https://cwe.mitre.org/data/definitions/37.html
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
63 # CWE-37: Path Traversal
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
64 die "unsafe $destfile" if $destfile =~ m!\Q..\E(/|\\)!;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
65
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
66 my $buff;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
67 my $fh = IO::File->new($destfile, "w")
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
68 or die "Couldn't write to $destfile: $!";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
69 while (($status = $u->read($buff)) > 0) {
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
70 $fh->write($buff);
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
71 }
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
72 $fh->close();
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
73 my $stored_time = $header->{'Time'};
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
74 utime ($stored_time, $stored_time, $destfile)
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
75 or die "Couldn't touch $destfile: $!";
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
76 }
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
77
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
78 die "Error processing $file: $!\n"
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
79 if $status < 0 ;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
80
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
81 return;
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
82 }
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
83
8970d544f2b3 <ais523> fetch https://gist.githubusercontent.com/eqhmcow/5389877/raw/514a27c213aefb58079687e4c257b57d6ad7a39f/unzip.pl
HackEso <hackeso@esolangs.org>
parents:
diff changeset
84 1;