1*ae771770SStanislav Sedov /*
2*ae771770SStanislav Sedov * Copyright (c) 2004 Kungliga Tekniska Högskolan
3*ae771770SStanislav Sedov * (Royal Institute of Technology, Stockholm, Sweden).
4*ae771770SStanislav Sedov * All rights reserved.
5*ae771770SStanislav Sedov *
6*ae771770SStanislav Sedov * Redistribution and use in source and binary forms, with or without
7*ae771770SStanislav Sedov * modification, are permitted provided that the following conditions
8*ae771770SStanislav Sedov * are met:
9*ae771770SStanislav Sedov *
10*ae771770SStanislav Sedov * 1. Redistributions of source code must retain the above copyright
11*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer.
12*ae771770SStanislav Sedov *
13*ae771770SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright
14*ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer in the
15*ae771770SStanislav Sedov * documentation and/or other materials provided with the distribution.
16*ae771770SStanislav Sedov *
17*ae771770SStanislav Sedov * 3. Neither the name of the Institute nor the names of its contributors
18*ae771770SStanislav Sedov * may be used to endorse or promote products derived from this software
19*ae771770SStanislav Sedov * without specific prior written permission.
20*ae771770SStanislav Sedov *
21*ae771770SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22*ae771770SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*ae771770SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*ae771770SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25*ae771770SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*ae771770SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*ae771770SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*ae771770SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*ae771770SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*ae771770SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*ae771770SStanislav Sedov * SUCH DAMAGE.
32*ae771770SStanislav Sedov */
33*ae771770SStanislav Sedov
34*ae771770SStanislav Sedov #ifdef HAVE_CONFIG_H
35*ae771770SStanislav Sedov #include <config.h>
36*ae771770SStanislav Sedov #endif
37*ae771770SStanislav Sedov #include <stdio.h>
38*ae771770SStanislav Sedov #include <stdlib.h>
39*ae771770SStanislav Sedov #include <string.h>
40*ae771770SStanislav Sedov #include <err.h>
41*ae771770SStanislav Sedov
42*ae771770SStanislav Sedov #include <roken.h>
43*ae771770SStanislav Sedov
44*ae771770SStanislav Sedov #include "windlocl.h"
45*ae771770SStanislav Sedov #include "normalize_table.h"
46*ae771770SStanislav Sedov
47*ae771770SStanislav Sedov static size_t
parse_vector(char * buf,uint32_t * v)48*ae771770SStanislav Sedov parse_vector(char *buf, uint32_t *v)
49*ae771770SStanislav Sedov {
50*ae771770SStanislav Sedov char *last;
51*ae771770SStanislav Sedov unsigned ret = 0;
52*ae771770SStanislav Sedov const char *n;
53*ae771770SStanislav Sedov unsigned u;
54*ae771770SStanislav Sedov
55*ae771770SStanislav Sedov for(n = strtok_r(buf, " ", &last);
56*ae771770SStanislav Sedov n != NULL;
57*ae771770SStanislav Sedov n = strtok_r(NULL, " ", &last)) {
58*ae771770SStanislav Sedov if (ret >= MAX_LENGTH_CANON) {
59*ae771770SStanislav Sedov errx(1, "increase MAX_LENGTH_CANON");
60*ae771770SStanislav Sedov }
61*ae771770SStanislav Sedov if (sscanf(n, "%x", &u) != 1) {
62*ae771770SStanislav Sedov errx(1, "failed to parse hex: %s", n);
63*ae771770SStanislav Sedov }
64*ae771770SStanislav Sedov v[ret] = u;
65*ae771770SStanislav Sedov ++ret;
66*ae771770SStanislav Sedov }
67*ae771770SStanislav Sedov return ret;
68*ae771770SStanislav Sedov }
69*ae771770SStanislav Sedov
70*ae771770SStanislav Sedov static void
dump_vector(const char * msg,uint32_t * v,size_t len)71*ae771770SStanislav Sedov dump_vector(const char * msg, uint32_t * v, size_t len)
72*ae771770SStanislav Sedov {
73*ae771770SStanislav Sedov size_t i;
74*ae771770SStanislav Sedov
75*ae771770SStanislav Sedov printf("%s: (%d) ", msg, (int)len);
76*ae771770SStanislav Sedov for (i=0; i < len; i++) {
77*ae771770SStanislav Sedov printf("%s%x", (i > 0? " ":""), v[i]);
78*ae771770SStanislav Sedov }
79*ae771770SStanislav Sedov printf("\n");
80*ae771770SStanislav Sedov }
81*ae771770SStanislav Sedov
82*ae771770SStanislav Sedov static int
test(char * buf,unsigned lineno)83*ae771770SStanislav Sedov test(char *buf, unsigned lineno)
84*ae771770SStanislav Sedov {
85*ae771770SStanislav Sedov char *last;
86*ae771770SStanislav Sedov char *c;
87*ae771770SStanislav Sedov uint32_t in[MAX_LENGTH_CANON];
88*ae771770SStanislav Sedov size_t in_len;
89*ae771770SStanislav Sedov uint32_t out[MAX_LENGTH_CANON];
90*ae771770SStanislav Sedov size_t out_len;
91*ae771770SStanislav Sedov uint32_t *tmp;
92*ae771770SStanislav Sedov size_t norm_len;
93*ae771770SStanislav Sedov int ret;
94*ae771770SStanislav Sedov
95*ae771770SStanislav Sedov c = strtok_r(buf, ";", &last);
96*ae771770SStanislav Sedov if (c == NULL)
97*ae771770SStanislav Sedov return 0;
98*ae771770SStanislav Sedov
99*ae771770SStanislav Sedov in_len = parse_vector(c, in);
100*ae771770SStanislav Sedov if (strtok_r(NULL, ";", &last) == NULL)
101*ae771770SStanislav Sedov return 0;
102*ae771770SStanislav Sedov if (strtok_r(NULL, ";", &last) == NULL)
103*ae771770SStanislav Sedov return 0;
104*ae771770SStanislav Sedov c = strtok_r(NULL, ";", &last);
105*ae771770SStanislav Sedov if (c == NULL)
106*ae771770SStanislav Sedov return 0;
107*ae771770SStanislav Sedov out_len = parse_vector(c, out);
108*ae771770SStanislav Sedov if (strtok_r(NULL, ";", &last) == NULL)
109*ae771770SStanislav Sedov return 0;
110*ae771770SStanislav Sedov c = last;
111*ae771770SStanislav Sedov
112*ae771770SStanislav Sedov norm_len = MAX_LENGTH_CANON;
113*ae771770SStanislav Sedov tmp = malloc(norm_len * sizeof(uint32_t));
114*ae771770SStanislav Sedov if (tmp == NULL && norm_len != 0)
115*ae771770SStanislav Sedov err(1, "malloc");
116*ae771770SStanislav Sedov ret = _wind_stringprep_normalize(in, in_len, tmp, &norm_len);
117*ae771770SStanislav Sedov if (ret) {
118*ae771770SStanislav Sedov printf("wind_stringprep_normalize %s failed\n", c);
119*ae771770SStanislav Sedov free(tmp);
120*ae771770SStanislav Sedov return 1;
121*ae771770SStanislav Sedov }
122*ae771770SStanislav Sedov if (out_len != norm_len) {
123*ae771770SStanislav Sedov printf("%u: wrong out len (%s)\n", lineno, c);
124*ae771770SStanislav Sedov dump_vector("Expected", out, out_len);
125*ae771770SStanislav Sedov dump_vector("Received", tmp, norm_len);
126*ae771770SStanislav Sedov free(tmp);
127*ae771770SStanislav Sedov return 1;
128*ae771770SStanislav Sedov }
129*ae771770SStanislav Sedov if (memcmp(out, tmp, out_len * sizeof(uint32_t)) != 0) {
130*ae771770SStanislav Sedov printf("%u: wrong out data (%s)\n", lineno, c);
131*ae771770SStanislav Sedov dump_vector("Expected", out, out_len);
132*ae771770SStanislav Sedov dump_vector("Received", tmp, norm_len);
133*ae771770SStanislav Sedov free(tmp);
134*ae771770SStanislav Sedov return 1;
135*ae771770SStanislav Sedov }
136*ae771770SStanislav Sedov free(tmp);
137*ae771770SStanislav Sedov return 0;
138*ae771770SStanislav Sedov }
139*ae771770SStanislav Sedov
140*ae771770SStanislav Sedov int
main(int argc,char ** argv)141*ae771770SStanislav Sedov main(int argc, char **argv)
142*ae771770SStanislav Sedov {
143*ae771770SStanislav Sedov FILE *f;
144*ae771770SStanislav Sedov char buf[1024];
145*ae771770SStanislav Sedov char filename[256] = "NormalizationTest.txt";
146*ae771770SStanislav Sedov unsigned failures = 0;
147*ae771770SStanislav Sedov unsigned lineno = 0;
148*ae771770SStanislav Sedov
149*ae771770SStanislav Sedov if (argc > 2)
150*ae771770SStanislav Sedov errx(1, "usage: %s [file]", argv[0]);
151*ae771770SStanislav Sedov else if (argc == 2)
152*ae771770SStanislav Sedov strlcpy(filename, argv[1], sizeof(filename));
153*ae771770SStanislav Sedov
154*ae771770SStanislav Sedov f = fopen(filename, "r");
155*ae771770SStanislav Sedov if (f == NULL) {
156*ae771770SStanislav Sedov const char *srcdir = getenv("srcdir");
157*ae771770SStanislav Sedov if (srcdir != NULL) {
158*ae771770SStanislav Sedov char longname[256];
159*ae771770SStanislav Sedov snprintf(longname, sizeof(longname), "%s/%s", srcdir, filename);
160*ae771770SStanislav Sedov f = fopen(longname, "r");
161*ae771770SStanislav Sedov }
162*ae771770SStanislav Sedov if (f == NULL)
163*ae771770SStanislav Sedov err(1, "open %s", filename);
164*ae771770SStanislav Sedov }
165*ae771770SStanislav Sedov while (fgets(buf, sizeof(buf), f) != NULL) {
166*ae771770SStanislav Sedov lineno++;
167*ae771770SStanislav Sedov if (buf[0] == '#')
168*ae771770SStanislav Sedov continue;
169*ae771770SStanislav Sedov if (buf[0] == '@') {
170*ae771770SStanislav Sedov continue;
171*ae771770SStanislav Sedov }
172*ae771770SStanislav Sedov failures += test(buf, lineno);
173*ae771770SStanislav Sedov }
174*ae771770SStanislav Sedov fclose(f);
175*ae771770SStanislav Sedov return failures != 0;
176*ae771770SStanislav Sedov }
177