mirror of
https://github.com/bdnugget/kcgi.git
synced 2026-11-07 05:47:27 +00:00
450 lines
9.3 KiB
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);
|
|
}
|