asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
60 of 67, 0 excluded
89.6%
Functions:
3 of 4, 0 excluded
75.0%
Branches:
114 of 175, 0 excluded
65.1%

platform/file-helpers.cpp
Line Branch Exec Source
1 #include "platform/file-helpers.h"
2
3
4 // This function is based in part on nall, which is under the following licence.
5 // This modified version is licenced under the LGPL version 3 or later. See the LICENSE file
6 // for details.
7 //
8 // Copyright (c) 2006-2015 byuu
9 //
10 // Permission to use, copy, modify, and/or distribute this software for
11 // any purpose with or without fee is hereby granted, provided that the
12 // above copyright notice and this permission notice appear in all
13 // copies.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
16 // WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
18 // AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
19 // DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
20 // PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 // PERFORMANCE OF THIS SOFTWARE.
23 20713 string dir(char const *name)
24 {
25
4/6
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 10372 times.
✓ Branch 7 → 3 taken 140787 times.
✗ Branch 7 → 8 not taken.
✓ Branch 13 → 5 taken 141022 times.
✓ Branch 13 → 14 taken 1 time.
281810 for (signed i = (int)strlen(name); i >= 0; i--)
26 {
27
6/8
✓ Branch 3 → 4 taken 130446 times.
✓ Branch 3 → 5 taken 10341 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 130446 times.
✓ Branch 7 → 8 taken 130651 times.
✓ Branch 7 → 11 taken 10371 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 130651 times.
281809 if (name[i] == '/' || name[i] == '\\')
28 {
29 20712 return string(name, i+1);
30 }
31 }
32 1 return "";
33 }
34
35 10332 string create_combined_path(const char* path1, const char* path2)
36 {
37
2/4
✓ Branch 2 → 3 taken 5136 times.
✗ Branch 2 → 22 not taken.
✓ Branch 3 → 4 taken 5196 times.
✗ Branch 3 → 28 not taken.
10332 string combined = path1;
38
39 10332 int length = combined.length();
40
41
9/15
✓ Branch 5 → 6 taken 5136 times.
✗ Branch 5 → 9 not taken.
✓ Branch 6 → 7 taken 10332 times.
✗ Branch 6 → 9 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5136 times.
✓ Branch 9 → 10 taken 5196 times.
✗ Branch 9 → 14 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 13 taken 5136 times.
✓ Branch 12 → 13 taken 33 times.
✓ Branch 12 → 14 taken 5163 times.
✓ Branch 15 → 16 taken 33 times.
✓ Branch 15 → 18 taken 5163 times.
10332 if (combined.length() > 0 && path1[length - 1] != '\\' && path1[length - 1] != '/')
42 {
43
2/8
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 20 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 20 not taken.
✓ Branch 16 → 17 taken 33 times.
✗ Branch 16 → 26 not taken.
✓ Branch 17 → 18 taken 33 times.
✗ Branch 17 → 26 not taken.
33 combined += get_native_path_separator();
44 }
45
46
2/4
✓ Branch 13 → 14 taken 5136 times.
✗ Branch 13 → 20 not taken.
✓ Branch 18 → 19 taken 5196 times.
✗ Branch 18 → 26 not taken.
10332 combined += path2;
47
48
2/4
✓ Branch 15 → 16 taken 5136 times.
✗ Branch 15 → 20 not taken.
✓ Branch 21 → 22 taken 5196 times.
✗ Branch 21 → 26 not taken.
20664 return normalize_path(combined);
49 10332 }
50
51
52 // RPG Hacker: This function attempts to normalize a path.
53 // This means that it attempts to put it into a format
54 // where a simple string compare between two paths
55 // referring to the same file will hopefully always
56 // succeed.
57 // There are a few known problems and limitations:
58 // - Relative paths are not recommended, as they can't be
59 // resolved reliably. For example, in this path
60 // ../patch/main.asm
61 // we can't collapse the .. because we don't know the
62 // parent directory. A comparison will also fail when
63 // one piece of code uses a relative path while another
64 // piece of code uses an absolute path. For those
65 // reasons, it's recommended to always use absolute paths
66 // everywhere if possible.
67 // - Windows network paths like
68 // \\MY_PC\patch\main.asm
69 // Will likely break with this, since the function converts
70 // all back slashes to forward slashes. I think Windows
71 // actually requires back slashes for network paths.
72 // - Currently, the code doesn't look at drive letters
73 // and just treats them as folders, so a path like
74 // C:/../patch/main.asm
75 // would result in
76 // patch/main.asm
77 // (However, a path like that is invalid, anyways, so
78 // this hopefully doesn't matter).
79 22902 string normalize_path(const char* path)
80 {
81
1/4
✓ Branch 2 → 3 taken 22902 times.
✗ Branch 2 → 66 not taken.
✗ Branch 2 → 68 not taken.
✗ Branch 2 → 103 not taken.
22902 string normalized = path;
82
83
84 // RPG Hacker: Replace all \ in path by /
85 // (Windows should work with / in paths just fine).
86 // Note: will likely break network paths on Windows,
87 // which still expect a prefix of \\, but does anyone
88 // seriously even use them with Asar?
89
4/4
✓ Branch 10 → 4 taken 354907 times.
✓ Branch 10 → 11 taken 11270 times.
✓ Branch 14 → 4 taken 361263 times.
✓ Branch 14 → 15 taken 11632 times.
739072 for (int i = 0; i < normalized.length(); ++i)
90 {
91
2/4
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 354907 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 12 taken 361263 times.
716170 if (normalized[i] == '\\')
92 {
93 normalized.temp_raw()[i]= '/';
94 }
95 }
96
97 // RPG Hacker: Collapse path by removing all unnecessary
98 // . or .. path components.
99 // As a little hack, just overwrite all the stuff we're
100 // going to remove with 0x01 and remove it later. Probably
101 // easier than to always shorten the path immediately.
102 // Also using \x01 instead of \0 so that the path is still
103 // easily readable in a debugger (since it normally just
104 // assumes a string to end at \0). I don't think \x01 can
105 // be used in valid paths, so this should be okay.
106 22902 char* previous_dir_start_pos = nullptr;
107 22902 char* current_dir_start_pos = normalized.temp_raw();
108
3/4
✗ Branch 14 → 13 not taken.
✓ Branch 14 → 15 taken 11270 times.
✓ Branch 20 → 17 taken 6463 times.
✓ Branch 20 → 21 taken 11632 times.
29365 while (*current_dir_start_pos == '/')
109 {
110 6463 ++current_dir_start_pos;
111 }
112 22902 char* current_dir_end_pos = current_dir_start_pos;
113
114
115
4/4
✓ Branch 48 → 16 taken 47398 times.
✓ Branch 48 → 49 taken 11270 times.
✓ Branch 80 → 22 taken 46247 times.
✓ Branch 80 → 81 taken 11632 times.
116547 while (*current_dir_start_pos != '\0')
116 {
117
8/8
✓ Branch 18 → 19 taken 330058 times.
✓ Branch 18 → 20 taken 36128 times.
✓ Branch 19 → 17 taken 318788 times.
✓ Branch 19 → 20 taken 11270 times.
✓ Branch 26 → 27 taken 332573 times.
✓ Branch 26 → 29 taken 34616 times.
✓ Branch 28 → 23 taken 320942 times.
✓ Branch 28 → 29 taken 11631 times.
733375 while (*current_dir_end_pos != '/' && *current_dir_end_pos != '\0')
118 {
119 639730 ++current_dir_end_pos;
120 }
121
122 93645 size_t length = (size_t)(current_dir_end_pos - current_dir_start_pos);
123
9/10
✓ Branch 20 → 21 taken 47389 times.
✓ Branch 20 → 28 taken 9 times.
✓ Branch 21 → 22 taken 36 times.
✓ Branch 21 → 28 taken 47353 times.
✓ Branch 29 → 30 taken 45489 times.
✓ Branch 29 → 44 taken 758 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 45489 times.
✓ Branch 32 → 33 taken 36 times.
✓ Branch 32 → 44 taken 45453 times.
93645 if (length > 0 && strncmp(current_dir_start_pos, ".", length) == 0)
124 {
125 // Found a . path component - remove it.
126
4/4
✓ Branch 24 → 23 taken 36 times.
✓ Branch 24 → 25 taken 36 times.
✓ Branch 37 → 34 taken 36 times.
✓ Branch 37 → 38 taken 36 times.
144 while (current_dir_start_pos != current_dir_end_pos)
127 {
128 72 *current_dir_start_pos = '\x01';
129 72 ++current_dir_start_pos;
130 }
131
132
2/4
✓ Branch 25 → 26 taken 36 times.
✗ Branch 25 → 27 not taken.
✓ Branch 39 → 40 taken 36 times.
✗ Branch 39 → 43 not taken.
72 if (*current_dir_start_pos == '/')
133 {
134 72 *current_dir_start_pos = '\x01';
135 72 ++current_dir_end_pos;
136 }
137 }
138
9/10
✓ Branch 28 → 29 taken 47353 times.
✓ Branch 28 → 43 taken 9 times.
✓ Branch 29 → 30 taken 48 times.
✓ Branch 29 → 43 taken 47305 times.
✓ Branch 44 → 45 taken 45453 times.
✓ Branch 44 → 72 taken 758 times.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 45453 times.
✓ Branch 47 → 48 taken 1857 times.
✓ Branch 47 → 72 taken 43596 times.
93573 else if (length > 0 && strncmp(current_dir_start_pos, "..", length) == 0)
139 {
140 // Found a .. path component - if we have any known
141 // folder before it, remove them both.
142
4/4
✓ Branch 30 → 31 taken 36 times.
✓ Branch 30 → 42 taken 12 times.
✓ Branch 48 → 49 taken 1096 times.
✓ Branch 48 → 71 taken 761 times.
1905 if (previous_dir_start_pos != nullptr)
143 {
144 // previous_dir_start_pos and current_dir_start_pos are immediately
145 // set to something else shortly after, so it should be
146 // okay to move them directly here and not use a
147 // temporary variable.
148
6/8
✓ Branch 33 → 34 taken 180 times.
✓ Branch 33 → 35 taken 36 times.
✓ Branch 34 → 32 taken 180 times.
✗ Branch 34 → 35 not taken.
✓ Branch 54 → 55 taken 4858 times.
✓ Branch 54 → 57 taken 1096 times.
✓ Branch 56 → 50 taken 4858 times.
✗ Branch 56 → 57 not taken.
6170 while (*previous_dir_start_pos != '/' && *previous_dir_start_pos != '\0')
149 {
150 5038 *previous_dir_start_pos = '\x01';
151 5038 ++previous_dir_start_pos;
152 }
153
154
2/4
✓ Branch 35 → 36 taken 36 times.
✗ Branch 35 → 37 not taken.
✓ Branch 58 → 59 taken 1096 times.
✗ Branch 58 → 61 not taken.
1132 if (*previous_dir_start_pos == '/')
155 {
156 1132 *previous_dir_start_pos = '\x01';
157 }
158
159
4/4
✓ Branch 39 → 38 taken 72 times.
✓ Branch 39 → 40 taken 36 times.
✓ Branch 65 → 62 taken 2192 times.
✓ Branch 65 → 66 taken 1096 times.
3396 while (current_dir_start_pos != current_dir_end_pos)
160 {
161 2264 *current_dir_start_pos = '\x01';
162 2264 ++current_dir_start_pos;
163 }
164
165
4/4
✓ Branch 40 → 41 taken 33 times.
✓ Branch 40 → 42 taken 3 times.
✓ Branch 67 → 68 taken 1093 times.
✓ Branch 67 → 71 taken 3 times.
1132 if (*current_dir_start_pos == '/')
166 {
167 1126 *current_dir_start_pos = '\x01';
168 1126 ++current_dir_end_pos;
169 }
170 }
171
172 1905 previous_dir_start_pos = nullptr;
173 }
174 else
175 {
176
4/4
✓ Branch 43 → 44 taken 36050 times.
✓ Branch 43 → 45 taken 11264 times.
✓ Branch 73 → 74 taken 32729 times.
✓ Branch 73 → 76 taken 11625 times.
91668 if (*current_dir_end_pos == '/')
177 {
178 68779 ++current_dir_end_pos;
179 }
180
181
4/4
✓ Branch 45 → 46 taken 47305 times.
✓ Branch 45 → 47 taken 9 times.
✓ Branch 76 → 77 taken 43596 times.
✓ Branch 76 → 78 taken 758 times.
91668 if (length > 0)
182 {
183 90901 previous_dir_start_pos = current_dir_start_pos;
184 }
185 }
186
187 93645 current_dir_start_pos = current_dir_end_pos;
188 }
189
190
191 // Now construct our new string by copying everything but the \x01 into it.
192 22902 string copy;
193
194
4/4
✓ Branch 57 → 51 taken 354907 times.
✓ Branch 57 → 58 taken 11270 times.
✓ Branch 94 → 84 taken 361263 times.
✓ Branch 94 → 95 taken 11632 times.
739072 for (int i = 0; i < normalized.length(); ++i)
195 {
196
4/4
✓ Branch 52 → 53 taken 354514 times.
✓ Branch 52 → 55 taken 393 times.
✓ Branch 87 → 88 taken 351952 times.
✓ Branch 87 → 92 taken 9311 times.
716170 if (normalized[i] != '\x01')
197 {
198
2/5
✓ Branch 54 → 55 taken 354514 times.
✗ Branch 54 → 62 not taken.
✗ Branch 54 → 64 not taken.
✓ Branch 91 → 92 taken 351952 times.
✗ Branch 91 → 99 not taken.
706466 copy += normalized[i];
199 }
200 }
201
202
2/5
✓ Branch 58 → 59 taken 11270 times.
✗ Branch 58 → 62 not taken.
✗ Branch 58 → 64 not taken.
✓ Branch 95 → 96 taken 11632 times.
✗ Branch 95 → 99 not taken.
22902 normalized = copy;
203
204
205 // RPG Hacker: On Windows, file paths are case-insensitive.
206 // It isn't really good style to mix different cases, especially
207 // when referring to the same file, but it's theoretically possible
208 // to do so, so we need to handle it and not have Asar fail in this case.
209 // The easiest way to handle it is to convert the entire path to lowercase.
210 #if defined(windows)
211
1/2
✓ Branch 60 → 61 taken 11270 times.
✗ Branch 60 → 64 not taken.
11270 normalized = lower(normalized);
212 #endif
213
214
215 // TODO: Maybe resolve symbolic links here?
216 // Not sure if it's a good idea and if it's needed in the first place.
217 // In theory, it could lead to some problems with files that exist
218 // only in memory.
219 22902 return normalized;
220 22902 }
221
222 string get_base_name(char const *name)
223 {
224 for(int i = (int)strlen(name); i >= 0; --i)
225 {
226 if(name[i] == '/' || name[i] == '\\')
227 {
228 //file has no extension
229 break;
230 }
231 if(name[i] == '.')
232 {
233 return string(name, i);
234 }
235 }
236 return string(name);
237 }
238