/src/edk2/MdeModulePkg/Universal/Disk/UdfDxe/FileName.c
Line | Count | Source |
1 | | /** @file |
2 | | Helper functions for mangling file names in UDF/ECMA-167 file systems. |
3 | | |
4 | | Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com> |
5 | | |
6 | | SPDX-License-Identifier: BSD-2-Clause-Patent |
7 | | **/ |
8 | | |
9 | | #include "Udf.h" |
10 | | |
11 | | /** |
12 | | Trim the leading and trailing spaces for a give Unicode string. |
13 | | |
14 | | @param[in] String The Unicode string to trim. |
15 | | |
16 | | @return A pointer to the trimmed string. |
17 | | |
18 | | **/ |
19 | | CHAR16 * |
20 | | TrimString ( |
21 | | IN CHAR16 *String |
22 | | ) |
23 | 408 | { |
24 | 408 | CHAR16 *TempString; |
25 | | |
26 | 665 | for ( ; *String != L'\0' && *String == L' '; String++) { |
27 | 257 | } |
28 | | |
29 | 408 | TempString = String + StrLen (String) - 1; |
30 | 466 | while ((TempString >= String) && (*TempString == L' ')) { |
31 | 58 | TempString--; |
32 | 58 | } |
33 | | |
34 | 408 | *(TempString + 1) = L'\0'; |
35 | | |
36 | 408 | return String; |
37 | 408 | } |
38 | | |
39 | | /** |
40 | | Replace the content of a Unicode string with the content of another Unicode |
41 | | string. |
42 | | |
43 | | @param[in] Destination A pointer to a Unicode string. |
44 | | @param[in] Source A pointer to a Unicode string. |
45 | | |
46 | | **/ |
47 | | VOID |
48 | | ReplaceLeft ( |
49 | | IN CHAR16 *Destination, |
50 | | IN CONST CHAR16 *Source |
51 | | ) |
52 | 2.21k | { |
53 | 2.21k | CONST CHAR16 *EndString; |
54 | | |
55 | 2.21k | EndString = Source + StrLen (Source); |
56 | 906k | while (Source <= EndString) { |
57 | 904k | *Destination++ = *Source++; |
58 | 904k | } |
59 | 2.21k | } |
60 | | |
61 | | /** |
62 | | Remove one or more consecutive backslashes starting from the second character |
63 | | of a given Unicode string. |
64 | | |
65 | | @param[in] String A pointer to a Unicode string. |
66 | | |
67 | | @return A pointer to the modified string. |
68 | | |
69 | | **/ |
70 | | CHAR16 * |
71 | | ExcludeTrailingBackslashes ( |
72 | | IN CHAR16 *String |
73 | | ) |
74 | 2.70k | { |
75 | 2.70k | CHAR16 *TempString; |
76 | | |
77 | 2.70k | switch (*(String + 1)) { |
78 | 956 | case L'\\': |
79 | 956 | break; |
80 | 22 | case L'\0': |
81 | 1.75k | default: |
82 | 1.75k | String++; |
83 | 1.75k | goto Exit; |
84 | 2.70k | } |
85 | | |
86 | 956 | TempString = String; |
87 | 3.60k | while (*TempString == L'\\') { |
88 | 2.64k | TempString++; |
89 | 2.64k | } |
90 | | |
91 | 956 | if (TempString - 1 > String) { |
92 | 956 | ReplaceLeft (String + 1, TempString); |
93 | 956 | } |
94 | | |
95 | 956 | String++; |
96 | | |
97 | 2.70k | Exit: |
98 | 2.70k | return String; |
99 | 956 | } |
100 | | |
101 | | /** |
102 | | Mangle a filename by cutting off trailing whitespaces, "\\", "." and "..". |
103 | | |
104 | | @param[in] FileName Filename. |
105 | | |
106 | | @retval The mangled Filename. |
107 | | |
108 | | **/ |
109 | | CHAR16 * |
110 | | MangleFileName ( |
111 | | IN CHAR16 *FileName |
112 | | ) |
113 | 413 | { |
114 | 413 | CHAR16 *FileNameSavedPointer; |
115 | 413 | CHAR16 *TempFileName; |
116 | 413 | UINTN BackslashesNo; |
117 | | |
118 | 413 | if ((FileName == NULL) || (*FileName == L'\0')) { |
119 | 5 | FileName = NULL; |
120 | 5 | goto Exit; |
121 | 5 | } |
122 | | |
123 | 408 | FileName = TrimString (FileName); |
124 | 408 | if (*FileName == L'\0') { |
125 | 8 | goto Exit; |
126 | 8 | } |
127 | | |
128 | 400 | if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) { |
129 | 40 | FileName[StrLen (FileName) - 1] = L'\0'; |
130 | 40 | } |
131 | | |
132 | 400 | FileNameSavedPointer = FileName; |
133 | | |
134 | 400 | if (FileName[0] == L'.') { |
135 | 127 | if (FileName[1] == L'.') { |
136 | 29 | if (FileName[2] == L'\0') { |
137 | 1 | goto Exit; |
138 | 28 | } else { |
139 | 28 | FileName += 2; |
140 | 28 | } |
141 | 98 | } else if (FileName[1] == L'\0') { |
142 | 1 | goto Exit; |
143 | 1 | } |
144 | 127 | } |
145 | | |
146 | 26.0k | while (*FileName != L'\0') { |
147 | 25.6k | if (*FileName == L'\\') { |
148 | 1.45k | FileName = ExcludeTrailingBackslashes (FileName); |
149 | 24.2k | } else if (*FileName == L'.') { |
150 | 3.41k | switch (*(FileName + 1)) { |
151 | 29 | case L'\0': |
152 | 29 | *FileName = L'\0'; |
153 | 29 | break; |
154 | 781 | case L'\\': |
155 | 781 | TempFileName = FileName + 1; |
156 | 781 | TempFileName = ExcludeTrailingBackslashes (TempFileName); |
157 | 781 | ReplaceLeft (FileName, TempFileName); |
158 | 781 | break; |
159 | 1.46k | case L'.': |
160 | 1.46k | if (FileName - 1 >= FileNameSavedPointer && *(FileName - 1) != L'\\' && |
161 | 1.22k | *(FileName + 2) != L'\\' && *(FileName + 2) != L'\0') |
162 | 879 | { |
163 | 879 | FileName++; |
164 | 879 | continue; |
165 | 879 | } |
166 | | |
167 | 588 | BackslashesNo = 0; |
168 | 588 | TempFileName = FileName - 1; |
169 | 9.00k | while (TempFileName >= FileNameSavedPointer) { |
170 | 8.91k | if (*TempFileName == L'\\') { |
171 | 1.05k | if (++BackslashesNo == 2) { |
172 | 498 | break; |
173 | 498 | } |
174 | 1.05k | } |
175 | | |
176 | 8.41k | TempFileName--; |
177 | 8.41k | } |
178 | | |
179 | 588 | TempFileName++; |
180 | | |
181 | 588 | if ((*TempFileName == L'.') && (*(TempFileName + 1) == L'.')) { |
182 | 88 | FileName += 2; |
183 | 500 | } else { |
184 | 500 | if (TempFileName - 1 >= FileNameSavedPointer && *(TempFileName - 1) == L'\\') { |
185 | 476 | ReplaceLeft (TempFileName, FileName + 3); |
186 | 476 | if (*(TempFileName - 1) == L'\\') { |
187 | 476 | FileName = TempFileName; |
188 | 476 | ExcludeTrailingBackslashes (TempFileName - 1); |
189 | 476 | TempFileName = FileName; |
190 | 476 | } |
191 | 476 | } else { |
192 | 24 | *TempFileName = L'\0'; |
193 | 24 | } |
194 | | |
195 | 500 | FileName = TempFileName; |
196 | 500 | } |
197 | | |
198 | 588 | break; |
199 | 1.13k | default: |
200 | 1.13k | FileName++; |
201 | 3.41k | } |
202 | 20.8k | } else { |
203 | 20.8k | FileName++; |
204 | 20.8k | } |
205 | 25.6k | } |
206 | | |
207 | 398 | FileName = FileNameSavedPointer; |
208 | 398 | if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) { |
209 | 39 | FileName[StrLen (FileName) - 1] = L'\0'; |
210 | 39 | } |
211 | | |
212 | 413 | Exit: |
213 | 413 | return FileName; |
214 | 398 | } |