1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
static const CHAR testStringA[] = { 'T', 'h', 'e', ' ', 'q', 'u', 'i', 'c', 'k', ' ', 'b',
'r', 'o', 'w', 'n', ' ', 'f', 'o', 'x', ' ', 'j', 'u',
'm', 'p', 's', ' ', 'o', 'v', 'e', 'r', ' ', 't', 'h',
'e', ' ', 'l', 'a', 'z', 'y', ' ', 'd', 'o', 'g', '\0' };
#define testStringA_Length ((sizeof(testStringA) / sizeof(CHAR)) - 1)
static const CHAR testToken1A[] = { 'q', 'u', 'i', 'c', 'k', '\0' };
static const CHAR testToken2A[] = { 'b', 'r', 'o', 'w', 'n', '\0' };
static const CHAR testToken3A[] = { 'f', 'o', 'x', '\0' };
#define testToken1A_Length ((sizeof(testToken1A) / sizeof(CHAR)) - 1)
#define testToken2A_Length ((sizeof(testToken2A) / sizeof(CHAR)) - 1)
#define testToken3A_Length ((sizeof(testToken3A) / sizeof(CHAR)) - 1)
static const CHAR testTokensA[] = { 'q', 'u', 'i', 'c', 'k', '\r', '\n', 'b', 'r', 'o',
'w', 'n', '\r', '\n', 'f', 'o', 'x', '\r', '\n', '\0' };
#define testTokensA_Length ((sizeof(testTokensA) / sizeof(CHAR)) - 1)
static const CHAR testDelimiterA[] = { '\r', '\n', '\0' };
#define testDelimiterA_Length ((sizeof(testDelimiter) / sizeof(CHAR)) - 1)
struct url_test_pair
{
const char* what;
const char* escaped;
};
static const struct url_test_pair url_tests[] = {
{ "xxx%bar ga<ka>ee#%%#%{h}g{f{e%d|c\\b^a~p[q]r`s;t/u?v:w@x=y&z$xxx",
"xxx%25bar%20ga%3Cka%3Eee%23%25%25%23%25%7Bh%7Dg%7Bf%7Be%25d%7Cc%5Cb%5Ea~p%5Bq%5Dr%60s%3Bt%"
"2Fu%3Fv%3Aw%40x%3Dy%26z%24xxx" },
{ "äöúëü", "%C3%A4%C3%B6%C3%BA%C3%AB%C3%BC" },
{ "🎅🏄🤘😈", "%F0%9F%8E%85%F0%9F%8F%84%F0%9F%A4%98%F0%9F%98%88" },
{ "foo$.%.^.&.\\.txt+", "foo%24.%25.%5E.%26.%5C.txt%2B" }
};
static BOOL test_url_escape(void)
{
for (size_t x = 0; x < ARRAYSIZE(url_tests); x++)
{
const struct url_test_pair* cur = &url_tests[x];
char* escaped = winpr_str_url_encode(cur->what, strlen(cur->what) + 1);
char* what = winpr_str_url_decode(cur->escaped, strlen(cur->escaped) + 1);
const size_t elen = strlen(escaped);
const size_t wlen = strlen(what);
const size_t pelen = strlen(cur->escaped);
const size_t pwlen = strlen(cur->what);
BOOL rc = TRUE;
if (!escaped || (elen != pelen) || (strcmp(escaped, cur->escaped) != 0))
{
printf("expected: [%" PRIuz "] %s\n", pelen, cur->escaped);
printf("got : [%" PRIuz "] %s\n", elen, escaped);
rc = FALSE;
}
else if (!what || (wlen != pwlen) || (strcmp(what, cur->what) != 0))
{
printf("expected: [%" PRIuz "] %s\n", pwlen, cur->what);
printf("got : [%" PRIuz "] %s\n", wlen, what);
rc = FALSE;
}
free(escaped);
free(what);
if (!rc)
return FALSE;
}
return TRUE;
}
int TestString(int argc, char* argv[])
{
const WCHAR* p = NULL;
size_t pos = 0;
size_t length = 0;
WCHAR* context = NULL;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
if (!test_url_escape())
return -1;
/* _wcslen */
WCHAR testStringW[ARRAYSIZE(testStringA)] = { 0 };
ConvertUtf8NToWChar(testStringA, ARRAYSIZE(testStringA), testStringW, ARRAYSIZE(testStringW));
const size_t testStringW_Length = testStringA_Length;
length = _wcslen(testStringW);
if (length != testStringW_Length)
{
printf("_wcslen error: length mismatch: Actual: %" PRIuz ", Expected: %" PRIuz "\n", length,
testStringW_Length);
return -1;
}
/* _wcschr */
union
{
char c[2];
WCHAR w;
} search;
search.c[0] = 'r';
search.c[1] = '\0';
p = _wcschr(testStringW, search.w);
pos = (p - testStringW);
if (pos != 11)
{
printf("_wcschr error: position mismatch: Actual: %" PRIuz ", Expected: 11\n", pos);
return -1;
}
p = _wcschr(&testStringW[pos + 1], search.w);
pos = (p - testStringW);
if (pos != 29)
{
printf("_wcschr error: position mismatch: Actual: %" PRIuz ", Expected: 29\n", pos);
return -1;
}
p = _wcschr(&testStringW[pos + 1], search.w);
if (p != NULL)
{
printf("_wcschr error: return value mismatch: Actual: %p, Expected: NULL\n",
(const void*)p);
return -1;
}
/* wcstok_s */
WCHAR testDelimiterW[ARRAYSIZE(testDelimiterA)] = { 0 };
WCHAR testTokensW[ARRAYSIZE(testTokensA)] = { 0 };
ConvertUtf8NToWChar(testTokensA, ARRAYSIZE(testTokensA), testTokensW, ARRAYSIZE(testTokensW));
ConvertUtf8NToWChar(testDelimiterA, ARRAYSIZE(testDelimiterA), testDelimiterW,
ARRAYSIZE(testDelimiterW));
p = wcstok_s(testTokensW, testDelimiterW, &context);
WCHAR testToken1W[ARRAYSIZE(testToken1A)] = { 0 };
ConvertUtf8NToWChar(testToken1A, ARRAYSIZE(testToken1A), testToken1W, ARRAYSIZE(testToken1W));
if (memcmp(p, testToken1W, sizeof(testToken1W)) != 0)
{
printf("wcstok_s error: token #1 mismatch\n");
return -1;
}
p = wcstok_s(NULL, testDelimiterW, &context);
WCHAR testToken2W[ARRAYSIZE(testToken2A)] = { 0 };
ConvertUtf8NToWChar(testToken2A, ARRAYSIZE(testToken2A), testToken2W, ARRAYSIZE(testToken2W));
if (memcmp(p, testToken2W, sizeof(testToken2W)) != 0)
{
printf("wcstok_s error: token #2 mismatch\n");
return -1;
}
p = wcstok_s(NULL, testDelimiterW, &context);
WCHAR testToken3W[ARRAYSIZE(testToken3A)] = { 0 };
ConvertUtf8NToWChar(testToken3A, ARRAYSIZE(testToken3A), testToken3W, ARRAYSIZE(testToken3W));
if (memcmp(p, testToken3W, sizeof(testToken3W)) != 0)
{
printf("wcstok_s error: token #3 mismatch\n");
return -1;
}
p = wcstok_s(NULL, testDelimiterW, &context);
if (p != NULL)
{
printf("wcstok_s error: return value is not NULL\n");
return -1;
}
return 0;
}
|