DF-5755 / difftest.c
/* DF-5755/DF-5756 — userland iconv(3) differential. * * The kernel's libiconv UCS converter accepts/rejects the same byte * sequences differently from the base-system userland iconv(3). This tool * prints, for each case, what userland does — the contrast baseline for the * kernel witness module and msdosfs runs. */ #include <err.h> #include <iconv.h> #include <stdio.h> #include <string.h> #include <errno.h> struct tc { const char *tag; const char *to, *from; const char *in; size_t inlen; }; static struct tc cases[] = { { "u8_overlong_slash_C0AF", "UTF-16BE", "UTF-8", "\xC0\xAF", 2 }, { "u8_overlong3_slash_E080AF","UTF-16BE","UTF-8", "\xE0\x80\xAF", 3 }, { "u8_overlong4_F08FBFBF", "UTF-16BE", "UTF-8", "\xF0\x8F\xBF\xBF", 4 }, { "u8_valid_slash", "UTF-16BE", "UTF-8", "\x2F", 1 }, { "u16_lone_low_DC00", "UTF-8", "UTF-16BE","\xDC\x00", 2 }, { "u16_lone_high_D83D", "UTF-8", "UTF-16BE","\xD8\x3D", 2 }, { "u16_valid_pair_D83DDE48", "UTF-8", "UTF-16BE","\xD8\x3D\xDE\x48", 4 }, { NULL, NULL, NULL, NULL, 0 } }; int main(void) { int i; for (i = 0; cases[i].tag; i++) { iconv_t cd; char out[16]; const char *src; char *dst; size_t il, ol, k; errno = 0; cd = iconv_open(cases[i].to, cases[i].from); if (cd == (iconv_t)-1) { printf("%-28s : iconv_open(%s,%s) FAILED: %s\n", cases[i].tag, cases[i].to, cases[i].from, strerror(errno)); continue; } memset(out, 0xAA, sizeof(out)); src = cases[i].in; dst = out; il = cases[i].inlen; ol = sizeof(out); errno = 0; iconv(cd, &src, &il, &dst, &ol); printf("%-28s : ret-errno=%s consumed=%zu out=", cases[i].tag, errno ? strerror(errno) : "0(OK)", cases[i].inlen - il); for (k = 0; k < sizeof(out) - ol; k++) printf("%02x ", (unsigned char)out[k]); printf("\n"); iconv_close(cd); } return 0; } |