Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/winpr/libwinpr/path/include/PathAllocCombine.c
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
#define DEFINE_UNICODE    FALSE
4
#define CUR_PATH_SEPARATOR_CHR  '\\'
5
#define CUR_PATH_SEPARATOR_STR  "\\"
6
#define PATH_ALLOC_COMBINE  PathAllocCombineA
7
*/
8
9
/**
10
 * FIXME: These implementations of the PathAllocCombine functions have
11
 * several issues:
12
 * - pszPathIn or pszMore may be NULL (but not both)
13
 * - no check if pszMore is fully qualified (if so, it must be directly
14
 *   copied to the output buffer without being combined with pszPathIn.
15
 * - if pszMore begins with a _single_ backslash it must be combined with
16
 *   only the root of the path pointed to by pszPathIn and there's no code
17
 *   to extract the root of pszPathIn.
18
 * - the function will crash with some short string lengths of the parameters
19
 */
20
21
#if DEFINE_UNICODE
22
23
HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
24
                           PWSTR* ppszPathOut)
25
0
{
26
0
  PWSTR pszPathOut;
27
0
  BOOL backslashIn;
28
0
  BOOL backslashMore;
29
0
  size_t pszMoreLength;
30
0
  size_t pszPathInLength;
31
0
  size_t pszPathOutLength;
32
0
  WLog_WARN(TAG, "has known bugs and needs fixing.");
33
34
0
  if (!ppszPathOut)
35
0
    return E_INVALIDARG;
36
37
0
  if (!pszPathIn && !pszMore)
38
0
    return E_INVALIDARG;
39
40
0
  if (!pszMore)
41
0
    return E_FAIL; /* valid but not implemented, see top comment */
42
43
0
  if (!pszPathIn)
44
0
    return E_FAIL; /* valid but not implemented, see top comment */
45
46
0
  pszPathInLength = _wcslen(pszPathIn);
47
0
  pszMoreLength = _wcslen(pszMore);
48
49
  /* prevent segfaults - the complete implementation below is buggy */
50
0
  if (pszPathInLength < 3)
51
0
    return E_FAIL;
52
53
0
  backslashIn = (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
54
0
  backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
55
56
0
  if (backslashMore)
57
0
  {
58
0
    if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
59
0
    {
60
0
      const WCHAR colon[] = { ':', '\0' };
61
0
      size_t sizeOfBuffer;
62
0
      pszPathOutLength = sizeof(WCHAR) + pszMoreLength;
63
0
      sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
64
0
      pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR));
65
66
0
      if (!pszPathOut)
67
0
        return E_OUTOFMEMORY;
68
69
0
      _wcsncat(pszPathOut, &pszPathIn[0], 1);
70
0
      _wcsncat(pszPathOut, colon, ARRAYSIZE(colon));
71
0
      _wcsncat(pszPathOut, pszMore, pszMoreLength);
72
0
      *ppszPathOut = pszPathOut;
73
0
      return S_OK;
74
0
    }
75
0
  }
76
0
  else
77
0
  {
78
0
    const WCHAR sep[] = CUR_PATH_SEPARATOR_STR;
79
0
    size_t sizeOfBuffer;
80
0
    pszPathOutLength = pszPathInLength + pszMoreLength;
81
0
    sizeOfBuffer = (pszPathOutLength + 1) * 2;
82
0
    pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2);
83
84
0
    if (!pszPathOut)
85
0
      return E_OUTOFMEMORY;
86
87
0
    _wcsncat(pszPathOut, pszPathIn, pszPathInLength);
88
0
    if (!backslashIn)
89
0
      _wcsncat(pszPathOut, sep, ARRAYSIZE(sep));
90
0
    _wcsncat(pszPathOut, pszMore, pszMoreLength);
91
92
0
    *ppszPathOut = pszPathOut;
93
0
    return S_OK;
94
0
  }
95
96
0
  return E_FAIL;
97
0
}
Unexecuted instantiation: PathAllocCombineW
Unexecuted instantiation: UnixPathAllocCombineW
Unexecuted instantiation: NativePathAllocCombineW
98
99
#else
100
101
HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut)
102
0
{
103
0
  PSTR pszPathOut;
104
0
  BOOL backslashIn;
105
0
  BOOL backslashMore;
106
0
  int pszMoreLength;
107
0
  int pszPathInLength;
108
0
  int pszPathOutLength;
109
0
  WLog_WARN(TAG, "has known bugs and needs fixing.");
110
111
0
  if (!ppszPathOut)
112
0
    return E_INVALIDARG;
113
114
0
  if (!pszPathIn && !pszMore)
115
0
    return E_INVALIDARG;
116
117
0
  if (!pszMore)
118
0
    return E_FAIL; /* valid but not implemented, see top comment */
119
120
0
  if (!pszPathIn)
121
0
    return E_FAIL; /* valid but not implemented, see top comment */
122
123
0
  pszPathInLength = strlen(pszPathIn);
124
0
  pszMoreLength = strlen(pszMore);
125
126
  /* prevent segfaults - the complete implementation below is buggy */
127
0
  if (pszPathInLength < 3)
128
0
    return E_FAIL;
129
130
0
  backslashIn = (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
131
0
  backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
132
133
0
  if (backslashMore)
134
0
  {
135
0
    if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
136
0
    {
137
0
      size_t sizeOfBuffer;
138
0
      pszPathOutLength = 2 + pszMoreLength;
139
0
      sizeOfBuffer = (pszPathOutLength + 1) * 2;
140
0
      pszPathOut = (PSTR)calloc(sizeOfBuffer, 2);
141
142
0
      if (!pszPathOut)
143
0
        return E_OUTOFMEMORY;
144
145
0
      sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore);
146
0
      *ppszPathOut = pszPathOut;
147
0
      return S_OK;
148
0
    }
149
0
  }
150
0
  else
151
0
  {
152
0
    size_t sizeOfBuffer;
153
0
    pszPathOutLength = pszPathInLength + pszMoreLength;
154
0
    sizeOfBuffer = (pszPathOutLength + 1) * 2;
155
0
    pszPathOut = (PSTR)calloc(sizeOfBuffer, 2);
156
157
0
    if (!pszPathOut)
158
0
      return E_OUTOFMEMORY;
159
160
0
    if (backslashIn)
161
0
      sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore);
162
0
    else
163
0
      sprintf_s(pszPathOut, sizeOfBuffer, "%s" CUR_PATH_SEPARATOR_STR "%s", pszPathIn,
164
0
                pszMore);
165
166
0
    *ppszPathOut = pszPathOut;
167
0
    return S_OK;
168
0
  }
169
170
0
  return E_FAIL;
171
0
}
Unexecuted instantiation: PathAllocCombineA
Unexecuted instantiation: UnixPathAllocCombineA
Unexecuted instantiation: NativePathAllocCombineA
172
173
#endif
174
175
/*
176
#undef DEFINE_UNICODE
177
#undef CUR_PATH_SEPARATOR_CHR
178
#undef CUR_PATH_SEPARATOR_STR
179
#undef PATH_ALLOC_COMBINE
180
*/