1ddba0402SEnji Cooper /* $NetBSD: t_vis.c,v 1.9 2017/01/10 15:16:57 christos Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*-
457718be8SEnji Cooper * Copyright (c) 2002 The NetBSD Foundation, Inc.
557718be8SEnji Cooper * All rights reserved.
657718be8SEnji Cooper *
757718be8SEnji Cooper * This code was contributed to The NetBSD Foundation by Christos Zoulas.
857718be8SEnji Cooper *
957718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
1057718be8SEnji Cooper * modification, are permitted provided that the following conditions
1157718be8SEnji Cooper * are met:
1257718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer.
1457718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1557718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the
1657718be8SEnji Cooper * documentation and/or other materials provided with the distribution.
1757718be8SEnji Cooper *
1857718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1957718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2057718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2157718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2257718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2357718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2457718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2557718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2657718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2757718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2857718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
2957718be8SEnji Cooper */
3057718be8SEnji Cooper
3157718be8SEnji Cooper #include <atf-c.h>
3257718be8SEnji Cooper
3357718be8SEnji Cooper #include <string.h>
3457718be8SEnji Cooper #include <stdlib.h>
35640235e2SEnji Cooper #include <locale.h>
3657718be8SEnji Cooper #include <err.h>
3757718be8SEnji Cooper #include <vis.h>
3857718be8SEnji Cooper
3957718be8SEnji Cooper static int styles[] = {
4057718be8SEnji Cooper VIS_OCTAL,
4157718be8SEnji Cooper VIS_CSTYLE,
4257718be8SEnji Cooper VIS_SP,
4357718be8SEnji Cooper VIS_TAB,
4457718be8SEnji Cooper VIS_NL,
4557718be8SEnji Cooper VIS_WHITE,
4657718be8SEnji Cooper VIS_SAFE,
4757718be8SEnji Cooper #if 0 /* Not reversible */
4857718be8SEnji Cooper VIS_NOSLASH,
4957718be8SEnji Cooper #endif
5057718be8SEnji Cooper VIS_HTTP1808,
5157718be8SEnji Cooper VIS_MIMESTYLE,
5257718be8SEnji Cooper #if 0 /* Not supported by vis(3) */
5357718be8SEnji Cooper VIS_HTTP1866,
5457718be8SEnji Cooper #endif
5557718be8SEnji Cooper };
5657718be8SEnji Cooper
5757718be8SEnji Cooper #define SIZE 256
5857718be8SEnji Cooper
5957718be8SEnji Cooper ATF_TC(strvis_basic);
ATF_TC_HEAD(strvis_basic,tc)6057718be8SEnji Cooper ATF_TC_HEAD(strvis_basic, tc)
6157718be8SEnji Cooper {
6257718be8SEnji Cooper
6357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strvis(3)");
6457718be8SEnji Cooper }
6557718be8SEnji Cooper
ATF_TC_BODY(strvis_basic,tc)6657718be8SEnji Cooper ATF_TC_BODY(strvis_basic, tc)
6757718be8SEnji Cooper {
6857718be8SEnji Cooper char *srcbuf, *dstbuf, *visbuf;
6957718be8SEnji Cooper unsigned int i, j;
7057718be8SEnji Cooper
7157718be8SEnji Cooper ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL);
7257718be8SEnji Cooper ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL);
7357718be8SEnji Cooper ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL);
7457718be8SEnji Cooper
7557718be8SEnji Cooper for (i = 0; i < SIZE; i++)
7657718be8SEnji Cooper srcbuf[i] = (char)i;
7757718be8SEnji Cooper
7857718be8SEnji Cooper for (i = 0; i < __arraycount(styles); i++) {
7957718be8SEnji Cooper ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0);
8057718be8SEnji Cooper memset(dstbuf, 0, SIZE);
8157718be8SEnji Cooper ATF_REQUIRE(strunvisx(dstbuf, visbuf,
8257718be8SEnji Cooper styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0);
8357718be8SEnji Cooper for (j = 0; j < SIZE; j++)
8457718be8SEnji Cooper if (dstbuf[j] != (char)j)
8557718be8SEnji Cooper atf_tc_fail_nonfatal("Failed for style %x, "
8657718be8SEnji Cooper "char %d [%d]", styles[i], j, dstbuf[j]);
8757718be8SEnji Cooper }
8857718be8SEnji Cooper free(dstbuf);
8957718be8SEnji Cooper free(srcbuf);
9057718be8SEnji Cooper free(visbuf);
9157718be8SEnji Cooper }
9257718be8SEnji Cooper
9357718be8SEnji Cooper ATF_TC(strvis_null);
ATF_TC_HEAD(strvis_null,tc)9457718be8SEnji Cooper ATF_TC_HEAD(strvis_null, tc)
9557718be8SEnji Cooper {
9657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL");
9757718be8SEnji Cooper }
9857718be8SEnji Cooper
ATF_TC_BODY(strvis_null,tc)9957718be8SEnji Cooper ATF_TC_BODY(strvis_null, tc)
10057718be8SEnji Cooper {
10157718be8SEnji Cooper char dst[] = "fail";
10257718be8SEnji Cooper strvis(dst, NULL, VIS_SAFE);
10357718be8SEnji Cooper ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a');
10457718be8SEnji Cooper }
10557718be8SEnji Cooper
10657718be8SEnji Cooper ATF_TC(strvis_empty);
ATF_TC_HEAD(strvis_empty,tc)10757718be8SEnji Cooper ATF_TC_HEAD(strvis_empty, tc)
10857718be8SEnji Cooper {
10957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty");
11057718be8SEnji Cooper }
11157718be8SEnji Cooper
ATF_TC_BODY(strvis_empty,tc)11257718be8SEnji Cooper ATF_TC_BODY(strvis_empty, tc)
11357718be8SEnji Cooper {
11457718be8SEnji Cooper char dst[] = "fail";
11557718be8SEnji Cooper strvis(dst, "", VIS_SAFE);
11657718be8SEnji Cooper ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a');
11757718be8SEnji Cooper }
11857718be8SEnji Cooper
11957718be8SEnji Cooper ATF_TC(strunvis_hex);
ATF_TC_HEAD(strunvis_hex,tc)12057718be8SEnji Cooper ATF_TC_HEAD(strunvis_hex, tc)
12157718be8SEnji Cooper {
12257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX");
12357718be8SEnji Cooper }
12457718be8SEnji Cooper
ATF_TC_BODY(strunvis_hex,tc)12557718be8SEnji Cooper ATF_TC_BODY(strunvis_hex, tc)
12657718be8SEnji Cooper {
12757718be8SEnji Cooper static const struct {
12857718be8SEnji Cooper const char *e;
12957718be8SEnji Cooper const char *d;
13057718be8SEnji Cooper int error;
13157718be8SEnji Cooper } ed[] = {
13257718be8SEnji Cooper { "\\xff", "\xff", 1 },
13357718be8SEnji Cooper { "\\x1", "\x1", 1 },
13457718be8SEnji Cooper { "\\x1\\x02", "\x1\x2", 2 },
13557718be8SEnji Cooper { "\\x1x", "\x1x", 2 },
13657718be8SEnji Cooper { "\\xx", "", -1 },
13757718be8SEnji Cooper };
13857718be8SEnji Cooper char uv[10];
13957718be8SEnji Cooper
14057718be8SEnji Cooper for (size_t i = 0; i < __arraycount(ed); i++) {
14157718be8SEnji Cooper ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error);
14257718be8SEnji Cooper if (ed[i].error > 0)
14357718be8SEnji Cooper ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0);
14457718be8SEnji Cooper }
14557718be8SEnji Cooper }
14657718be8SEnji Cooper
14772a02000SEnji Cooper #ifdef VIS_NOLOCALE
148640235e2SEnji Cooper ATF_TC(strvis_locale);
ATF_TC_HEAD(strvis_locale,tc)149640235e2SEnji Cooper ATF_TC_HEAD(strvis_locale, tc)
150640235e2SEnji Cooper {
151640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strvis(3) with locale");
152640235e2SEnji Cooper }
153640235e2SEnji Cooper
ATF_TC_BODY(strvis_locale,tc)154640235e2SEnji Cooper ATF_TC_BODY(strvis_locale, tc)
155640235e2SEnji Cooper {
156640235e2SEnji Cooper char s[256], cd[sizeof(s) * 4 + 1], jd[sizeof(cd)], *ol;
157640235e2SEnji Cooper int jr, cr;
158640235e2SEnji Cooper
159640235e2SEnji Cooper for (size_t i = 0; i < sizeof(s) - 1; i++)
160640235e2SEnji Cooper s[i] = i + 1;
161640235e2SEnji Cooper s[sizeof(s) - 1] = '\0';
162640235e2SEnji Cooper
163640235e2SEnji Cooper ol = setlocale(LC_CTYPE, "ja_JP.UTF-8");
164640235e2SEnji Cooper ATF_REQUIRE(ol != NULL);
165640235e2SEnji Cooper jr = strvisx(jd, s, sizeof(s), VIS_WHITE | VIS_NOLOCALE);
166640235e2SEnji Cooper ATF_REQUIRE(jr != -1);
167640235e2SEnji Cooper ol = strdup(ol);
168640235e2SEnji Cooper ATF_REQUIRE(ol != NULL);
169640235e2SEnji Cooper ATF_REQUIRE(setlocale(LC_CTYPE, "C") != NULL);
170640235e2SEnji Cooper cr = strvisx(cd, s, sizeof(s), VIS_WHITE);
171640235e2SEnji Cooper ATF_REQUIRE(jr == cr);
172640235e2SEnji Cooper ATF_REQUIRE(memcmp(jd, cd, jr) == 0);
173640235e2SEnji Cooper setlocale(LC_CTYPE, ol);
174640235e2SEnji Cooper free(ol);
175640235e2SEnji Cooper }
17672a02000SEnji Cooper #endif /* VIS_NOLOCALE */
177640235e2SEnji Cooper
1782f489a50SKyle Evans #ifdef __FreeBSD__
179*79e6ffb6SKyle Evans #define STRVIS_OVERFLOW_MARKER ((char)0xff) /* Arbitrary */
1802f489a50SKyle Evans
1812f489a50SKyle Evans ATF_TC(strvis_overflow_mb);
ATF_TC_HEAD(strvis_overflow_mb,tc)1822f489a50SKyle Evans ATF_TC_HEAD(strvis_overflow_mb, tc)
1832f489a50SKyle Evans {
1842f489a50SKyle Evans atf_tc_set_md_var(tc, "descr", "Test strvis(3) multi-byte overflow");
1852f489a50SKyle Evans }
1862f489a50SKyle Evans
ATF_TC_BODY(strvis_overflow_mb,tc)1872f489a50SKyle Evans ATF_TC_BODY(strvis_overflow_mb, tc)
1882f489a50SKyle Evans {
1892f489a50SKyle Evans const char src[] = "\xf0\x9f\xa5\x91";
1902f489a50SKyle Evans /* Extra byte to detect overflow */
1912f489a50SKyle Evans char dst[sizeof(src) + 1];
1922f489a50SKyle Evans int n;
1932f489a50SKyle Evans
1942f489a50SKyle Evans setlocale(LC_CTYPE, "en_US.UTF-8");
1952f489a50SKyle Evans
1962f489a50SKyle Evans /* Arbitrary */
1972f489a50SKyle Evans memset(dst, STRVIS_OVERFLOW_MARKER, sizeof(dst));
1982f489a50SKyle Evans
1992f489a50SKyle Evans /*
2002f489a50SKyle Evans * If we only provide four bytes of buffer, we shouldn't be able encode
2012f489a50SKyle Evans * a full 4-byte sequence.
2022f489a50SKyle Evans */
2032f489a50SKyle Evans n = strnvis(dst, 4, src, VIS_SAFE);
2042f489a50SKyle Evans ATF_REQUIRE(dst[4] == STRVIS_OVERFLOW_MARKER);
2052f489a50SKyle Evans ATF_REQUIRE(n == -1);
2062f489a50SKyle Evans
2072f489a50SKyle Evans n = strnvis(dst, sizeof(src), src, VIS_SAFE);
2082f489a50SKyle Evans ATF_REQUIRE(n == sizeof(src) - 1);
2092f489a50SKyle Evans }
2102f489a50SKyle Evans
2112f489a50SKyle Evans ATF_TC(strvis_overflow_c);
ATF_TC_HEAD(strvis_overflow_c,tc)2122f489a50SKyle Evans ATF_TC_HEAD(strvis_overflow_c, tc)
2132f489a50SKyle Evans {
2142f489a50SKyle Evans atf_tc_set_md_var(tc, "descr", "Test strvis(3) C locale overflow");
2152f489a50SKyle Evans }
2162f489a50SKyle Evans
ATF_TC_BODY(strvis_overflow_c,tc)2172f489a50SKyle Evans ATF_TC_BODY(strvis_overflow_c, tc)
2182f489a50SKyle Evans {
2192f489a50SKyle Evans const char src[] = "AAAA";
2202f489a50SKyle Evans /* Extra byte to detect overflow */
2212f489a50SKyle Evans char dst[sizeof(src) + 1];
2222f489a50SKyle Evans int n;
2232f489a50SKyle Evans
2242f489a50SKyle Evans /* Arbitrary */
2252f489a50SKyle Evans memset(dst, STRVIS_OVERFLOW_MARKER, sizeof(dst));
2262f489a50SKyle Evans
2272f489a50SKyle Evans /*
2282f489a50SKyle Evans * If we only provide four bytes of buffer, we shouldn't be able encode
2292f489a50SKyle Evans * 4 bytes of input.
2302f489a50SKyle Evans */
2312f489a50SKyle Evans n = strnvis(dst, 4, src, VIS_SAFE | VIS_NOLOCALE);
2322f489a50SKyle Evans ATF_REQUIRE(dst[4] == STRVIS_OVERFLOW_MARKER);
2332f489a50SKyle Evans ATF_REQUIRE(n == -1);
2342f489a50SKyle Evans
2352f489a50SKyle Evans n = strnvis(dst, sizeof(src), src, VIS_SAFE | VIS_NOLOCALE);
2362f489a50SKyle Evans ATF_REQUIRE(n == sizeof(src) - 1);
2372f489a50SKyle Evans }
2382f489a50SKyle Evans #endif /* __FreeBSD__ */
2392f489a50SKyle Evans
ATF_TP_ADD_TCS(tp)24057718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
24157718be8SEnji Cooper {
24257718be8SEnji Cooper
24357718be8SEnji Cooper ATF_TP_ADD_TC(tp, strvis_basic);
24457718be8SEnji Cooper ATF_TP_ADD_TC(tp, strvis_null);
24557718be8SEnji Cooper ATF_TP_ADD_TC(tp, strvis_empty);
24657718be8SEnji Cooper ATF_TP_ADD_TC(tp, strunvis_hex);
24772a02000SEnji Cooper #ifdef VIS_NOLOCALE
248640235e2SEnji Cooper ATF_TP_ADD_TC(tp, strvis_locale);
24972a02000SEnji Cooper #endif /* VIS_NOLOCALE */
2502f489a50SKyle Evans #ifdef __FreeBSD__
2512f489a50SKyle Evans ATF_TP_ADD_TC(tp, strvis_overflow_mb);
2522f489a50SKyle Evans ATF_TP_ADD_TC(tp, strvis_overflow_c);
2532f489a50SKyle Evans #endif
25457718be8SEnji Cooper
25557718be8SEnji Cooper return atf_no_error();
25657718be8SEnji Cooper }
257