Files
kcgi/regress/test-template.c

450 lines
9.3 KiB
C

/* $Id$ */
/*
* Copyright (c) 2017--2018 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../config.h"
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../kcgi.h"
static int
testmulti_cmp(size_t idx, void *arg)
{
if (idx)
return(0);
kcgi_buf_puts(arg, "XXX");
return(1);
}
static int
testempty_cmp(size_t idx, void *arg)
{
if (idx)
return(0);
kcgi_buf_puts(arg, "XXX");
return(1);
}
static int
test1_cmp(size_t idx, void *arg)
{
const char *res = "foo";
if (idx)
return(0);
kcgi_buf_puts(arg, res);
return(1);
}
static int
test1_fallthrough(const char *k, size_t ksz, void *arg)
{
const char *val = "foo", *key = "bar";
size_t keysz;
keysz = strlen(key);
if (keysz == ksz && 0 == memcmp(key, k, keysz))
kcgi_buf_puts(arg, val);
return(1);
}
int
main(void)
{
struct ktemplate t;
struct ktemplatex tkx;
const char *keys[] = { "foobar" };
const char *multikeys[] = { "foobar", "foobar" };
const char *ekeys[] = { "" };
const char *test;
const char *r;
size_t testsz, rsz;
struct kcgi_buf b;
int c = EXIT_FAILURE;
enum kcgi_err rc;
memset(&t, 0, sizeof(struct ktemplate));
memset(&tkx, 0, sizeof(struct ktemplatex));
memset(&b, 0, sizeof(struct kcgi_buf));
tkx.writer = kcgi_buf_write;
/* Not found: should go through unchanged. */
test = "abc@@foobar@@def";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = NULL;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
if (b.sz != testsz || memcmp(test, b.buf, testsz))
goto out;
/* Found in keys. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@foobar@@def";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcfoodef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Found in keys (use only first). */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@foobar@@def";
testsz = strlen(test);
t.key = multikeys;
t.keysz = 2;
t.arg = &b;
t.cb = testmulti_cmp;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcXXXdef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Not found: unchanged. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@bar@@def";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@bar@@def";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Not found, fallthrough, not found (omitted). */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@foobar@@def";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcdef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Not found, fallthrough, found. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@bar@@def";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcfoodef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* First string found in keys, second omitted. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@bar@@def@@moobar@@";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcfoodef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Found zero-length. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@@@def";
testsz = strlen(test);
t.key = ekeys;
t.keysz = 1;
t.arg = &b;
t.cb = testempty_cmp;
tkx.fbk = NULL;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcXXXdef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Found zero-length after escaped. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc\\@@@@@@def";
testsz = strlen(test);
t.key = ekeys;
t.keysz = 1;
t.arg = &b;
t.cb = testempty_cmp;
tkx.fbk = NULL;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@XXXdef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Not found, no fallthrough, kept. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@@@def";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = NULL;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@@@def";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Not found, fallthrough, discarded. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@@@def";
testsz = strlen(test);
t.key = NULL;
t.keysz = 0;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abcdef";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Error: not terminated. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@def";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = NULL;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@def";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Error: not terminated (w/fallthrough). */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@def";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@def";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Error: not terminated at eof. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc@@";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Full span. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "@@foobar@@";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "foo";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Empty string. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Only delim. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "@@";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
tkx.fbk = test1_fallthrough;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "@@";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Escaped. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc\\@@foobar\\@@def";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@foobar@@def";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
/* Escaped at eof. */
free(b.buf);
memset(&b, 0, sizeof(struct kcgi_buf));
test = "abc\\@@";
testsz = strlen(test);
t.key = keys;
t.keysz = 1;
t.arg = &b;
t.cb = test1_cmp;
rc = khttp_templatex_buf(&t, test, testsz, &tkx, &b);
if (KCGI_OK != rc)
goto out;
r = "abc@@";
rsz = strlen(r);
if (b.sz != rsz || memcmp(r, b.buf, rsz))
goto out;
c = EXIT_SUCCESS;
out:
free(b.buf);
return(c);
}