1226031Sstas/* 2226031Sstas * Copyright (c) 2004 Kungliga Tekniska H��gskolan 3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4226031Sstas * All rights reserved. 5226031Sstas * 6226031Sstas * Redistribution and use in source and binary forms, with or without 7226031Sstas * modification, are permitted provided that the following conditions 8226031Sstas * are met: 9226031Sstas * 10226031Sstas * 1. Redistributions of source code must retain the above copyright 11226031Sstas * notice, this list of conditions and the following disclaimer. 12226031Sstas * 13226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 14226031Sstas * notice, this list of conditions and the following disclaimer in the 15226031Sstas * documentation and/or other materials provided with the distribution. 16226031Sstas * 17226031Sstas * 3. Neither the name of the Institute nor the names of its contributors 18226031Sstas * may be used to endorse or promote products derived from this software 19226031Sstas * without specific prior written permission. 20226031Sstas * 21226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31226031Sstas * SUCH DAMAGE. 32226031Sstas */ 33226031Sstas 34226031Sstas#ifdef HAVE_CONFIG_H 35226031Sstas#include <config.h> 36226031Sstas#endif 37226031Sstas#include <stdio.h> 38226031Sstas#include <stdlib.h> 39226031Sstas#include <string.h> 40226031Sstas#include <err.h> 41226031Sstas 42226031Sstas#include <roken.h> 43226031Sstas 44226031Sstas#include "windlocl.h" 45226031Sstas#include "normalize_table.h" 46226031Sstas 47226031Sstasstatic size_t 48226031Sstasparse_vector(char *buf, uint32_t *v) 49226031Sstas{ 50226031Sstas char *last; 51226031Sstas unsigned ret = 0; 52226031Sstas const char *n; 53226031Sstas unsigned u; 54226031Sstas 55226031Sstas for(n = strtok_r(buf, " ", &last); 56226031Sstas n != NULL; 57226031Sstas n = strtok_r(NULL, " ", &last)) { 58226031Sstas if (ret >= MAX_LENGTH_CANON) { 59226031Sstas errx(1, "increase MAX_LENGTH_CANON"); 60226031Sstas } 61226031Sstas if (sscanf(n, "%x", &u) != 1) { 62226031Sstas errx(1, "failed to parse hex: %s", n); 63226031Sstas } 64226031Sstas v[ret] = u; 65226031Sstas ++ret; 66226031Sstas } 67226031Sstas return ret; 68226031Sstas} 69226031Sstas 70226031Sstasstatic void 71226031Sstasdump_vector(const char * msg, uint32_t * v, size_t len) 72226031Sstas{ 73226031Sstas size_t i; 74226031Sstas 75226031Sstas printf("%s: (%d) ", msg, (int)len); 76226031Sstas for (i=0; i < len; i++) { 77226031Sstas printf("%s%x", (i > 0? " ":""), v[i]); 78226031Sstas } 79226031Sstas printf("\n"); 80226031Sstas} 81226031Sstas 82226031Sstasstatic int 83226031Sstastest(char *buf, unsigned lineno) 84226031Sstas{ 85226031Sstas char *last; 86226031Sstas char *c; 87226031Sstas uint32_t in[MAX_LENGTH_CANON]; 88226031Sstas size_t in_len; 89226031Sstas uint32_t out[MAX_LENGTH_CANON]; 90226031Sstas size_t out_len; 91226031Sstas uint32_t *tmp; 92226031Sstas size_t norm_len; 93226031Sstas int ret; 94226031Sstas 95226031Sstas c = strtok_r(buf, ";", &last); 96226031Sstas if (c == NULL) 97226031Sstas return 0; 98226031Sstas 99226031Sstas in_len = parse_vector(c, in); 100226031Sstas if (strtok_r(NULL, ";", &last) == NULL) 101226031Sstas return 0; 102226031Sstas if (strtok_r(NULL, ";", &last) == NULL) 103226031Sstas return 0; 104226031Sstas c = strtok_r(NULL, ";", &last); 105226031Sstas if (c == NULL) 106226031Sstas return 0; 107226031Sstas out_len = parse_vector(c, out); 108226031Sstas if (strtok_r(NULL, ";", &last) == NULL) 109226031Sstas return 0; 110226031Sstas c = last; 111226031Sstas 112226031Sstas norm_len = MAX_LENGTH_CANON; 113226031Sstas tmp = malloc(norm_len * sizeof(uint32_t)); 114226031Sstas if (tmp == NULL && norm_len != 0) 115226031Sstas err(1, "malloc"); 116226031Sstas ret = _wind_stringprep_normalize(in, in_len, tmp, &norm_len); 117226031Sstas if (ret) { 118226031Sstas printf("wind_stringprep_normalize %s failed\n", c); 119226031Sstas free(tmp); 120226031Sstas return 1; 121226031Sstas } 122226031Sstas if (out_len != norm_len) { 123226031Sstas printf("%u: wrong out len (%s)\n", lineno, c); 124226031Sstas dump_vector("Expected", out, out_len); 125226031Sstas dump_vector("Received", tmp, norm_len); 126226031Sstas free(tmp); 127226031Sstas return 1; 128226031Sstas } 129226031Sstas if (memcmp(out, tmp, out_len * sizeof(uint32_t)) != 0) { 130226031Sstas printf("%u: wrong out data (%s)\n", lineno, c); 131226031Sstas dump_vector("Expected", out, out_len); 132226031Sstas dump_vector("Received", tmp, norm_len); 133226031Sstas free(tmp); 134226031Sstas return 1; 135226031Sstas } 136226031Sstas free(tmp); 137226031Sstas return 0; 138226031Sstas} 139226031Sstas 140226031Sstasint 141226031Sstasmain(int argc, char **argv) 142226031Sstas{ 143226031Sstas FILE *f; 144226031Sstas char buf[1024]; 145226031Sstas char filename[256] = "NormalizationTest.txt"; 146226031Sstas unsigned failures = 0; 147226031Sstas unsigned lineno = 0; 148226031Sstas 149226031Sstas if (argc > 2) 150226031Sstas errx(1, "usage: %s [file]", argv[0]); 151226031Sstas else if (argc == 2) 152226031Sstas strlcpy(filename, argv[1], sizeof(filename)); 153226031Sstas 154226031Sstas f = fopen(filename, "r"); 155226031Sstas if (f == NULL) { 156226031Sstas const char *srcdir = getenv("srcdir"); 157226031Sstas if (srcdir != NULL) { 158226031Sstas char longname[256]; 159226031Sstas snprintf(longname, sizeof(longname), "%s/%s", srcdir, filename); 160226031Sstas f = fopen(longname, "r"); 161226031Sstas } 162226031Sstas if (f == NULL) 163226031Sstas err(1, "open %s", filename); 164226031Sstas } 165226031Sstas while (fgets(buf, sizeof(buf), f) != NULL) { 166226031Sstas lineno++; 167226031Sstas if (buf[0] == '#') 168226031Sstas continue; 169226031Sstas if (buf[0] == '@') { 170226031Sstas continue; 171226031Sstas } 172226031Sstas failures += test(buf, lineno); 173226031Sstas } 174226031Sstas fclose(f); 175226031Sstas return failures != 0; 176226031Sstas} 177