]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/UdfDxe/FileName.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / UdfDxe / FileName.c
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 {
24 CHAR16 *TempString;
25
26 for ( ; *String != L'\0' && *String == L' '; String++) {
27 ;
28 }
29
30 TempString = String + StrLen (String) - 1;
31 while ((TempString >= String) && (*TempString == L' ')) {
32 TempString--;
33 }
34
35 *(TempString + 1) = L'\0';
36
37 return String;
38 }
39
40 /**
41 Replace the content of a Unicode string with the content of another Unicode
42 string.
43
44 @param[in] Destination A pointer to a Unicode string.
45 @param[in] Source A pointer to a Unicode string.
46
47 **/
48 VOID
49 ReplaceLeft (
50 IN CHAR16 *Destination,
51 IN CONST CHAR16 *Source
52 )
53 {
54 CONST CHAR16 *EndString;
55
56 EndString = Source + StrLen (Source);
57 while (Source <= EndString) {
58 *Destination++ = *Source++;
59 }
60 }
61
62 /**
63 Remove one or more consecutive backslashes starting from the second character
64 of a given Unicode string.
65
66 @param[in] String A pointer to a Unicode string.
67
68 @return A pointer to the modified string.
69
70 **/
71 CHAR16 *
72 ExcludeTrailingBackslashes (
73 IN CHAR16 *String
74 )
75 {
76 CHAR16 *TempString;
77
78 switch (*(String + 1)) {
79 case L'\\':
80 break;
81 case L'\0':
82 default:
83 String++;
84 goto Exit;
85 }
86
87 TempString = String;
88 while (*TempString != L'\0' && *TempString == L'\\') {
89 TempString++;
90 }
91
92 if (TempString - 1 > String) {
93 ReplaceLeft (String + 1, TempString);
94 }
95
96 String++;
97
98 Exit:
99 return String;
100 }
101
102 /**
103 Mangle a filename by cutting off trailing whitespaces, "\\", "." and "..".
104
105 @param[in] FileName Filename.
106
107 @retval The mangled Filename.
108
109 **/
110 CHAR16 *
111 MangleFileName (
112 IN CHAR16 *FileName
113 )
114 {
115 CHAR16 *FileNameSavedPointer;
116 CHAR16 *TempFileName;
117 UINTN BackslashesNo;
118
119 if (FileName == NULL || *FileName == L'\0') {
120 FileName = NULL;
121 goto Exit;
122 }
123
124 FileName = TrimString (FileName);
125 if (*FileName == L'\0') {
126 goto Exit;
127 }
128
129 if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) {
130 FileName[StrLen (FileName) - 1] = L'\0';
131 }
132
133 FileNameSavedPointer = FileName;
134
135 if (FileName[0] == L'.') {
136 if (FileName[1] == L'.') {
137 if (FileName[2] == L'\0') {
138 goto Exit;
139 } else {
140 FileName += 2;
141 }
142 } else if (FileName[1] == L'\0') {
143 goto Exit;
144 }
145 }
146
147 while (*FileName != L'\0') {
148 if (*FileName == L'\\') {
149 FileName = ExcludeTrailingBackslashes (FileName);
150 } else if (*FileName == L'.') {
151 switch (*(FileName + 1)) {
152 case L'\0':
153 *FileName = L'\0';
154 break;
155 case L'\\':
156 TempFileName = FileName + 1;
157 TempFileName = ExcludeTrailingBackslashes (TempFileName);
158 ReplaceLeft (FileName, TempFileName);
159 break;
160 case '.':
161 if ((*(FileName - 1) != L'\\') && ((*(FileName + 2) != L'\\') ||
162 (*(FileName + 2) != L'\0'))) {
163 FileName++;
164 continue;
165 }
166
167 BackslashesNo = 0;
168 TempFileName = FileName - 1;
169 while (TempFileName >= FileNameSavedPointer) {
170 if (*TempFileName == L'\\') {
171 if (++BackslashesNo == 2) {
172 break;
173 }
174 }
175
176 TempFileName--;
177 }
178
179 TempFileName++;
180
181 if ((*TempFileName == L'.') && (*(TempFileName + 1) == L'.')) {
182 FileName += 2;
183 } else {
184 if (*(FileName + 2) != L'\0') {
185 ReplaceLeft (TempFileName, FileName + 3);
186 if (*(TempFileName - 1) == L'\\') {
187 FileName = TempFileName;
188 ExcludeTrailingBackslashes (TempFileName - 1);
189 TempFileName = FileName;
190 }
191 } else {
192 *TempFileName = L'\0';
193 }
194
195 FileName = TempFileName;
196 }
197
198 break;
199 default:
200 FileName++;
201 }
202 } else {
203 FileName++;
204 }
205 }
206
207 FileName = FileNameSavedPointer;
208 if ((StrLen (FileName) > 1) && (FileName [StrLen (FileName) - 1] == L'\\')) {
209 FileName [StrLen (FileName) - 1] = L'\0';
210 }
211
212 Exit:
213 return FileName;
214 }