1*058561cbSjbeck /* 2*058561cbSjbeck * Copyright (c) 2006 Sendmail, Inc. and its suppliers. 3*058561cbSjbeck * All rights reserved. 4*058561cbSjbeck * 5*058561cbSjbeck * By using this file, you agree to the terms and conditions set 6*058561cbSjbeck * forth in the LICENSE file which can be found at the top level of 7*058561cbSjbeck * the sendmail distribution. 8*058561cbSjbeck */ 9*058561cbSjbeck 10*058561cbSjbeck #pragma ident "%Z%%M% %I% %E% SMI" 11*058561cbSjbeck 12*058561cbSjbeck #include <sm/gen.h> 13*058561cbSjbeck SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.9 2006/08/24 21:26:13 ca Exp $") 14*058561cbSjbeck 15*058561cbSjbeck #include <stdio.h> 16*058561cbSjbeck #include <sm/sendmail.h> 17*058561cbSjbeck #include <sm/assert.h> 18*058561cbSjbeck #include <sm/heap.h> 19*058561cbSjbeck #include <sm/string.h> 20*058561cbSjbeck #include <sm/test.h> 21*058561cbSjbeck 22*058561cbSjbeck extern bool SmTestVerbose; 23*058561cbSjbeck 24*058561cbSjbeck 25*058561cbSjbeck void 26*058561cbSjbeck show_diff(s1, s2) 27*058561cbSjbeck const char *s1; 28*058561cbSjbeck const char *s2; 29*058561cbSjbeck { 30*058561cbSjbeck int i; 31*058561cbSjbeck 32*058561cbSjbeck for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++) 33*058561cbSjbeck { 34*058561cbSjbeck if (s1[i] != s2[i]) 35*058561cbSjbeck { 36*058561cbSjbeck fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n", 37*058561cbSjbeck i, (unsigned char) s1[i], 38*058561cbSjbeck (unsigned char) s2[i]); 39*058561cbSjbeck return; 40*058561cbSjbeck } 41*058561cbSjbeck } 42*058561cbSjbeck if (s1[i] != s2[i]) 43*058561cbSjbeck { 44*058561cbSjbeck fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n", 45*058561cbSjbeck i, (unsigned char) s1[i], (unsigned char) s2[i]); 46*058561cbSjbeck } 47*058561cbSjbeck } 48*058561cbSjbeck 49*058561cbSjbeck char *quote_unquote __P((char *, char *, int, int)); 50*058561cbSjbeck 51*058561cbSjbeck char * 52*058561cbSjbeck quote_unquote(in, out, outlen, exp) 53*058561cbSjbeck char *in; 54*058561cbSjbeck char *out; 55*058561cbSjbeck int outlen; 56*058561cbSjbeck int exp; 57*058561cbSjbeck { 58*058561cbSjbeck char *obp, *bp; 59*058561cbSjbeck char line_back[1024]; 60*058561cbSjbeck char line_in[1024]; 61*058561cbSjbeck int cmp; 62*058561cbSjbeck 63*058561cbSjbeck sm_strlcpy(line_in, in, sizeof(line_in)); 64*058561cbSjbeck obp = quote_internal_chars(in, out, &outlen); 65*058561cbSjbeck bp = str2prt(line_in); 66*058561cbSjbeck dequote_internal_chars(obp, line_back, sizeof(line_back)); 67*058561cbSjbeck cmp = strcmp(line_in, line_back); 68*058561cbSjbeck SM_TEST(exp == cmp); 69*058561cbSjbeck if (cmp != exp && !SmTestVerbose) 70*058561cbSjbeck { 71*058561cbSjbeck fprintf(stderr, "in: %s\n", bp); 72*058561cbSjbeck bp = str2prt(line_back); 73*058561cbSjbeck fprintf(stderr, "out:%s\n", bp); 74*058561cbSjbeck fprintf(stderr, "cmp=%d\n", cmp); 75*058561cbSjbeck show_diff(in, line_back); 76*058561cbSjbeck } 77*058561cbSjbeck if (SmTestVerbose) 78*058561cbSjbeck { 79*058561cbSjbeck fprintf(stderr, "%s -> ", bp); 80*058561cbSjbeck bp = str2prt(obp); 81*058561cbSjbeck fprintf(stderr, "%s\n", bp); 82*058561cbSjbeck fprintf(stderr, "cmp=%d\n", cmp); 83*058561cbSjbeck } 84*058561cbSjbeck return obp; 85*058561cbSjbeck } 86*058561cbSjbeck 87*058561cbSjbeck struct sm_qic_S 88*058561cbSjbeck { 89*058561cbSjbeck char *qic_in; 90*058561cbSjbeck char *qic_out; 91*058561cbSjbeck int qic_exp; 92*058561cbSjbeck }; 93*058561cbSjbeck 94*058561cbSjbeck typedef struct sm_qic_S sm_qic_T; 95*058561cbSjbeck 96*058561cbSjbeck 97*058561cbSjbeck int 98*058561cbSjbeck main(argc, argv) 99*058561cbSjbeck int argc; 100*058561cbSjbeck char *argv[]; 101*058561cbSjbeck { 102*058561cbSjbeck char line_in[1024], line[256], line_out[32], *obp; 103*058561cbSjbeck int i, los, cmp; 104*058561cbSjbeck sm_qic_T inout[] = { 105*058561cbSjbeck { "", "", 0 } 106*058561cbSjbeck , { "abcdef", "abcdef", 0 } 107*058561cbSjbeck , { "01234567890123456789", "01234567890123456789", 0 } 108*058561cbSjbeck , { "01234567890123456789\001", "01234567890123456789\001", 109*058561cbSjbeck 0 } 110*058561cbSjbeck , { "012345\2067890123456789", "012345\377\2067890123456789", 111*058561cbSjbeck 0 } 112*058561cbSjbeck , { "\377", "\377\377", 0 } 113*058561cbSjbeck , { "\240", "\240", 0 } 114*058561cbSjbeck , { "\220", "\377\220", 0 } 115*058561cbSjbeck , { "\240\220", "\240\377\220", 0 } 116*058561cbSjbeck , { "\377\377", "\377\377\377\377", 0 } 117*058561cbSjbeck , { "\377a\377b", "\377\377a\377\377b", 0 } 118*058561cbSjbeck , { "\376a\377b", "\376a\377\377b", 0 } 119*058561cbSjbeck , { "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240", 120*058561cbSjbeck "\377\200\377\201\377\202\377\203\377\204\377\205\377\206\377\207\377\210\377\211\377\212\377\213\377\214\377\215\377\216\377\217\377\220\377\221\377\222\377\223\377\224\377\225\377\226\377\227\377\230\377\231\377\232\377\233\377\234\377\235\377\236\377\237\240", 121*058561cbSjbeck 0 } 122*058561cbSjbeck , { NULL, NULL, 0 } 123*058561cbSjbeck }; 124*058561cbSjbeck 125*058561cbSjbeck sm_test_begin(argc, argv, "test meta quoting"); 126*058561cbSjbeck for (i = 0; i < sizeof(line_out); i++) 127*058561cbSjbeck line_out[i] = '\0'; 128*058561cbSjbeck for (i = 0; i < sizeof(line_in); i++) 129*058561cbSjbeck line_in[i] = '\0'; 130*058561cbSjbeck for (i = 0; i < sizeof(line_in) / 2; i++) 131*058561cbSjbeck { 132*058561cbSjbeck char ch; 133*058561cbSjbeck 134*058561cbSjbeck ch = 0200 + i; 135*058561cbSjbeck if ('\0' == ch) 136*058561cbSjbeck ch = '0'; 137*058561cbSjbeck line_in[i] = ch; 138*058561cbSjbeck } 139*058561cbSjbeck los = sizeof(line_out) / 2; 140*058561cbSjbeck obp = quote_unquote(line_in, line_out, los, 0); 141*058561cbSjbeck if (obp != line_out) 142*058561cbSjbeck SM_FREE(obp); 143*058561cbSjbeck 144*058561cbSjbeck for (i = 0; i < sizeof(line_in); i++) 145*058561cbSjbeck line_in[i] = '\0'; 146*058561cbSjbeck for (i = 0; i < sizeof(line_in) / 2; i++) 147*058561cbSjbeck { 148*058561cbSjbeck char ch; 149*058561cbSjbeck 150*058561cbSjbeck ch = 0200 + i; 151*058561cbSjbeck if ('\0' == ch) 152*058561cbSjbeck ch = '0'; 153*058561cbSjbeck line_in[i] = ch; 154*058561cbSjbeck } 155*058561cbSjbeck los = sizeof(line_in); 156*058561cbSjbeck obp = quote_unquote(line_in, line_in, los, 0); 157*058561cbSjbeck if (obp != line_in) 158*058561cbSjbeck SM_FREE(obp); 159*058561cbSjbeck 160*058561cbSjbeck for (i = 0; inout[i].qic_in != NULL; i++) 161*058561cbSjbeck { 162*058561cbSjbeck los = sizeof(line_out) / 2; 163*058561cbSjbeck obp = quote_unquote(inout[i].qic_in, line_out, los, 164*058561cbSjbeck inout[i].qic_exp); 165*058561cbSjbeck cmp = strcmp(inout[i].qic_out, obp); 166*058561cbSjbeck SM_TEST(inout[i].qic_exp == cmp); 167*058561cbSjbeck if (inout[i].qic_exp != cmp && !SmTestVerbose) 168*058561cbSjbeck { 169*058561cbSjbeck char *bp; 170*058561cbSjbeck 171*058561cbSjbeck bp = str2prt(obp); 172*058561cbSjbeck fprintf(stderr, "got: %s\n", bp); 173*058561cbSjbeck bp = str2prt(inout[i].qic_out); 174*058561cbSjbeck fprintf(stderr, "exp:%s\n", bp); 175*058561cbSjbeck fprintf(stderr, "cmp=%d\n", cmp); 176*058561cbSjbeck show_diff(inout[i].qic_in, inout[i].qic_out); 177*058561cbSjbeck } 178*058561cbSjbeck if (obp != line_out) 179*058561cbSjbeck SM_FREE(obp); 180*058561cbSjbeck } 181*058561cbSjbeck 182*058561cbSjbeck /* use same buffer for in and out */ 183*058561cbSjbeck for (i = 0; inout[i].qic_in != NULL; i++) 184*058561cbSjbeck { 185*058561cbSjbeck bool same; 186*058561cbSjbeck 187*058561cbSjbeck same = strcmp(inout[i].qic_in, inout[i].qic_out) == 0; 188*058561cbSjbeck los = sm_strlcpy(line, inout[i].qic_in, sizeof(line)); 189*058561cbSjbeck SM_TEST(los + 1 < sizeof(line)); 190*058561cbSjbeck ++los; 191*058561cbSjbeck obp = quote_unquote(line, line, los, inout[i].qic_exp); 192*058561cbSjbeck cmp = strcmp(inout[i].qic_out, obp); 193*058561cbSjbeck SM_TEST(inout[i].qic_exp == cmp); 194*058561cbSjbeck if (inout[i].qic_exp != cmp && !SmTestVerbose) 195*058561cbSjbeck { 196*058561cbSjbeck char *bp; 197*058561cbSjbeck 198*058561cbSjbeck bp = str2prt(obp); 199*058561cbSjbeck fprintf(stderr, "got: %s\n", bp); 200*058561cbSjbeck bp = str2prt(inout[i].qic_out); 201*058561cbSjbeck fprintf(stderr, "exp:%s\n", bp); 202*058561cbSjbeck fprintf(stderr, "cmp=%d\n", cmp); 203*058561cbSjbeck show_diff(inout[i].qic_in, inout[i].qic_out); 204*058561cbSjbeck } 205*058561cbSjbeck if (obp != line) 206*058561cbSjbeck { 207*058561cbSjbeck SM_TEST(!same); 208*058561cbSjbeck if (same) 209*058561cbSjbeck show_diff(obp, inout[i].qic_out); 210*058561cbSjbeck SM_FREE(obp); 211*058561cbSjbeck } 212*058561cbSjbeck } 213*058561cbSjbeck 214*058561cbSjbeck /* use NULL buffer for out */ 215*058561cbSjbeck for (i = 0; inout[i].qic_in != NULL; i++) 216*058561cbSjbeck { 217*058561cbSjbeck los = 0; 218*058561cbSjbeck obp = quote_unquote(inout[i].qic_in, NULL, los, 219*058561cbSjbeck inout[i].qic_exp); 220*058561cbSjbeck SM_TEST(obp != NULL); 221*058561cbSjbeck cmp = strcmp(inout[i].qic_out, obp); 222*058561cbSjbeck SM_TEST(inout[i].qic_exp == cmp); 223*058561cbSjbeck if (inout[i].qic_exp != cmp && !SmTestVerbose) 224*058561cbSjbeck { 225*058561cbSjbeck char *bp; 226*058561cbSjbeck 227*058561cbSjbeck bp = str2prt(obp); 228*058561cbSjbeck fprintf(stderr, "got: %s\n", bp); 229*058561cbSjbeck bp = str2prt(inout[i].qic_out); 230*058561cbSjbeck fprintf(stderr, "exp:%s\n", bp); 231*058561cbSjbeck fprintf(stderr, "cmp=%d\n", cmp); 232*058561cbSjbeck show_diff(inout[i].qic_in, inout[i].qic_out); 233*058561cbSjbeck } 234*058561cbSjbeck } 235*058561cbSjbeck 236*058561cbSjbeck return sm_test_end(); 237*058561cbSjbeck } 238