1 #include <stddef.h>
2 #include <stdint.h>
3
4 #include <filesystem>
5 #include <fstream>
6 #include <memory>
7 #include <string>
8 #include <system_error>
9 #include <unistd.h>
10
11 #include "rar.hpp"
12
13 namespace fs = std::__fs::filesystem;
14
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)15 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
16 // unrar likes to create files in the current directory.
17 // So, the following few lines created and 'cd' to a directory named 'o'
18 // in the current working directory.
19 std::error_code code, ok;
20 fs::path original_path = fs::current_path(code);
21 if (code != ok) return 0;
22
23 fs::path out_path = original_path / "o";
24 bool created = fs::create_directory(out_path, code);
25 if (code != ok) return 0;
26
27 fs::current_path(out_path, code);
28 if (code != ok) return 0;
29
30 static const std::string filename = "temp.rar";
31 std::ofstream file(filename,
32 std::ios::binary | std::ios::out | std::ios::trunc);
33 if (!file.is_open()) {
34 return 0;
35 }
36 file.write(reinterpret_cast<const char *>(data), size);
37 file.close();
38
39 std::unique_ptr<CommandData> cmd_data(new CommandData);
40 cmd_data->ParseArg(const_cast<wchar_t *>(L"-p"));
41 cmd_data->ParseArg(const_cast<wchar_t *>(L"x"));
42 cmd_data->ParseDone();
43 std::wstring wide_filename(filename.begin(), filename.end());
44 cmd_data->AddArcName(wide_filename.c_str());
45
46 try {
47 CmdExtract extractor(cmd_data.get());
48 extractor.DoExtract();
49 } catch (...) {
50 }
51
52 unlink(filename.c_str());
53
54 // 'cd' back to the original directory and delete 'o' along with
55 // all its contents.
56 fs::current_path(original_path, code);
57 if (code != ok) return 0;
58 fs::remove_all(out_path, code);
59 if (code != ok) return 0;
60 return 0;
61 }
62