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