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