2
0

teststr.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "testutil.h"
  17. #include <assert.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #if APR_HAVE_LIMITS_H
  22. #include <limits.h>
  23. #endif
  24. #include "fspr_general.h"
  25. #include "fspr_strings.h"
  26. #include "fspr_errno.h"
  27. /* I haven't bothered to check for APR_ENOTIMPL here, AFAIK, all string
  28. * functions exist on all platforms.
  29. */
  30. static void test_strtok(abts_case *tc, void *data)
  31. {
  32. struct {
  33. char *input;
  34. char *sep;
  35. }
  36. cases[] = {
  37. {
  38. "",
  39. "Z"
  40. },
  41. {
  42. " asdf jkl; 77889909 \r\n\1\2\3Z",
  43. " \r\n\3\2\1"
  44. },
  45. {
  46. NULL, /* but who cares if fspr_strtok() segfaults? */
  47. " \t"
  48. },
  49. #if 0 /* don't do this... you deserve to segfault */
  50. {
  51. "a b c ",
  52. NULL
  53. },
  54. #endif
  55. {
  56. " a b c ",
  57. ""
  58. },
  59. {
  60. "a b c ",
  61. " "
  62. }
  63. };
  64. int curtc;
  65. for (curtc = 0; curtc < sizeof cases / sizeof cases[0]; curtc++) {
  66. char *retval1, *retval2;
  67. char *str1, *str2;
  68. char *state;
  69. str1 = fspr_pstrdup(p, cases[curtc].input);
  70. str2 = fspr_pstrdup(p, cases[curtc].input);
  71. do {
  72. retval1 = fspr_strtok(str1, cases[curtc].sep, &state);
  73. retval2 = strtok(str2, cases[curtc].sep);
  74. if (!retval1) {
  75. ABTS_TRUE(tc, retval2 == NULL);
  76. }
  77. else {
  78. ABTS_TRUE(tc, retval2 != NULL);
  79. ABTS_STR_EQUAL(tc, retval2, retval1);
  80. }
  81. str1 = str2 = NULL; /* make sure we pass NULL on subsequent calls */
  82. } while (retval1);
  83. }
  84. }
  85. static void snprintf_noNULL(abts_case *tc, void *data)
  86. {
  87. char buff[100];
  88. char *testing = fspr_palloc(p, 10);
  89. testing[0] = 't';
  90. testing[1] = 'e';
  91. testing[2] = 's';
  92. testing[3] = 't';
  93. testing[4] = 'i';
  94. testing[5] = 'n';
  95. testing[6] = 'g';
  96. /* If this test fails, we are going to seg fault. */
  97. fspr_snprintf(buff, sizeof(buff), "%.*s", 7, testing);
  98. ABTS_STR_NEQUAL(tc, buff, testing, 7);
  99. }
  100. static void snprintf_0NULL(abts_case *tc, void *data)
  101. {
  102. int rv;
  103. rv = fspr_snprintf(NULL, 0, "%sBAR", "FOO");
  104. ABTS_INT_EQUAL(tc, 6, rv);
  105. }
  106. static void snprintf_0nonNULL(abts_case *tc, void *data)
  107. {
  108. int rv;
  109. char *buff = "testing";
  110. rv = fspr_snprintf(buff, 0, "%sBAR", "FOO");
  111. ABTS_INT_EQUAL(tc, 6, rv);
  112. ABTS_ASSERT(tc, "buff unmangled", strcmp(buff, "FOOBAR") != 0);
  113. }
  114. static void snprintf_underflow(abts_case *tc, void *data)
  115. {
  116. char buf[20];
  117. int rv;
  118. rv = fspr_snprintf(buf, sizeof buf, "%.2f", (double)0.0001);
  119. ABTS_INT_EQUAL(tc, 4, rv);
  120. ABTS_STR_EQUAL(tc, "0.00", buf);
  121. rv = fspr_snprintf(buf, sizeof buf, "%.2f", (double)0.001);
  122. ABTS_INT_EQUAL(tc, 4, rv);
  123. ABTS_STR_EQUAL(tc, "0.00", buf);
  124. rv = fspr_snprintf(buf, sizeof buf, "%.2f", (double)0.01);
  125. ABTS_INT_EQUAL(tc, 4, rv);
  126. ABTS_STR_EQUAL(tc, "0.01", buf);
  127. }
  128. static void string_error(abts_case *tc, void *data)
  129. {
  130. char buf[128], *rv;
  131. fspr_status_t n;
  132. buf[0] = '\0';
  133. rv = fspr_strerror(APR_ENOENT, buf, sizeof buf);
  134. ABTS_PTR_EQUAL(tc, buf, rv);
  135. ABTS_TRUE(tc, strlen(buf) > 0);
  136. rv = fspr_strerror(APR_TIMEUP, buf, sizeof buf);
  137. ABTS_PTR_EQUAL(tc, buf, rv);
  138. ABTS_STR_EQUAL(tc, "The timeout specified has expired", buf);
  139. /* throw some randomish numbers at it to check for robustness */
  140. for (n = 1; n < 1000000; n *= 2) {
  141. fspr_strerror(n, buf, sizeof buf);
  142. }
  143. }
  144. #define SIZE 180000
  145. static void string_long(abts_case *tc, void *data)
  146. {
  147. char s[SIZE + 1];
  148. memset(s, 'A', SIZE);
  149. s[SIZE] = '\0';
  150. fspr_psprintf(p, "%s", s);
  151. }
  152. /* ### FIXME: apr.h/fspr_strings.h should provide these! */
  153. #define MY_LLONG_MAX (APR_INT64_C(9223372036854775807))
  154. #define MY_LLONG_MIN (-MY_LLONG_MAX - APR_INT64_C(1))
  155. static void string_strtoi64(abts_case *tc, void *data)
  156. {
  157. static const struct {
  158. int errnum, base;
  159. const char *in, *end;
  160. fspr_int64_t result;
  161. } ts[] = {
  162. /* base 10 tests */
  163. { 0, 10, "123545", NULL, APR_INT64_C(123545) },
  164. { 0, 10, " 123545", NULL, APR_INT64_C(123545) },
  165. { 0, 10, " +123545", NULL, APR_INT64_C(123545) },
  166. { 0, 10, "-123545", NULL, APR_INT64_C(-123545) },
  167. { 0, 10, " 00000123545", NULL, APR_INT64_C(123545) },
  168. { 0, 10, "123545ZZZ", "ZZZ", APR_INT64_C(123545) },
  169. { 0, 10, " 123545 ", " ", APR_INT64_C(123545) },
  170. /* base 16 tests */
  171. { 0, 16, "1E299", NULL, APR_INT64_C(123545) },
  172. { 0, 16, "1e299", NULL, APR_INT64_C(123545) },
  173. { 0, 16, "0x1e299", NULL, APR_INT64_C(123545) },
  174. { 0, 16, "0X1E299", NULL, APR_INT64_C(123545) },
  175. { 0, 16, "+1e299", NULL, APR_INT64_C(123545) },
  176. { 0, 16, "-1e299", NULL, APR_INT64_C(-123545) },
  177. { 0, 16, " -1e299", NULL, APR_INT64_C(-123545) },
  178. /* automatic base detection tests */
  179. { 0, 0, "123545", NULL, APR_INT64_C(123545) },
  180. { 0, 0, "0x1e299", NULL, APR_INT64_C(123545) },
  181. { 0, 0, " 0x1e299", NULL, APR_INT64_C(123545) },
  182. { 0, 0, "+0x1e299", NULL, APR_INT64_C(123545) },
  183. { 0, 0, "-0x1e299", NULL, APR_INT64_C(-123545) },
  184. /* large number tests */
  185. { 0, 10, "8589934605", NULL, APR_INT64_C(8589934605) },
  186. { 0, 10, "-8589934605", NULL, APR_INT64_C(-8589934605) },
  187. { 0, 16, "0x20000000D", NULL, APR_INT64_C(8589934605) },
  188. { 0, 16, "-0x20000000D", NULL, APR_INT64_C(-8589934605) },
  189. { 0, 16, " 0x20000000D", NULL, APR_INT64_C(8589934605) },
  190. { 0, 16, " 0x20000000D", NULL, APR_INT64_C(8589934605) },
  191. /* error cases */
  192. { ERANGE, 10, "999999999999999999999999999999999", "", MY_LLONG_MAX },
  193. { ERANGE, 10, "-999999999999999999999999999999999", "", MY_LLONG_MIN },
  194. #if 0
  195. /* C99 doesn't require EINVAL for an invalid range. */
  196. { EINVAL, 99, "", (void *)-1 /* don't care */, 0 },
  197. #endif
  198. /* some strtoll implementations give EINVAL when no conversion
  199. * is performed. */
  200. { -1 /* don't care */, 10, "zzz", "zzz", APR_INT64_C(0) },
  201. { -1 /* don't care */, 10, "", NULL, APR_INT64_C(0) }
  202. };
  203. int n;
  204. for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) {
  205. char *end = "end ptr not changed";
  206. fspr_int64_t result;
  207. int errnum;
  208. errno = 0;
  209. result = fspr_strtoi64(ts[n].in, &end, ts[n].base);
  210. errnum = errno;
  211. ABTS_ASSERT(tc,
  212. fspr_psprintf(p, "for '%s': result was %" APR_INT64_T_FMT
  213. " not %" APR_INT64_T_FMT, ts[n].in,
  214. result, ts[n].result),
  215. result == ts[n].result);
  216. if (ts[n].errnum != -1) {
  217. ABTS_ASSERT(tc,
  218. fspr_psprintf(p, "for '%s': errno was %d not %d", ts[n].in,
  219. errnum, ts[n].errnum),
  220. ts[n].errnum == errnum);
  221. }
  222. if (ts[n].end == NULL) {
  223. /* end must point to NUL terminator of .in */
  224. ABTS_PTR_EQUAL(tc, ts[n].in + strlen(ts[n].in), end);
  225. } else if (ts[n].end != (void *)-1) {
  226. ABTS_ASSERT(tc,
  227. fspr_psprintf(p, "for '%s', end was '%s' not '%s'",
  228. ts[n].in, end, ts[n].end),
  229. strcmp(ts[n].end, end) == 0);
  230. }
  231. }
  232. }
  233. static void string_strtoff(abts_case *tc, void *data)
  234. {
  235. fspr_off_t off;
  236. ABTS_ASSERT(tc, "strtoff fails on out-of-range integer",
  237. fspr_strtoff(&off, "999999999999999999999999999999",
  238. NULL, 10) != APR_SUCCESS);
  239. ABTS_ASSERT(tc, "strtoff failed for 1234",
  240. fspr_strtoff(&off, "1234", NULL, 10) == APR_SUCCESS);
  241. ABTS_ASSERT(tc, "strtoff failed to parse 1234", off == 1234);
  242. }
  243. /* random-ish checks for strfsize buffer overflows */
  244. static void overflow_strfsize(abts_case *tc, void *data)
  245. {
  246. fspr_off_t off;
  247. char buf[7];
  248. buf[5] = '$';
  249. buf[6] = '@';
  250. for (off = -9999; off < 20000; off++) {
  251. fspr_strfsize(off, buf);
  252. }
  253. for (; off < 9999999; off += 9) {
  254. fspr_strfsize(off, buf);
  255. }
  256. for (; off < 999999999; off += 999) {
  257. fspr_strfsize(off, buf);
  258. }
  259. for (off = 1; off < LONG_MAX && off > 0; off *= 2) {
  260. fspr_strfsize(off, buf);
  261. fspr_strfsize(off + 1, buf);
  262. fspr_strfsize(off - 1, buf);
  263. }
  264. ABTS_ASSERT(tc, "strfsize overflowed", buf[5] == '$');
  265. ABTS_ASSERT(tc, "strfsize overflowed", buf[6] == '@');
  266. }
  267. static void string_strfsize(abts_case *tc, void *data)
  268. {
  269. static const struct {
  270. fspr_off_t size;
  271. const char *buf;
  272. } ts[] = {
  273. { -1, " - " },
  274. { 0, " 0 " },
  275. { 666, "666 " },
  276. { 1024, "1.0K" },
  277. { 1536, "1.5K" },
  278. { 2048, "2.0K" },
  279. { 1293874, "1.2M" },
  280. { 9999999, "9.5M" },
  281. { 103809024, " 99M" },
  282. { 1047527424, "1.0G" } /* "999M" would be more correct */
  283. };
  284. fspr_size_t n;
  285. for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) {
  286. char buf[6], *ret;
  287. buf[5] = '%';
  288. ret = fspr_strfsize(ts[n].size, buf);
  289. ABTS_ASSERT(tc, "strfsize returned wrong buffer", ret == buf);
  290. ABTS_ASSERT(tc, "strfsize overflowed", buf[5] == '%');
  291. ABTS_STR_EQUAL(tc, ts[n].buf, ret);
  292. }
  293. }
  294. static void snprintf_overflow(abts_case *tc, void *data)
  295. {
  296. char buf[4];
  297. int rv;
  298. buf[2] = '4';
  299. buf[3] = '2';
  300. rv = fspr_snprintf(buf, 2, "%s", "a");
  301. ABTS_INT_EQUAL(tc, 1, rv);
  302. rv = fspr_snprintf(buf, 2, "%s", "abcd");
  303. ABTS_INT_EQUAL(tc, 1, rv);
  304. ABTS_STR_EQUAL(tc, buf, "a");
  305. /* Check the buffer really hasn't been overflowed. */
  306. ABTS_TRUE(tc, buf[2] == '4' && buf[3] == '2');
  307. }
  308. abts_suite *teststr(abts_suite *suite)
  309. {
  310. suite = ADD_SUITE(suite)
  311. abts_run_test(suite, snprintf_0NULL, NULL);
  312. abts_run_test(suite, snprintf_0nonNULL, NULL);
  313. abts_run_test(suite, snprintf_noNULL, NULL);
  314. abts_run_test(suite, snprintf_underflow, NULL);
  315. abts_run_test(suite, test_strtok, NULL);
  316. abts_run_test(suite, string_error, NULL);
  317. abts_run_test(suite, string_long, NULL);
  318. abts_run_test(suite, string_strtoi64, NULL);
  319. abts_run_test(suite, string_strtoff, NULL);
  320. abts_run_test(suite, overflow_strfsize, NULL);
  321. abts_run_test(suite, string_strfsize, NULL);
  322. abts_run_test(suite, snprintf_overflow, NULL);
  323. return suite;
  324. }