Skip to content

Commit b4db982

Browse files
committed
use abs path for archives
1 parent de9965e commit b4db982

8 files changed

Lines changed: 130 additions & 10 deletions

File tree

src/odr/exceptions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,7 @@ DecryptionFailed::DecryptionFailed()
126126
NotEncryptedError::NotEncryptedError()
127127
: std::runtime_error("not encrypted error") {}
128128

129+
InvalidPath::InvalidPath(const std::string &message)
130+
: std::runtime_error("invalid path: " + message) {}
131+
129132
} // namespace odr

src/odr/exceptions.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,9 @@ struct NotEncryptedError : public std::runtime_error {
215215
explicit NotEncryptedError();
216216
};
217217

218+
/// @brief Invalid path
219+
struct InvalidPath : public std::runtime_error {
220+
explicit InvalidPath(const std::string &message);
221+
};
222+
218223
} // namespace odr

src/odr/internal/cfb/cfb_archive.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ std::shared_ptr<abstract::Filesystem> CfbArchive::as_filesystem() const {
3434

3535
void CfbArchive::save(std::ostream &out) const {
3636
(void)out;
37-
3837
throw UnsupportedOperation();
3938
}
4039

src/odr/internal/common/filesystem.cpp

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ class SystemFileWalker final : public abstract::FileWalker {
1919
public:
2020
SystemFileWalker(Path root, const Path &path)
2121
: m_root{std::move(root)},
22-
m_iterator{std::filesystem::recursive_directory_iterator(path)} {}
22+
m_iterator{std::filesystem::recursive_directory_iterator(path)} {
23+
if (path.relative()) {
24+
throw InvalidPath("SystemFileWalker: path must be absolute");
25+
}
26+
}
2327

2428
[[nodiscard]] std::unique_ptr<FileWalker> clone() const final {
2529
return std::make_unique<SystemFileWalker>(*this);
@@ -69,40 +73,77 @@ Path SystemFilesystem::to_system_path_(const Path &path) const {
6973
}
7074

7175
bool SystemFilesystem::exists(const Path &path) const {
76+
if (path.relative()) {
77+
throw InvalidPath("SystemFilesystem::exists: path must be absolute");
78+
}
79+
7280
return std::filesystem::exists(to_system_path_(path));
7381
}
7482

7583
bool SystemFilesystem::is_file(const Path &path) const {
84+
if (path.relative()) {
85+
throw InvalidPath("SystemFilesystem::is_file: path must be absolute");
86+
}
87+
7688
return std::filesystem::is_regular_file(to_system_path_(path));
7789
}
7890

7991
bool SystemFilesystem::is_directory(const Path &path) const {
92+
if (path.relative()) {
93+
throw InvalidPath("SystemFilesystem::is_directory: path must be absolute");
94+
}
95+
8096
return std::filesystem::is_directory(to_system_path_(path));
8197
}
8298

8399
std::unique_ptr<abstract::FileWalker>
84100
SystemFilesystem::file_walker(const Path &path) const {
101+
if (path.relative()) {
102+
throw InvalidPath("SystemFilesystem::file_walker: path must be absolute");
103+
}
104+
85105
return std::make_unique<SystemFileWalker>(m_root, to_system_path_(path));
86106
}
87107

88108
std::shared_ptr<abstract::File> SystemFilesystem::open(const Path &path) const {
109+
if (path.relative()) {
110+
throw InvalidPath("SystemFilesystem::open: path must be absolute");
111+
}
112+
89113
return std::make_unique<DiskFile>(to_system_path_(path));
90114
}
91115

92116
std::unique_ptr<std::ostream> SystemFilesystem::create_file(const Path &path) {
117+
if (path.relative()) {
118+
throw InvalidPath("SystemFilesystem::create_file: path must be absolute");
119+
}
120+
93121
return std::make_unique<std::ofstream>(
94122
util::file::create(to_system_path_(path).string()));
95123
}
96124

97125
bool SystemFilesystem::create_directory(const Path &path) {
126+
if (path.relative()) {
127+
throw InvalidPath(
128+
"SystemFilesystem::create_directory: path must be absolute");
129+
}
130+
98131
return std::filesystem::create_directory(to_system_path_(path));
99132
}
100133

101134
bool SystemFilesystem::remove(const Path &path) {
135+
if (path.relative()) {
136+
throw InvalidPath("SystemFilesystem::remove: path must be absolute");
137+
}
138+
102139
return std::filesystem::remove(to_system_path_(path));
103140
}
104141

105142
bool SystemFilesystem::copy(const Path &from, const Path &to) {
143+
if (from.relative() || to.relative()) {
144+
throw InvalidPath("SystemFilesystem::copy: paths must be absolute");
145+
}
146+
106147
std::error_code error_code;
107148
std::filesystem::copy(to_system_path_(from), to_system_path_(to), error_code);
108149
if (error_code) {
@@ -113,6 +154,10 @@ bool SystemFilesystem::copy(const Path &from, const Path &to) {
113154

114155
std::shared_ptr<abstract::File>
115156
SystemFilesystem::copy(const abstract::File &from, const Path &to) {
157+
if (to.relative()) {
158+
throw InvalidPath("SystemFilesystem::copy: path must be absolute");
159+
}
160+
116161
auto istream = from.stream();
117162
auto ostream = create_file(to_system_path_(to));
118163

@@ -123,10 +168,18 @@ SystemFilesystem::copy(const abstract::File &from, const Path &to) {
123168

124169
std::shared_ptr<abstract::File>
125170
SystemFilesystem::copy(std::shared_ptr<abstract::File> from, const Path &to) {
171+
if (to.relative()) {
172+
throw InvalidPath("SystemFilesystem::copy: path must be absolute");
173+
}
174+
126175
return copy(*from, to_system_path_(to));
127176
}
128177

129178
bool SystemFilesystem::move(const Path &from, const Path &to) {
179+
if (from.relative() || to.relative()) {
180+
throw InvalidPath("SystemFilesystem::move: paths must be absolute");
181+
}
182+
130183
std::error_code error_code;
131184
std::filesystem::rename(to_system_path_(from), to_system_path_(to),
132185
error_code);
@@ -142,6 +195,10 @@ class VirtualFileWalker final : public abstract::FileWalker {
142195
VirtualFileWalker(
143196
const Path &root,
144197
const std::map<Path, std::shared_ptr<abstract::File>> &files) {
198+
if (root.relative()) {
199+
throw InvalidPath("VirtualFileWalker: path must be absolute");
200+
}
201+
145202
for (auto &&f : files) {
146203
if (f.first.ancestor_of(root)) {
147204
m_files[f.first] = f.second;
@@ -195,10 +252,18 @@ class VirtualFileWalker final : public abstract::FileWalker {
195252
} // namespace
196253

197254
bool VirtualFilesystem::exists(const Path &path) const {
255+
if (path.relative()) {
256+
throw InvalidPath("VirtualFilesystem::exists: path must be absolute");
257+
}
258+
198259
return m_files.find(path) != std::end(m_files);
199260
}
200261

201262
bool VirtualFilesystem::is_file(const Path &path) const {
263+
if (path.relative()) {
264+
throw InvalidPath("VirtualFilesystem::is_file: path must be absolute");
265+
}
266+
202267
auto file_it = m_files.find(path);
203268
if (file_it == std::end(m_files)) {
204269
return false;
@@ -207,6 +272,10 @@ bool VirtualFilesystem::is_file(const Path &path) const {
207272
}
208273

209274
bool VirtualFilesystem::is_directory(const Path &path) const {
275+
if (path.relative()) {
276+
throw InvalidPath("VirtualFilesystem::is_directory: path must be absolute");
277+
}
278+
210279
auto file_it = m_files.find(path);
211280
if (file_it == std::end(m_files)) {
212281
return false;
@@ -216,11 +285,19 @@ bool VirtualFilesystem::is_directory(const Path &path) const {
216285

217286
std::unique_ptr<abstract::FileWalker>
218287
VirtualFilesystem::file_walker(const Path &path) const {
219-
return std::make_unique<VirtualFileWalker>(std::move(path), m_files);
288+
if (path.relative()) {
289+
throw InvalidPath("VirtualFilesystem::file_walker: path must be absolute");
290+
}
291+
292+
return std::make_unique<VirtualFileWalker>(path, m_files);
220293
}
221294

222295
std::shared_ptr<abstract::File>
223296
VirtualFilesystem::open(const Path &path) const {
297+
if (path.relative()) {
298+
throw InvalidPath("VirtualFilesystem::open: path must be absolute");
299+
}
300+
224301
auto file_it = m_files.find(path);
225302
if (file_it == std::end(m_files)) {
226303
return {};
@@ -234,6 +311,11 @@ VirtualFilesystem::create_file(const Path & /*path*/) {
234311
}
235312

236313
bool VirtualFilesystem::create_directory(const Path &path) {
314+
if (path.relative()) {
315+
throw InvalidPath(
316+
"VirtualFilesystem::create_directory: path must be absolute");
317+
}
318+
237319
if (exists(path)) {
238320
return false;
239321
}
@@ -242,6 +324,10 @@ bool VirtualFilesystem::create_directory(const Path &path) {
242324
}
243325

244326
bool VirtualFilesystem::remove(const Path &path) {
327+
if (path.relative()) {
328+
throw InvalidPath("VirtualFilesystem::remove: path must be absolute");
329+
}
330+
245331
auto file_it = m_files.find(path);
246332
if (file_it == std::end(m_files)) {
247333
return false;
@@ -251,6 +337,10 @@ bool VirtualFilesystem::remove(const Path &path) {
251337
}
252338

253339
bool VirtualFilesystem::copy(const Path &from, const Path &to) {
340+
if (from.relative() || to.relative()) {
341+
throw InvalidPath("VirtualFilesystem::copy: paths must be absolute");
342+
}
343+
254344
// TODO what about directories?
255345

256346
auto from_it = m_files.find(from);
@@ -271,6 +361,10 @@ VirtualFilesystem::copy(const abstract::File & /*from*/, const Path & /*to*/) {
271361

272362
std::shared_ptr<abstract::File>
273363
VirtualFilesystem::copy(std::shared_ptr<abstract::File> from, const Path &to) {
364+
if (to.relative()) {
365+
throw InvalidPath("VirtualFilesystem::copy: path must be absolute");
366+
}
367+
274368
if (exists(to)) {
275369
return {};
276370
}
@@ -279,6 +373,10 @@ VirtualFilesystem::copy(std::shared_ptr<abstract::File> from, const Path &to) {
279373
}
280374

281375
bool VirtualFilesystem::move(const Path &from, const Path &to) {
376+
if (from.relative() || to.relative()) {
377+
throw InvalidPath("VirtualFilesystem::move: paths must be absolute");
378+
}
379+
282380
if (!copy(from, to)) {
283381
return false;
284382
}

src/odr/internal/html/filesystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class HtmlServiceImpl : public HtmlService {
6565
HtmlResources write_filesystem(HtmlWriter &out) const {
6666
HtmlResources resources;
6767

68-
auto file_walker = m_filesystem.file_walker("");
68+
auto file_walker = m_filesystem.file_walker("/");
6969

7070
out.write_begin();
7171

src/odr/internal/oldms/oldms_file.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ FileMeta parse_meta(const abstract::ReadableFilesystem &storage) {
1414
static const std::unordered_map<common::Path, FileType> types = {
1515
// MS-DOC: The "WordDocument" stream MUST be present in the file.
1616
// https://msdn.microsoft.com/en-us/library/dd926131(v=office.12).aspx
17-
{common::Path("WordDocument"), FileType::legacy_word_document},
17+
{common::Path("/WordDocument"), FileType::legacy_word_document},
1818
// MS-PPT: The "PowerPoint Document" stream MUST be present in the file.
1919
// https://msdn.microsoft.com/en-us/library/dd911009(v=office.12).aspx
20-
{common::Path("PowerPoint Document"),
20+
{common::Path("/PowerPoint Document"),
2121
FileType::legacy_powerpoint_presentation},
2222
// MS-XLS: The "Workbook" stream MUST be present in the file.
2323
// https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ppt/1fc22d56-28f9-4818-bd45-67c2bf721ccf
24-
{common::Path("Workbook"), FileType::legacy_excel_worksheets},
24+
{common::Path("/Workbook"), FileType::legacy_excel_worksheets},
2525
};
2626

2727
FileMeta result;

src/odr/internal/open_strategy.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ open_strategy::list_file_types(const std::shared_ptr<abstract::File> &file,
143143
ODR_VERBOSE(logger, "failed to open as pdf with poppler");
144144
}
145145
#endif
146+
147+
// just to be sure we don't miss any legacy ms files
148+
#ifdef ODR_WITH_WVWARE
149+
try {
150+
ODR_VERBOSE(logger, "try open as legacy ms with wvware");
151+
result.push_back(WvWareLegacyMicrosoftFile(memory_file).file_type());
152+
} catch (...) {
153+
ODR_VERBOSE(logger, "failed to open as legacy ms with wvware");
154+
}
155+
#endif
146156
} else {
147157
ODR_VERBOSE(logger, "anything else");
148158
result.push_back(file_type);
@@ -364,7 +374,7 @@ open_strategy::open_file(std::shared_ptr<abstract::File> file, FileType as,
364374
ODR_VERBOSE(logger, "using wvware engine");
365375
try {
366376
auto memory_file = std::make_shared<common::MemoryFile>(*file);
367-
return std::make_unique<odr::internal::WvWareLegacyMicrosoftFile>(
377+
return std::make_unique<WvWareLegacyMicrosoftFile>(
368378
std::move(memory_file));
369379
} catch (...) {
370380
ODR_VERBOSE(logger, "failed to open as legacy ms with wvware engine");

src/odr/internal/zip/zip_archive.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,15 @@ std::shared_ptr<abstract::Filesystem> ZipArchive::as_filesystem() const {
6060
auto filesystem = std::make_shared<common::VirtualFilesystem>();
6161

6262
for (const auto &e : *this) {
63+
common::Path path = e.path();
64+
if (path.relative()) {
65+
path = common::Path("/").join(path);
66+
}
67+
6368
if (e.is_directory()) {
64-
filesystem->create_directory(e.path());
69+
filesystem->create_directory(path);
6570
} else if (e.is_file()) {
66-
filesystem->copy(e.file(), e.path());
71+
filesystem->copy(e.file(), path);
6772
}
6873
}
6974

0 commit comments

Comments
 (0)