asar coverage - build #127


src/asar/
File: src/asar/virtualfile.cpp
Date: 2024-01-21 09:08:27
Lines:
125/142
88.0%
Functions:
27/27
100.0%
Branches:
94/153
61.4%

Line Branch Exec Source
1 #include <errno.h>
2 #include "virtualfile.h"
3 #include "platform/file-helpers.h"
4 #include "warnings.h"
5
6 class virtual_file
7 {
8 public:
9 1672 virtual ~virtual_file()
10 1672 {
11 1672 }
12
13 virtual void close() = 0;
14
15 virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes) = 0;
16
17 virtual size_t get_size() = 0;
18 };
19
20 class memory_file : public virtual_file
21 {
22 public:
23 36 memory_file(const void* data, size_t length)
24 38 : m_data(data), m_length(length)
25 {
26 36 }
27
28 148 virtual ~memory_file()
29 72 {
30 72 close();
31 148 }
32
33 74 virtual void close()
34 {
35 74 }
36
37 38 virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes)
38 {
39
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36 times.
38 if(pos > m_length) return 0;
40
41 38 int diff = (int)(pos + num_bytes) - (int)m_length;
42 38 num_bytes -= diff < 0 ? 0 : (unsigned int)diff;
43
44 38 memcpy(out_buffer, (const char*)m_data + pos, num_bytes);
45 38 return num_bytes;
46 }
47
48 38 virtual size_t get_size()
49 {
50 38 return m_length;
51 }
52
53 private:
54 const void* m_data;
55 size_t m_length;
56 };
57
58 class physical_file : public virtual_file
59 {
60 public:
61 800 physical_file()
62 1597 : m_file_handle(InvalidFileHandle)
63 {
64 800 }
65
66 6388 virtual ~physical_file()
67 3194 {
68 3194 close();
69 6388 }
70
71 1597 virtual_file_error open(const string& path)
72 {
73
1/2
✓ Branch 0 taken 1597 times.
✗ Branch 1 not taken.
1597 if (path != "")
74 {
75 // randomdude999: checking this before file regularity to improve error messages
76
4/4
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 773 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 776 times.
1597 if(!file_exists((const char*)path)) return vfe_doesnt_exist;
77
4/4
✓ Branch 0 taken 1531 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 758 times.
1549 if(!check_is_regular_file((const char*)path)) return vfe_not_regular_file;
78
79 1513 FileOpenError error = FileOpenError_None;
80
81
1/2
✓ Branch 0 taken 758 times.
✗ Branch 1 not taken.
1513 m_file_handle = open_file((const char*)path, FileOpenMode_Read, &error);
82
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1513 times.
1513 if (m_file_handle == InvalidFileHandle)
84 {
85 if (error == FileOpenError_NotFound)
86 {
87 return vfe_doesnt_exist;
88 }
89 else if (error == FileOpenError_AccessDenied)
90 {
91 return vfe_access_denied;
92 }
93 else
94 {
95 return vfe_unknown;
96 }
97 }
98
99 758 return vfe_none;
100 }
101
102 return vfe_doesnt_exist;
103 }
104
105 3110 virtual void close()
106 {
107
2/2
✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 1597 times.
3110 if (m_file_handle != InvalidFileHandle)
108 {
109 1513 close_file(m_file_handle);
110 1513 m_file_handle = InvalidFileHandle;
111 }
112 3110 }
113
114 1555 virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes)
115 {
116 1555 set_file_pos(m_file_handle, (uint64_t)pos);
117 1555 return (size_t)read_file(m_file_handle, out_buffer, (uint32_t)num_bytes);
118 }
119
120 1513 virtual size_t get_size()
121 {
122 1513 return (size_t)get_file_size(m_file_handle);
123 }
124
125 private:
126 friend class virtual_filesystem;
127
128 FileHandleType m_file_handle;
129 };
130
131
132
133 722 void virtual_filesystem::initialize(const char** include_paths, size_t num_include_paths)
134 {
135 722 m_include_paths.reset();
136
137
2/2
✓ Branch 0 taken 1183 times.
✓ Branch 1 taken 722 times.
1905 for (size_t i = 0; i < num_include_paths; ++i)
138 {
139 1183 m_include_paths[(int)i] = include_paths[i];
140 }
141
142 722 m_last_error = vfe_none;
143 722 m_memory_files.reset();
144 722 }
145
146 722 void virtual_filesystem::destroy()
147 {
148 722 m_include_paths.reset();
149 722 }
150
151
152 1635 virtual_file_handle virtual_filesystem::open_file(const char* path, const char* base_path)
153 {
154 1635 m_last_error = vfe_none;
155
156
1/2
✓ Branch 0 taken 836 times.
✗ Branch 1 not taken.
1635 string absolutepath = create_absolute_path(base_path, path);
157
158
1/2
✓ Branch 0 taken 836 times.
✗ Branch 1 not taken.
1635 virtual_file_type vft = get_file_type_from_path(absolutepath);
159
160
2/2
✓ Branch 0 taken 802 times.
✓ Branch 1 taken 833 times.
1635 if (vft != vft_memory_file)
161 {
162
1/2
✓ Branch 0 taken 1597 times.
✗ Branch 1 not taken.
1597 asar_throw_warning(0, warning_id_check_memory_file, path, (int)warning_id_check_memory_file);
163 }
164
165
2/3
✓ Branch 0 taken 1597 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
1633 switch (vft)
166 {
167 1597 case vft_physical_file:
168 {
169
1/2
✓ Branch 0 taken 1597 times.
✗ Branch 1 not taken.
1597 physical_file* new_file = new physical_file;
170
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 800 times.
800 if (new_file == nullptr)
172 {
173 m_last_error = vfe_unknown;
174 return INVALID_VIRTUAL_FILE_HANDLE;
175 }
176
177
1/2
✓ Branch 0 taken 1597 times.
✗ Branch 1 not taken.
1597 virtual_file_error error = new_file->open(absolutepath);
178
179
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 1513 times.
1597 if (error != vfe_none)
180 {
181
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 delete new_file;
182 84 m_last_error = error;
183 84 return INVALID_VIRTUAL_FILE_HANDLE;
184 }
185
186 758 return static_cast<virtual_file_handle>(new_file);
187 }
188
189 36 case vft_memory_file:
190 {
191
2/4
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
38 if(m_memory_files.exists(absolutepath)) {
192
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
38 memory_buffer mem_buf = m_memory_files.find(absolutepath);
193
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 memory_file* new_file = new memory_file(mem_buf.data, mem_buf.length);
194 36 return static_cast<virtual_file_handle>(new_file);
195 } else {
196 m_last_error = vfe_doesnt_exist;
197 return INVALID_VIRTUAL_FILE_HANDLE;
198 }
199 }
200
201 default:
202 // We should not get here
203 m_last_error = vfe_unknown;
204 return INVALID_VIRTUAL_FILE_HANDLE;
205 }
206 1635 }
207
208 1551 void virtual_filesystem::close_file(virtual_file_handle file_handle)
209 {
210
1/2
✓ Branch 0 taken 1551 times.
✗ Branch 1 not taken.
1551 if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
211 {
212 794 virtual_file* file = static_cast<virtual_file*>(file_handle);
213
214 1551 file->close();
215
216
1/2
✓ Branch 0 taken 794 times.
✗ Branch 1 not taken.
1551 delete file;
217 }
218 1551 }
219
220
221
222 1593 size_t virtual_filesystem::read_file(virtual_file_handle file_handle, void* out_buffer, size_t pos, size_t num_bytes)
223 {
224
1/2
✓ Branch 0 taken 1593 times.
✗ Branch 1 not taken.
1593 if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
225 {
226 815 virtual_file* file = static_cast<virtual_file*>(file_handle);
227
228 1593 return file->read(out_buffer, pos, num_bytes);
229 }
230
231 return 0u;
232 }
233
234 1551 size_t virtual_filesystem::get_file_size(virtual_file_handle file_handle)
235 {
236
1/2
✓ Branch 0 taken 1551 times.
✗ Branch 1 not taken.
1551 if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
237 {
238 794 virtual_file* file = static_cast<virtual_file*>(file_handle);
239
240 1551 return file->get_size();
241 }
242
243 return 0u;
244 }
245
246
247 1635 virtual_filesystem::virtual_file_type virtual_filesystem::get_file_type_from_path(const char* path)
248 {
249
2/2
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 802 times.
1635 if(m_memory_files.exists(path)) {
250 36 return vft_memory_file;
251 } else {
252 1597 return vft_physical_file;
253 }
254 }
255
256 260 void virtual_filesystem::add_memory_file(const char* name, const void* buffer, size_t length) {
257 142 memory_buffer mem_buf = { buffer, length };
258
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
260 string normalized_path = normalize_path(name);
259
1/2
✓ Branch 0 taken 260 times.
✗ Branch 1 not taken.
260 m_memory_files.remove(normalized_path);
260
1/2
✓ Branch 0 taken 260 times.
✗ Branch 1 not taken.
260 m_memory_files.create(normalized_path) = mem_buf;
261 260 }
262
263 11801 bool virtual_filesystem::is_path_absolute(const char* path)
264 {
265 11801 return path_is_absolute(path);
266 }
267
268 29943 string virtual_filesystem::create_absolute_path(const char* base, const char* target)
269 {
270
10/10
✓ Branch 0 taken 27223 times.
✓ Branch 1 taken 2720 times.
✓ Branch 2 taken 24354 times.
✓ Branch 3 taken 2869 times.
✓ Branch 4 taken 24337 times.
✓ Branch 5 taken 17 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 8913 times.
✓ Branch 8 taken 2888 times.
✓ Branch 9 taken 8913 times.
29943 if (is_path_absolute(target) || base == nullptr || base[0] == '\0')
271 {
272
1/2
✓ Branch 0 taken 2888 times.
✗ Branch 1 not taken.
5619 return normalize_path(target);
273 }
274
275
1/2
✓ Branch 0 taken 8913 times.
✗ Branch 1 not taken.
8913 string path_to_use = "";
276
1/2
✓ Branch 0 taken 8913 times.
✗ Branch 1 not taken.
8913 string test_path = "";
277
278
2/4
✓ Branch 0 taken 24324 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24324 times.
✗ Branch 3 not taken.
24324 test_path = normalize_path(target);
279
280 // First check if path is absolute
281
2/4
✓ Branch 0 taken 24324 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24324 times.
24324 if (path_is_absolute(test_path))
282 {
283 if (m_memory_files.exists(test_path) || file_exists(test_path))
284 {
285 path_to_use = test_path;
286 }
287 }
288 else
289 {
290 // Now check if path exists relative to the base path
291
1/2
✓ Branch 0 taken 8913 times.
✗ Branch 1 not taken.
8913 if (base != nullptr)
292 {
293
3/6
✓ Branch 0 taken 24324 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24324 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8913 times.
✗ Branch 5 not taken.
24324 test_path = create_combined_path(dir(base), target);
294 }
295
296
10/12
✓ Branch 0 taken 24324 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24324 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24321 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 8961 times.
✓ Branch 7 taken 15360 times.
✓ Branch 8 taken 8850 times.
✓ Branch 9 taken 60 times.
✓ Branch 10 taken 8853 times.
✓ Branch 11 taken 60 times.
24324 if (test_path != "" && (m_memory_files.exists(test_path) || file_exists(test_path)))
297 {
298
1/2
✓ Branch 0 taken 8853 times.
✗ Branch 1 not taken.
8853 path_to_use = test_path;
299 }
300 else
301 {
302 // Finally check if path exists relative to any include path
303 60 bool found = false;
304
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 90 times.
304 for (int i = 0; i < m_include_paths.count; ++i)
305 {
306
3/6
✓ Branch 0 taken 214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
✗ Branch 5 not taken.
214 test_path = create_combined_path(m_include_paths[i], target);
307
308
9/10
✓ Branch 0 taken 214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 205 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 199 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 101 times.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 101 times.
214 if (m_memory_files.exists(test_path) || file_exists(test_path))
309 {
310 15 found = true;
311
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 path_to_use = test_path;
312 15 break;
313 }
314 }
315
316
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 15 times.
60 if (!found)
317 {
318 // Reset our path so that we don't return an empty one
319 // (that will do some weird shit and fuck up error messages)
320
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 path_to_use = target;
321 }
322 }
323 }
324
325
1/2
✓ Branch 0 taken 8913 times.
✗ Branch 1 not taken.
8913 return path_to_use;
326 24324 }
327