Coverage Report

Created: 2026-03-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}