string-tests.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /*
  2. String handling tests
  3. Copyright (C) 2001-2007, 2009, Joe Orton <[email protected]>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #ifdef HAVE_STDLIB_H
  18. #include <stdlib.h>
  19. #endif
  20. #ifdef HAVE_STRING_H
  21. #include <string.h>
  22. #endif
  23. #ifdef HAVE_ERRNO_H
  24. #include <errno.h> /* for the ENOENT definitions in str_errors */
  25. #endif
  26. #include "ne_string.h"
  27. #include "ne_utils.h"
  28. #include "tests.h"
  29. #undef ONCMP
  30. #define ONCMP(a,b) ONV(!a || strcmp(a, b), \
  31. ("result was [%s] not [%s]", a, b))
  32. static int simple(void) {
  33. ne_buffer *s = ne_buffer_create();
  34. ON(s == NULL);
  35. ne_buffer_zappend(s, "abcde");
  36. ONCMP(s->data, "abcde");
  37. ON(ne_buffer_size(s) != 5);
  38. ne_buffer_destroy(s);
  39. return OK;
  40. }
  41. static int buf_concat(void)
  42. {
  43. ne_buffer *s = ne_buffer_create();
  44. ON(s == NULL);
  45. ne_buffer_concat(s, "a", "b", "c", "d", "e", "f", "g", NULL);
  46. ONCMP(s->data, "abcdefg");
  47. ON(ne_buffer_size(s) != 7);
  48. ne_buffer_destroy(s);
  49. return OK;
  50. }
  51. static int buf_concat2(void)
  52. {
  53. #define RES "alphabetagammadeltaepsilonetatheta"
  54. ne_buffer *s = ne_buffer_create();
  55. ON(s == NULL);
  56. ne_buffer_concat(s, "alpha", "beta", "gamma", "delta", "epsilon",
  57. "eta", "theta", NULL);
  58. ONCMP(s->data, RES);
  59. ON(ne_buffer_size(s) != strlen(RES));
  60. ne_buffer_destroy(s);
  61. return OK;
  62. }
  63. static int buf_concat3(void)
  64. {
  65. ne_buffer *s = ne_buffer_create();
  66. ON(s == NULL);
  67. ne_buffer_zappend(s, "foobar");
  68. ne_buffer_concat(s, "norman", NULL);
  69. ONCMP(s->data, "foobarnorman");
  70. ON(ne_buffer_size(s) != 12);
  71. ne_buffer_destroy(s);
  72. return OK;
  73. }
  74. static int append(void)
  75. {
  76. ne_buffer *s = ne_buffer_create();
  77. ON(s == NULL);
  78. ne_buffer_append(s, "a", 1);
  79. ne_buffer_append(s, "b", 1);
  80. ne_buffer_append(s, "c", 1);
  81. ONCMP(s->data, "abc");
  82. ON(ne_buffer_size(s) != 3);
  83. ne_buffer_zappend(s, "hello");
  84. ONCMP(s->data, "abchello");
  85. ne_buffer_czappend(s, "world");
  86. ONCMP(s->data, "abchelloworld");
  87. ON(ne_buffer_size(s) != 13);
  88. ne_buffer_destroy(s);
  89. return OK;
  90. }
  91. static int grow(void)
  92. {
  93. ne_buffer *s = ne_buffer_ncreate(2);
  94. ON(s == NULL);
  95. ne_buffer_append(s, "a", 1);
  96. ne_buffer_grow(s, 4);
  97. ONCMP(s->data, "a");
  98. ne_buffer_destroy(s);
  99. return OK;
  100. }
  101. static int alter(void) {
  102. ne_buffer *s = ne_buffer_create();
  103. char *d;
  104. ON(s == NULL);
  105. ne_buffer_zappend(s, "abcdefg");
  106. d = s->data;
  107. ON(d == NULL);
  108. d[2] = '\0';
  109. ne_buffer_altered(s);
  110. ONCMP(s->data, "ab");
  111. ON(ne_buffer_size(s) != 2);
  112. ne_buffer_zappend(s, "hijkl");
  113. ONCMP(s->data, "abhijkl");
  114. ne_buffer_destroy(s);
  115. return OK;
  116. }
  117. /* Macros for testing ne_token. */
  118. #define TEST(res) do { \
  119. char *tok = ne_token(&pnt, ','); \
  120. ONN(res ": return", tok == NULL); \
  121. ONN(res ": compare", strcmp(tok, (res))); \
  122. ONN(res ": modify", pnt == NULL); \
  123. } while (0)
  124. #define LASTTEST(res) do { \
  125. char *tok = ne_token(&pnt, ','); \
  126. ONN(res ": last return", tok == NULL); \
  127. ONN(res ": last compare", strcmp(tok, (res))); \
  128. ONN(res ": last modify", pnt != NULL); \
  129. } while (0)
  130. #define QTEST(res) do { \
  131. char *tok = ne_qtoken(&pnt, ',', QUOTES); \
  132. ONN(res ": return", tok == NULL); \
  133. ONN(res ": compare", strcmp(tok, (res))); \
  134. ONN(res ": modify", pnt == NULL); \
  135. } while (0)
  136. #define QLASTTEST(res) do { \
  137. char *tok = ne_qtoken(&pnt, ',', QUOTES); \
  138. ONN(res ": last return", tok == NULL); \
  139. ONN(res ": last compare", strcmp(tok, (res))); \
  140. ONN(res ": last modify", pnt != NULL); \
  141. } while (0)
  142. static int token1(void)
  143. {
  144. char *str = ne_strdup("a,b,c,d"), *pnt = str;
  145. TEST("a"); TEST("b"); TEST("c"); LASTTEST("d");
  146. ne_free(str);
  147. return OK;
  148. }
  149. static int token2(void)
  150. {
  151. char *str = ne_strdup("norman,fishing, elsewhere"), *pnt = str;
  152. TEST("norman"); TEST("fishing"); LASTTEST(" elsewhere");
  153. ne_free(str);
  154. return OK;
  155. }
  156. static int nulls(void)
  157. {
  158. char *str = ne_strdup("alpha,,gamma"), *pnt = str;
  159. TEST("alpha"); TEST(""); LASTTEST("gamma");
  160. ne_free(str);
  161. pnt = str = ne_strdup(",,,wooo");
  162. TEST(""); TEST(""); TEST(""); LASTTEST("wooo");
  163. ne_free(str);
  164. pnt = str = ne_strdup("wooo,,,");
  165. TEST("wooo"); TEST(""); TEST(""); LASTTEST("");
  166. ne_free(str);
  167. return OK;
  168. }
  169. static int empty(void)
  170. {
  171. char *str = ne_strdup(""), *pnt = str;
  172. LASTTEST("");
  173. ne_free(str);
  174. return OK;
  175. }
  176. #undef QUOTES
  177. #define QUOTES "'"
  178. static int quoted(void)
  179. {
  180. char *str =
  181. ne_strdup("alpha,'beta, a fish called HELLO!?',sandwiches");
  182. char *pnt = str;
  183. QTEST("alpha");
  184. QTEST("'beta, a fish called HELLO!?'");
  185. QLASTTEST("sandwiches");
  186. ne_free(str);
  187. return OK;
  188. }
  189. static int badquotes(void)
  190. {
  191. char *str = ne_strdup("alpha,'blah"), *pnt = str;
  192. QTEST("alpha");
  193. ON(ne_qtoken(&pnt, ',', QUOTES) != NULL);
  194. ne_free(str);
  195. return OK;
  196. }
  197. /* for testing ne_shave. */
  198. #undef TEST
  199. #define TEST(str, ws, res) do { \
  200. char *s = ne_strdup((str)); \
  201. char *r = ne_shave(s, (ws)); \
  202. ONN("[" str "]", strcmp(r, (res))); \
  203. ne_free(s); \
  204. } while (0)
  205. static int shave(void)
  206. {
  207. TEST(" b ", " ", "b");
  208. TEST("b", " ", "b");
  209. TEST(" b ", " ", "b");
  210. TEST("--bbb-----", "-", "bbb");
  211. TEST("hello, world ", " ", "hello, world");
  212. TEST("<<><<<><<this is foo<<><<<<><<", "<>", "this is foo");
  213. TEST("09809812342347I once saw an helicopter0012312312398", "0123456789",
  214. "I once saw an helicopter");
  215. return OK;
  216. }
  217. /* Regression test for ne_shave call which should produce an empty
  218. * string. */
  219. static int shave_regress(void)
  220. {
  221. TEST("\"\"", "\"", "");
  222. return OK;
  223. }
  224. /* Test the ne_token/ne_shave combination. */
  225. #undef TEST
  226. #undef LASTTEST
  227. #define TEST(res) do { \
  228. char *tok = ne_token(&pnt, ','); \
  229. ONN(res ": return", tok == NULL); \
  230. tok = ne_shave(tok, " "); \
  231. ONN(res ": shave", tok == NULL); \
  232. ONN(res ": compare", strcmp(tok, (res))); \
  233. ONN(res ": modify", pnt == NULL); \
  234. } while (0)
  235. #define LASTTEST(res) do { \
  236. char *tok = ne_token(&pnt, ','); \
  237. ONN(res ": last return", tok == NULL); \
  238. tok = ne_shave(tok, " "); \
  239. ONN(res ": last shave", tok == NULL); \
  240. ONN(res ": last compare", strcmp(tok, (res))); \
  241. ONN(res ": last modify", pnt != NULL); \
  242. } while (0)
  243. /* traditional use of ne_token/ne_shave. */
  244. static int combo(void)
  245. {
  246. char *str = ne_strdup(" fred , mary, jim , alice, david"), *pnt = str;
  247. TEST("fred"); TEST("mary"); TEST("jim"); TEST("alice");
  248. LASTTEST("david");
  249. ne_free(str);
  250. return 0;
  251. }
  252. static int concat(void)
  253. {
  254. #define CAT(res, args) do { char *str = ne_concat args; \
  255. ONCMP(str, res); \
  256. ne_free(str); } while (0)
  257. CAT("alphabeta", ("alpha", "beta", NULL));
  258. CAT("alpha", ("alpha", "", "", NULL));
  259. CAT("", ("", NULL));
  260. CAT("", ("", "", "", NULL));
  261. CAT("alpha", ("", "a", "lph", "", "a", NULL));
  262. return OK;
  263. }
  264. static int str_errors(void)
  265. {
  266. char expect[200], actual[200];
  267. strncpy(expect, strerror(ENOENT), sizeof(expect)-1);
  268. ONN("ne_strerror did not return passed-in buffer",
  269. ne_strerror(ENOENT, actual, sizeof(actual)) != actual);
  270. ONV(strcmp(expect, actual),
  271. ("error from ENOENT was `%s' not `%s'", actual, expect));
  272. /* Test truncated error string is still NUL-terminated. */
  273. ne_strerror(ENOENT, actual, 6);
  274. NE_DEBUG(NE_DBG_HTTP, "error: %s\n", actual);
  275. ONN("truncated string had wrong length", strlen(actual) != 5);
  276. ne_strerror(-1, actual, 6);
  277. ONN("truncated string for bad error had wrong length",
  278. strlen(actual) != 5);
  279. return OK;
  280. }
  281. static int strnzcpy(void)
  282. {
  283. char buf[16];
  284. ne_strnzcpy(buf, "abcdefghi", 5);
  285. ONV(strcmp(buf, "abcd"), ("result was `%s' not `abcd'", buf));
  286. ne_strnzcpy(buf, "ab", 5);
  287. ONV(strcmp(buf, "ab"), ("result was `%s' not `ab'", buf));
  288. return OK;
  289. }
  290. #define FOX_STRING "The quick brown fox jumped over the lazy dog"
  291. #define PUNC_STRING "<>,.;'#:@~[]{}!\"$%^&*()_+-="
  292. static int cleaner(void)
  293. {
  294. static const char *strings[] = {
  295. "alpha", "alpha",
  296. "pretty\033[41mcolours", "pretty [41mcolours",
  297. "beta\n", "beta ",
  298. "del\rt\na", "del t a",
  299. FOX_STRING, FOX_STRING,
  300. "0123456789", "0123456789",
  301. PUNC_STRING, PUNC_STRING,
  302. "\01blah blee\05bloo", " blah blee bloo",
  303. NULL,
  304. };
  305. unsigned int n;
  306. for (n = 0; strings[n]; n+=2) {
  307. char *act = ne_strclean(ne_strdup(strings[n]));
  308. ONV(strcmp(act, strings[n+1]),
  309. ("cleansed to `%s' not `%s'", act, strings[n+1]));
  310. ne_free(act);
  311. }
  312. return OK;
  313. }
  314. /* Check that raw data 'raw', of length 'len', has base64 encoding
  315. * of 'expected'. */
  316. static int b64_check(const unsigned char *raw, size_t len,
  317. const char *expected)
  318. {
  319. char *encoded = ne_base64(raw, len);
  320. unsigned char *decoded;
  321. size_t dlen;
  322. ONV(strcmp(encoded, expected),
  323. ("base64(\"%s\") gave \"%s\" not \"%s\"", raw, encoded, expected));
  324. dlen = ne_unbase64(encoded, &decoded);
  325. ONV(dlen != len,
  326. ("decoded `%s' length was %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T,
  327. expected, dlen, len));
  328. ONV(memcmp(raw, decoded, dlen),
  329. ("decoded `%s' as `%.*s' not `%.*s'",
  330. expected, (int)dlen, decoded, (int)dlen, raw));
  331. ne_free(decoded);
  332. ne_free(encoded);
  333. return OK;
  334. }
  335. /* ALLBITS: base64 encoding of "\0..\377" */
  336. #define ALLBITS \
  337. "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss" \
  338. "LS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ" \
  339. "WltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWG" \
  340. "h4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz" \
  341. "tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g" \
  342. "4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
  343. static int base64(void)
  344. {
  345. unsigned char bits[256];
  346. size_t n;
  347. #define B64B(x, l, y) CALL(b64_check((unsigned char *)x, l, y))
  348. #define B64(x, y) B64B(x, strlen(x), y)
  349. /* invent these with
  350. * $ printf "string" | uuencode -m blah
  351. */
  352. B64("a", "YQ==");
  353. B64("bb", "YmI=");
  354. B64("ccc", "Y2Nj");
  355. B64("Hello, world", "SGVsbG8sIHdvcmxk");
  356. B64("Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
  357. B64("I once saw a dog called norman.\n",
  358. "SSBvbmNlIHNhdyBhIGRvZyBjYWxsZWQgbm9ybWFuLgo=");
  359. B64("The quick brown fox jumped over the lazy dog",
  360. "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c=");
  361. /* binary data..
  362. * $ printf "string" | wc -c # get the length
  363. * $ printf "string" | uuencode -m blah # get the base64
  364. */
  365. B64B("\0\0\0\0\0\n", 6, "AAAAAAAK");
  366. B64B("I once wished \0 upon a \0 fish.", 30,
  367. "SSBvbmNlIHdpc2hlZCAAIHVwb24gYSAAIGZpc2gu");
  368. B64B("\201\202\203\204", 4, "gYKDhA==");
  369. for (n = 0; n < sizeof bits; n++)
  370. bits[n] = (unsigned char)n;
  371. CALL(b64_check(bits, sizeof bits, ALLBITS));
  372. #undef B64
  373. #undef B64B
  374. return OK;
  375. }
  376. static int unbase64(void)
  377. {
  378. static const char *ts[] = {
  379. "", "a", "ab", "abc",
  380. "}bcd", "a}cd", "ab}d", "abc}", " ",
  381. "^bcd", "a^cd", "ab^d", "abc^",
  382. "====", "=bcd", "a=cd", "ab=d", "a==d", "a=c=",
  383. NULL
  384. };
  385. size_t n;
  386. for (n = 0; ts[n]; n++) {
  387. unsigned char *tmp;
  388. ONV(ne_unbase64(ts[n], &tmp) != 0,
  389. ("invalid string `%s' was decoded", ts[n]));
  390. }
  391. return OK;
  392. }
  393. static int printing(void)
  394. {
  395. struct {
  396. const char *in, *out;
  397. size_t pass, ret;
  398. } ts[] = {
  399. { "alpha", "alpha", 10, 5 },
  400. { "alpha", "alph", 5, 4 },
  401. { "foobar", "", 1, 0 },
  402. { NULL, NULL, 0, 0}
  403. };
  404. size_t n;
  405. for (n = 0; ts[n].in; n++) {
  406. char buf[512];
  407. size_t ret;
  408. memset(buf, 'A', sizeof buf);
  409. ret = ne_snprintf(buf, ts[n].pass, "%s", ts[n].in);
  410. ONCMP(ts[n].out, buf);
  411. ONV(ret != ts[n].ret,
  412. ("got return value %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T,
  413. ret, ts[n].ret));
  414. /* byte past the NUL must still be 'A' */
  415. ONN("buffer over-ran!", buf[ret + 1] != 'A');
  416. }
  417. return OK;
  418. }
  419. static int casecmp(void)
  420. {
  421. static const struct {
  422. const char *left, *right;
  423. int expect;
  424. } ts[] = {
  425. { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 },
  426. { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", 0 },
  427. { "foo", "bar", 1 },
  428. { "!#:[@\377", "!#:[@\377", 0 },
  429. { "bar", "foo", -1 },
  430. { "foop", "foo", 1 },
  431. { "foo", "foop", -1 },
  432. { NULL, NULL, 0 }
  433. };
  434. size_t n;
  435. for (n = 0; ts[n].left; n++) {
  436. int actual;
  437. actual = ne_strcasecmp(ts[n].left, ts[n].right);
  438. ONV(ts[n].expect == 0 && actual != 0,
  439. ("strcasecmp(%s, %s) gave %d, expected 0",
  440. ts[n].left, ts[n].right, actual));
  441. ONV(ts[n].expect > 0 && actual <= 0,
  442. ("strcasecmp(%s, %s) gave %d, expected > 0",
  443. ts[n].left, ts[n].right, actual));
  444. ONV(ts[n].expect < 0 && actual >= 0,
  445. ("strcasecmp(%s, %s) gave %d, expected < 0",
  446. ts[n].left, ts[n].right, actual));
  447. }
  448. ONN("comparison of identical pointers did not give zero",
  449. ne_strcasecmp(ts[0].left, ts[0].left) != 0);
  450. return OK;
  451. }
  452. static int casencmp(void)
  453. {
  454. static const struct {
  455. const char *left, *right;
  456. size_t n;
  457. int expect;
  458. } ts[] = {
  459. { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 30, 0 },
  460. { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10, 0 },
  461. { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", 0, 0 },
  462. { "foo", "bar", 3, 1 },
  463. { "bar", "foo", 4, -1 },
  464. { "bar", "foo", 3, -1 },
  465. { "foop", "foo", 4, 1 },
  466. { "foo", "foop", 4, -1 },
  467. { "bee", "bar", 0, 0},
  468. { NULL, NULL, 0, 0 }
  469. };
  470. size_t n;
  471. for (n = 0; ts[n].left; n++) {
  472. int actual;
  473. actual = ne_strncasecmp(ts[n].left, ts[n].right, ts[n].n);
  474. ONV(ts[n].expect == 0 && actual != 0,
  475. ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected 0",
  476. ts[n].left, ts[n].right, ts[n].n, actual));
  477. ONV(ts[n].expect > 0 && actual <= 0,
  478. ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected > 0",
  479. ts[n].left, ts[n].right, ts[n].n, actual));
  480. ONV(ts[n].expect < 0 && actual >= 0,
  481. ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected < 0",
  482. ts[n].left, ts[n].right, ts[n].n, actual));
  483. }
  484. ONN("comparison of identical pointers did not give zero",
  485. ne_strncasecmp(ts[0].left, ts[0].left, 5) != 0);
  486. return OK;
  487. }
  488. static int buf_print(void)
  489. {
  490. ne_buffer *buf = ne_buffer_create();
  491. ne_buffer_czappend(buf, "foo-");
  492. ne_buffer_snprintf(buf, 20, "bar-%s-asda", "norman");
  493. ne_buffer_czappend(buf, "-bloo");
  494. ONN("snprintf return value", ne_buffer_snprintf(buf, 2, "---") != 1);
  495. ONCMP(buf->data, "foo-bar-norman-asda-bloo-");
  496. ne_buffer_destroy(buf);
  497. return OK;
  498. }
  499. static int qappend(void)
  500. {
  501. static const struct {
  502. const char *in;
  503. size_t inlen;
  504. const char *out;
  505. } ts[] = {
  506. { "", 0, "" },
  507. { "a", 1, "a" },
  508. { "b", 2, "b\\x00" },
  509. { "alpha\0alpha", 11, "alpha\\x00alpha" },
  510. { "a\tb", 3, "a\\x09b" },
  511. { "foo\x7f" "bar", 7, "foo\\x7fbar" },
  512. { NULL }
  513. };
  514. unsigned n;
  515. for (n = 0; ts[n].in; n++) {
  516. ne_buffer *buf = ne_buffer_create();
  517. char *s;
  518. const unsigned char *in = (const unsigned char *)ts[n].in;
  519. ne_buffer_qappend(buf, in, ts[n].inlen);
  520. ONCMP(buf->data, ts[n].out);
  521. ONV(strlen(buf->data) + 1 != buf->used,
  522. ("bad buffer length for '%s': %" NE_FMT_SIZE_T,
  523. ts[n].out, buf->used));
  524. s = ne_strnqdup(in, ts[n].inlen);
  525. ONCMP(s, ts[n].out);
  526. ne_free(s);
  527. ne_buffer_destroy(buf);
  528. }
  529. return OK;
  530. }
  531. static char *test_vstrhash(unsigned int flags, ...)
  532. {
  533. va_list ap;
  534. char *rv;
  535. va_start(ap, flags);
  536. rv = ne_vstrhash(flags, ap);
  537. va_end(ap);
  538. return rv;
  539. }
  540. #define TEST1 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
  541. #define TEST1_SHA "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
  542. #define ONVEC(args, expect) \
  543. do { char *h = ne_strhash args; ONCMP(h, expect); ne_free(h); } while (0)
  544. static int strhash(void)
  545. {
  546. ONN("zero flags must return NULL", ne_strhash(0, "", NULL) != NULL);
  547. ONN("zero flags must return NULL for vstrhash", test_vstrhash(0, "", NULL) != NULL);
  548. ONN("no alg flags must return NULL", ne_strhash(NE_HASH_COLON, "", NULL) != NULL);
  549. ONN("no alg flags must return NULL", ne_strhash(NE_HASH_SPACE, "", NULL) != NULL);
  550. ONVEC((NE_HASH_MD5, "", NULL), "d41d8cd98f00b204e9800998ecf8427e");
  551. ONVEC((NE_HASH_MD5, "foo", "ba", "r", NULL), "3858f62230ac3c915f300c664312c63f");
  552. ONVEC((NE_HASH_MD5|NE_HASH_SPACE, "foo", "ba", "r", NULL), "38 58 f6 22 30 ac 3c 91 5f 30 0c 66 43 12 c6 3f");
  553. return OK;
  554. }
  555. static int strhash_sha_256(void)
  556. {
  557. char *p = ne_strhash(NE_HASH_SHA256, "", NULL);
  558. if (p == NULL) {
  559. t_context("SHA-2-256 not supported");
  560. return SKIP;
  561. }
  562. ne_free(p);
  563. ONVEC((NE_HASH_SHA256, TEST1, NULL), TEST1_SHA);
  564. ONVEC((NE_HASH_SHA256, "foobar", "foo", "bar", "f", "oobar", NULL),
  565. "d173c93898d3ca8455a4526e0af2a1aee9b91c8ec19adac16e6e8be2da09436c");
  566. return OK;
  567. }
  568. /* NIST examples from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512.pdf */
  569. #define TEST1_512 "abc"
  570. #define TEST1_512_MDC "dd:af:35:a1:93:61:7a:ba:cc:41:73:49:ae:20:41:31:12:e6:fa:4e:89:a9:7e:a2:0a:9e:ee:e6:4b:55:d3:9a:21:92:99:2a:27:4f:c1:a8:36:ba:3c:23:a3:fe:eb:bd:45:4d:44:23:64:3c:e8:0e:2a:9a:c9:4f:a5:4c:a4:9f"
  571. #define TEST2_512_1 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrl"
  572. #define TEST2_512_2 "mnopqrsmnopqrstnopqrstu"
  573. #define TEST2_512_MD "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
  574. /* NIST examples from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512_256.pdf */
  575. #define TEST1_512_256 "abc"
  576. #define TEST1_512_256_MD "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"
  577. #define TEST2_512_256_1 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijkl"
  578. #define TEST2_512_256_2 "mnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
  579. #define TEST2_512_256_MD "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"
  580. #define TEST2_512_256_MDC "39:28:e1:84:fb:86:90:f8:40:da:39:88:12:1d:31:be:65:cb:9d:3e:f8:3e:e6:14:6f:ea:c8:61:e1:9b:56:3a"
  581. static int strhash_sha_512(void)
  582. {
  583. char *p = ne_strhash(NE_HASH_SHA512, "", NULL);
  584. if (p == NULL) {
  585. t_context("SHA-2-512 not supported");
  586. return SKIP;
  587. }
  588. ne_free(p);
  589. ONVEC((NE_HASH_SHA512|NE_HASH_COLON, TEST1_512, NULL), TEST1_512_MDC);
  590. ONVEC((NE_HASH_SHA512, TEST2_512_1, TEST2_512_2, NULL), TEST2_512_MD);
  591. return OK;
  592. }
  593. static int strhash_sha_512_256(void)
  594. {
  595. char *p = ne_strhash(NE_HASH_SHA512_256, "", NULL);
  596. if (p == NULL) {
  597. t_context("SHA-2-512/256 not supported");
  598. return SKIP;
  599. }
  600. ne_free(p);
  601. ONVEC((NE_HASH_SHA512_256, TEST1_512_256, NULL), TEST1_512_256_MD);
  602. ONVEC((NE_HASH_SHA512_256, TEST2_512_256_1, TEST2_512_256_2, NULL), TEST2_512_256_MD);
  603. ONVEC((NE_HASH_SHA512_256|NE_HASH_COLON, TEST2_512_256_1, TEST2_512_256_2, NULL),
  604. TEST2_512_256_MDC);
  605. return OK;
  606. }
  607. static int strparam(void)
  608. {
  609. static const struct {
  610. const char *charset, *lang;
  611. const char *value;
  612. const char *expect;
  613. } ts[] = {
  614. { "UTF-8", NULL, "foobar", NULL },
  615. { "UTF-8", NULL, "foo12345bar", NULL },
  616. { "UTF-8", NULL, "foo@bar", "UTF-8''foo%40bar" },
  617. { "UTF-8", NULL, "foo bar", "UTF-8''foo%20bar" },
  618. { "iso-8859-1", "en", "\xA3 rates", "iso-8859-1'en'%a3%20rates" },
  619. { "UTF-8", NULL, "£ and € rates", "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates" },
  620. { NULL }
  621. };
  622. unsigned n;
  623. for (n = 0; ts[n].charset; n++) {
  624. char *act = ne_strparam(ts[n].charset, ts[n].lang, (const unsigned char *)ts[n].value);
  625. if (ts[n].expect == NULL) {
  626. ONV(act != NULL, ("expected NULL output for '%s', got '%s'",
  627. ts[n].value, act));
  628. }
  629. else {
  630. ONCMP(act, ts[n].expect);
  631. ne_free(act);
  632. }
  633. }
  634. return OK;
  635. }
  636. ne_test tests[] = {
  637. T(simple),
  638. T(buf_concat),
  639. T(buf_concat2),
  640. T(buf_concat3),
  641. T(append),
  642. T(grow),
  643. T(alter),
  644. T(token1),
  645. T(token2),
  646. T(nulls),
  647. T(empty),
  648. T(quoted),
  649. T(badquotes),
  650. T(shave),
  651. T(shave_regress),
  652. T(combo),
  653. T(concat),
  654. T(str_errors),
  655. T(strnzcpy),
  656. T(cleaner),
  657. T(base64),
  658. T(unbase64),
  659. T(printing),
  660. T(casecmp),
  661. T(casencmp),
  662. T(buf_print),
  663. T(qappend),
  664. T(strhash),
  665. T(strhash_sha_256),
  666. T(strhash_sha_512),
  667. T(strhash_sha_512_256),
  668. T(strparam),
  669. T(NULL)
  670. };