Develop and Download Open Source Software

Browse Subversion Repository

Contents of /hamigaki/trunk/libs/archivers/example/uniso.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1782 - (show annotations) (download) (as text)
Sun Jun 10 06:01:53 2018 UTC (5 years, 9 months ago) by hamigaki
File MIME type: text/x-c++src
File size: 3418 byte(s)
fix for Zip Slip
1 // uniso.cpp: a simple ISO image extractor program
2
3 // Copyright Takeshi Mouri 2007, 2018.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 // See http://hamigaki.sourceforge.jp/libs/archivers for library home page.
9
10
11 // Security warning:
12 // This program never check the validity of paths in the archive.
13 // See http://www.forest.impress.co.jp/article/2004/07/30/arcsecurity.html .
14 // (The above link is Japanese site)
15
16
17 #include <hamigaki/archivers/iso_file.hpp>
18 #include <boost/filesystem/convenience.hpp>
19 #include <boost/iostreams/copy.hpp>
20 #include <boost/version.hpp>
21 #include <clocale>
22 #include <exception>
23 #include <functional>
24 #include <iostream>
25
26 namespace ar = hamigaki::archivers;
27 namespace io_ex = hamigaki::iostreams;
28 namespace fs = boost::filesystem;
29 namespace io = boost::iostreams;
30
31 template<class Path>
32 inline bool has_parent_path(const Path& ph)
33 {
34 #if BOOST_VERSION < 103600
35 return ph.has_branch_path();
36 #else
37 return ph.has_parent_path();
38 #endif
39 }
40
41 template<class Path>
42 bool is_valid_path(const Path& ph)
43 {
44 #if !defined(HAMIGAKI_ALLOW_DIRECTORY_TRAVERSAL)
45 if (ph.has_root_name() || ph.has_root_directory())
46 return false;
47 for (typename Path::iterator it = ph.begin(); it != ph.end(); ++it)
48 {
49 if (*it == "..")
50 return false;
51 }
52 #endif
53 return true;
54 }
55
56 int main(int argc, char* argv[])
57 {
58 try
59 {
60 if (argc != 2)
61 {
62 std::cerr << "Usage: uniso (archive)" << std::endl;
63 return 1;
64 }
65
66 std::setlocale(LC_ALL, "");
67
68 ar::iso_file_source iso(argv[1]);
69
70 typedef std::vector<ar::iso::volume_desc> descs_type;
71 const descs_type& descs = iso.volume_descs();
72
73 descs_type::const_iterator rr = std::find_if(
74 descs.begin(), descs.end(),
75 std::mem_fun_ref(&ar::iso::volume_desc::is_rock_ridge)
76 );
77
78 descs_type::const_iterator jol = std::find_if(
79 descs.begin(), descs.end(),
80 std::mem_fun_ref(&ar::iso::volume_desc::is_joliet)
81 );
82
83 if (rr != descs.end())
84 iso.select_volume_desc(rr - descs.begin());
85 else if (jol != descs.end())
86 iso.select_volume_desc(jol - descs.begin());
87 else
88 iso.select_volume_desc(0);
89
90 while (iso.next_entry())
91 {
92 const ar::iso::header& head = iso.header();
93
94 std::cout << head.path.string() << '\n';
95 if (!is_valid_path(head.path))
96 {
97 std::cerr << "Warning: invalid path" << '\n';
98 continue;
99 }
100
101 if (head.is_symlink())
102 std::cout << "-> " << head.link_path.string() << '\n';
103 else if (head.is_directory())
104 fs::create_directories(head.path);
105 else if (head.is_regular())
106 {
107 if (::has_parent_path(head.path))
108 fs::create_directories(head.path.branch_path());
109
110 io::copy(
111 iso,
112 io_ex::file_sink(
113 head.path.file_string(), std::ios_base::binary)
114 );
115 }
116 }
117
118 return 0;
119 }
120 catch (const std::exception& e)
121 {
122 std::cerr << "Error: " << e.what() << std::endl;
123 }
124 return 1;
125 }

Properties

Name Value
svn:eol-style native

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26