kernel32/tests: Add some tests for Idn functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-02-28 15:25:22 +01:00
parent fe6220dba7
commit 5d270e592d
1 changed files with 199 additions and 207 deletions

View File

@ -4416,100 +4416,44 @@ static void test_GetStringTypeW(void)
static void test_IdnToNameprepUnicode(void)
{
struct {
DWORD in_len;
const WCHAR in[64];
int in_len;
const WCHAR in[80];
DWORD flags;
DWORD ret;
DWORD broken_ret;
const WCHAR out[64];
DWORD flags;
DWORD err;
const WCHAR out[80];
NTSTATUS status;
NTSTATUS broken_status;
} test_data[] = {
{
5, {'t','e','s','t',0},
5, 5, {'t','e','s','t',0},
0, 0xdeadbeef
},
{
3, {'a',0xe111,'b'},
0, 0, {0},
0, ERROR_INVALID_NAME
},
{
4, {'t',0,'e',0},
0, 0, {0},
0, ERROR_INVALID_NAME
},
{
1, {'T',0},
1, 1, {'T',0},
0, 0xdeadbeef
},
{
1, {0},
0, 0, {0},
0, ERROR_INVALID_NAME
},
{
6, {' ','-','/','[',']',0},
6, 6, {' ','-','/','[',']',0},
0, 0xdeadbeef
},
{
3, {'a','-','a'},
3, 3, {'a','-','a'},
IDN_USE_STD3_ASCII_RULES, 0xdeadbeef
},
{
3, {'a','a','-'},
0, 0, {0},
IDN_USE_STD3_ASCII_RULES, ERROR_INVALID_NAME
},
{
10, {'T',0xdf,0x130,0x143,0x37a,0x6a,0x30c,' ',0xaa,0},
12, 12, {'t','s','s','i',0x307,0x144,' ',0x3b9,0x1f0,' ','a',0},
0, 0xdeadbeef
},
{
11, {'t',0xad,0x34f,0x1806,0x180b,0x180c,0x180d,0x200b,0x200c,0x200d,0},
2, 0, {'t',0},
0, 0xdeadbeef
},
{
2, {0x3b0, 0},
2, 2, {0x3b0, 0},
0, 0xdeadbeef,
},
{
2, {0x221, 0},
0, 2, {0},
0, ERROR_NO_UNICODE_TRANSLATION
},
{
2, {0x221, 0},
2, 2, {0x221, 0},
IDN_ALLOW_UNASSIGNED, 0xdeadbeef
},
{
5, {'a','.','.','a',0},
0, 0, {0},
0, ERROR_INVALID_NAME
},
{
3, {'a','.',0},
3, 3, {'a','.',0},
0, 0xdeadbeef
},
/* 0 */
{ 5, L"test", 0, 5, 5, L"test" },
{ 3, L"a\xe111z", 0, 0, 0, L"a\xe111z", 0, STATUS_NO_UNICODE_TRANSLATION },
{ 4, L"t\0e", 0, 0, 0, {0}, STATUS_NO_UNICODE_TRANSLATION, STATUS_NO_UNICODE_TRANSLATION },
{ 1, L"T", 0, 1, 1, L"t" },
{ 1, {0}, 0, 0 },
/* 5 */
{ 6, L" -/[]", 0, 6, 6, L" -/[]" },
{ 3, L"a-a", IDN_USE_STD3_ASCII_RULES, 3, 3, L"a-a" },
{ 3, L"aa-", IDN_USE_STD3_ASCII_RULES, 0, 0, L"aa-" },
{ -1, L"T\xdf\x130\x143\x37a\x6a\x30c \xaa", 0, 12, 12, L"tssi\x307\x144 \x3b9\x1f0 a" },
{ 11, L"t\xad\x34f\x1806\x180b\x180c\x180d\x200b\x200c\x200d", 0, 2, 0, L"t",
STATUS_NO_UNICODE_TRANSLATION },
/* 10 */
{ 2, {0x3b0}, 0, 2, 2, {0x3b0} },
{ 2, {0x380}, 0, 0, 2, {0x380} },
{ 2, {0x380}, IDN_ALLOW_UNASSIGNED, 2, 2, {0x380} },
{ 5, L"a..a", 0, 0, 0, L"a..a" },
{ 3, L"a.", 0, 3, 3, L"a." },
/* 15 */
{ 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0,
63, 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" },
{ 64, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0,
0, 0, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" },
};
WCHAR buf[1024];
DWORD i, ret, err;
if (!pIdnToNameprepUnicode)
{
win_skip("IdnToNameprepUnicode is not available\n");
return;
}
ret = pIdnToNameprepUnicode(0, test_data[0].in,
test_data[0].in_len, NULL, 0);
ok(ret == test_data[0].ret, "ret = %d\n", ret);
@ -4519,7 +4463,7 @@ static void test_IdnToNameprepUnicode(void)
test_data[1].in_len, NULL, 0);
err = GetLastError();
ok(ret == test_data[1].ret, "ret = %d\n", ret);
ok(err == test_data[1].err, "err = %d\n", err);
ok(err == ret ? 0xdeadbeef : ERROR_INVALID_NAME, "err = %d\n", err);
SetLastError(0xdeadbeef);
ret = pIdnToNameprepUnicode(0, test_data[0].in, -1, buf, ARRAY_SIZE(buf));
@ -4559,167 +4503,217 @@ static void test_IdnToNameprepUnicode(void)
for (i=0; i<ARRAY_SIZE(test_data); i++)
{
SetLastError(0xdeadbeef);
memset( buf, 0xcc, sizeof(buf) );
ret = pIdnToNameprepUnicode(test_data[i].flags, test_data[i].in, test_data[i].in_len,
buf, ARRAY_SIZE(buf));
err = GetLastError();
ok(ret == test_data[i].ret || broken(ret == test_data[i].broken_ret), "%d: ret = %d\n", i, ret);
if(ret != test_data[i].ret)
continue;
ok(err == test_data[i].err, "%d) err = %d\n", i, err);
ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
"%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
if (ret == test_data[i].ret)
{
ok(err == ret ? 0xdeadbeef : ERROR_INVALID_NAME, "%d: err = %d\n", i, err);
ok(!wcsnicmp(test_data[i].out, buf, ret), "%d: buf = %s\n", i, wine_dbgstr_wn(buf, ret));
}
if (pRtlNormalizeString)
{
NTSTATUS status;
int len = ARRAY_SIZE(buf);
memset( buf, 0xcc, sizeof(buf) );
status = pRtlNormalizeString( 13, test_data[i].in, test_data[i].in_len, buf, &len );
todo_wine_if (!test_data[i].status && (test_data[i].in_len == -1 || !test_data[i].in[test_data[i].in_len - 1]))
ok( status == test_data[i].status || broken(status == test_data[i].broken_status),
"%d: failed %x\n", i, status );
if (!status) ok( !wcsncmp(test_data[i].out, buf, len), "%d: buf = %s\n", i, wine_dbgstr_wn(buf, len));
}
}
}
static void test_IdnToAscii(void)
{
struct {
DWORD in_len;
const WCHAR in[64];
DWORD ret;
const WCHAR out[64];
int in_len;
const WCHAR in[80];
DWORD flags;
DWORD err;
DWORD ret;
DWORD broken_ret;
const WCHAR out[80];
} test_data[] = {
{
5, {'T','e','s','t',0},
5, {'T','e','s','t',0},
0, 0xdeadbeef
},
{
5, {'T','e',0x017c,'s','t',0},
12, {'x','n','-','-','t','e','s','t','-','c','b','b',0},
0, 0xdeadbeef
},
{
12, {'t','e',0x0105,'s','t','.','t','e',0x017c,'s','t',0},
26, {'x','n','-','-','t','e','s','t','-','c','t','a','.','x','n','-','-','t','e','s','t','-','c','b','b',0},
0, 0xdeadbeef
},
{
3, {0x0105,'.',0},
9, {'x','n','-','-','2','d','a','.',0},
0, 0xdeadbeef
},
{
10, {'h','t','t','p',':','/','/','t',0x0106,0},
17, {'x','n','-','-','h','t','t','p',':','/','/','t','-','7','8','a',0},
0, 0xdeadbeef
},
{
10, {0x4e3a,0x8bf4,0x4e0d,0x4ed6,0x5011,0x10d,0x11b,0x305c,0x306a,0},
35, {'x','n','-','-','b','e','a','2','a','1','6','3','1','a','v','b','a',
'v','4','4','t','y','h','a','3','2','b','9','1','e','g','s','2','t',0},
0, 0xdeadbeef
},
{
2, {0x221,0},
8, {'x','n','-','-','6','l','a',0},
IDN_ALLOW_UNASSIGNED, 0xdeadbeef
},
/* 0 */
{ 5, L"Test", 0, 5, 5, L"Test" },
{ 5, L"Te\x017cst", 0, 12, 12, L"xn--test-cbb" },
{ 12, L"te\x0105st.te\x017cst", 0, 26, 26, L"xn--test-cta.xn--test-cbb" },
{ 3, {0x0105,'.',0}, 0, 9, 9, L"xn--2da." },
{ 10, L"http://t\x106", 0, 17, 17, L"xn--http://t-78a" },
/* 5 */
{ -1, L"\x4e3a\x8bf4\x4e0d\x4ed6\x5011\x10d\x11b\x305c\x306a", 0,
35, 35, L"xn--bea2a1631avbav44tyha32b91egs2t" },
{ 2, L"\x380", IDN_ALLOW_UNASSIGNED, 8, 8, L"xn--7va" },
{ 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0,
63, 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" },
{ 64, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 0 },
{ -1, L"\xe4z123456789012345678901234567890123456789012345678901234", 0,
64, 64, L"xn--z123456789012345678901234567890123456789012345678901234-9te" },
/* 10 */
{ -1, L"\xd803\xde78\x46b5-\xa861.\x2e87", 0, 28, 0, L"xn----bm3an932a1l5d.xn--xvj" },
{ -1, L"\x06ef\x06ef", 0, 9, 0, L"xn--cmba" },
{ -1, L"-\x07e1\xff61\x2184", 0, 18, 0, L"xn----8cd.xn--r5g" },
};
WCHAR buf[1024];
DWORD i, ret, err;
if (!pIdnToAscii)
{
win_skip("IdnToAscii is not available\n");
return;
}
for (i=0; i<ARRAY_SIZE(test_data); i++)
{
SetLastError(0xdeadbeef);
ret = pIdnToAscii(test_data[i].flags, test_data[i].in,
test_data[i].in_len, buf, sizeof(buf));
ret = pIdnToAscii(test_data[i].flags, test_data[i].in, test_data[i].in_len, buf, ARRAY_SIZE(buf));
err = GetLastError();
ok(ret == test_data[i].ret, "%d) ret = %d\n", i, ret);
ok(err == test_data[i].err, "%d) err = %d\n", i, err);
ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
"%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
todo_wine_if (i > 9)
ok(ret == test_data[i].ret || broken(ret == test_data[i].broken_ret), "%d: ret = %d\n", i, ret);
ok(err == ret ? 0xdeadbeef : ERROR_INVALID_NAME, "%d: err = %d\n", i, err);
ok(!wcsncmp(test_data[i].out, buf, ret), "%d: buf = %s\n", i, wine_dbgstr_wn(buf, ret));
}
}
static void test_IdnToUnicode(void)
{
struct {
DWORD in_len;
const WCHAR in[64];
DWORD ret;
const WCHAR out[64];
int in_len;
const WCHAR in[80];
DWORD flags;
DWORD err;
DWORD ret;
DWORD broken_ret;
const WCHAR out[80];
} test_data[] = {
{
5, {'T','e','s','.',0},
5, {'T','e','s','.',0},
0, 0xdeadbeef
},
{
2, {0x105,0},
0, {0},
0, ERROR_INVALID_NAME
},
{
33, {'x','n','-','-','4','d','b','c','a','g','d','a','h','y','m','b',
'x','e','k','h','e','h','6','e','0','a','7','f','e','i','0','b',0},
23, {0x05dc,0x05de,0x05d4,0x05d4,0x05dd,0x05e4,0x05e9,0x05d5,0x05d8,
0x05dc,0x05d0,0x05de,0x05d3,0x05d1,0x05e8,0x05d9,0x05dd,0x05e2,
0x05d1,0x05e8,0x05d9,0x05ea,0},
0, 0xdeadbeef
},
{
34, {'t','e','s','t','.','x','n','-','-','k','d','a','9','a','g','5','e',
'9','j','n','f','s','j','.','x','n','-','-','p','d','-','f','n','a'},
16, {'t','e','s','t','.',0x0105,0x0119,0x015b,0x0107,
0x0142,0x00f3,0x017c,'.','p',0x0119,'d'},
0, 0xdeadbeef
},
{
64, {'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'},
0, {0},
0, ERROR_INVALID_NAME
},
{
8, {'x','n','-','-','6','l','a',0},
2, {0x221,0},
IDN_ALLOW_UNASSIGNED, 0xdeadbeef
},
/* 0 */
{ 5, L"Tes.", 0, 5, 5, L"Tes." },
{ 2, L"\x105", 0, 0 },
{ 33, L"xn--4dbcagdahymbxekheh6e0a7fei0b", 0,
23, 23, L"\x05dc\x05de\x05d4\x05d4\x05dd\x05e4\x05e9\x05d5\x05d8\x05dc\x05d0\x05de\x05d3\x05d1\x05e8\x05d9\x05dd\x05e2\x05d1\x05e8\x05d9\x05ea" },
{ 34, L"test.xn--kda9ag5e9jnfsj.xn--pz-fna", 0,
16, 16, L"test.\x0105\x0119\x015b\x0107\x0142\x00f3\x017c.p\x0119z" },
{ 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0,
63, 63, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" },
/* 5 */
{ 64, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 0 },
{ 8, L"xn--7va", IDN_ALLOW_UNASSIGNED, 2, 2, L"\x380" },
{ -1, L"xn----bm3an932a1l5d.xn--xvj", 0, 8, 0, L"\xd803\xde78\x46b5-\xa861.\x2e87" },
{ -1, L"xn--z123456789012345678901234567890123456789012345678901234-9te", 0,
57, 57, L"\xe4z123456789012345678901234567890123456789012345678901234" },
{ -1, L"foo.bar", 0, 8, 8, L"foo.bar" },
};
WCHAR buf[1024];
DWORD i, ret, err;
if (!pIdnToUnicode)
for (i=0; i<ARRAY_SIZE(test_data); i++)
{
win_skip("IdnToUnicode is not available\n");
ret = pIdnToUnicode(test_data[i].flags, test_data[i].in, test_data[i].in_len, NULL, 0);
todo_wine_if (i > 6)
ok(ret == test_data[i].ret || broken(ret == test_data[i].broken_ret), "%d: ret = %d\n", i, ret);
SetLastError(0xdeadbeef);
ret = pIdnToUnicode(test_data[i].flags, test_data[i].in, test_data[i].in_len, buf, ARRAY_SIZE(buf));
err = GetLastError();
todo_wine_if (i > 6)
ok(ret == test_data[i].ret || broken(ret == test_data[i].broken_ret), "%d: ret = %d\n", i, ret);
ok(err == ret ? 0xdeadbeef : ERROR_INVALID_NAME, "%d: err = %d\n", i, err);
ok(!wcsncmp(test_data[i].out, buf, ret), "%d: buf = %s\n", i, wine_dbgstr_wn(buf, ret));
}
}
static BOOL is_idn_error( const WCHAR *str )
{
WCHAR *p, err[256];
lstrcpyW( err, str );
for (p = wcstok( err, L" []" ); p; p = wcstok( NULL, L" []" ) )
{
if (*p == 'B' || !wcscmp( p, L"V8" )) continue; /* BiDi */
if (!wcscmp( p, L"V2" ) || !wcscmp( p, L"V3" )) continue; /* CheckHyphens */
if (!wcscmp( p, L"V7" )) continue; /* CheckJoiners */
return TRUE;
}
return FALSE;
}
static void test_Idn(void)
{
FILE *f;
if (!pIdnToAscii || !pIdnToUnicode || !pIdnToNameprepUnicode)
{
win_skip("Idn support is not available\n");
return;
}
for (i=0; i<ARRAY_SIZE(test_data); i++)
{
ret = pIdnToUnicode(test_data[i].flags, test_data[i].in,
test_data[i].in_len, NULL, 0);
ok(ret == test_data[i].ret, "%d) ret = %d\n", i, ret);
test_IdnToNameprepUnicode();
test_IdnToAscii();
test_IdnToUnicode();
SetLastError(0xdeadbeef);
ret = pIdnToUnicode(test_data[i].flags, test_data[i].in,
test_data[i].in_len, buf, sizeof(buf));
err = GetLastError();
ok(ret == test_data[i].ret, "%d) ret = %d\n", i, ret);
ok(err == test_data[i].err, "%d) err = %d\n", i, err);
ok(!memcmp(test_data[i].out, buf, ret*sizeof(WCHAR)),
"%d) buf = %s\n", i, wine_dbgstr_wn(buf, ret));
/* optionally run the full test file from Unicode.org
* available at https://www.unicode.org/Public/idna/latest/IdnaTestV2.txt
*/
if ((f = fopen( "IdnaTestV2.txt", "r" )))
{
char *p, *end, buffer[2048];
WCHAR columns[7][256], dst[256], *expect, *error;
int i, ret, line = 0;
while (fgets( buffer, sizeof(buffer), f ))
{
line++;
if ((p = strchr( buffer, '#' ))) *p = 0;
if (!(p = strtok( buffer, ";" ))) continue;
for (i = 0; i < 7 && p; i++)
{
while (*p == ' ') p++;
for (end = p + strlen(p); end > p; end--) if (end[-1] != ' ') break;
*end = 0;
MultiByteToWideChar( CP_UTF8, 0, p, -1, columns[i], 256 );
p = strtok( NULL, ";" );
}
if (i < 7) continue;
expect = columns[5];
if (!*expect) expect = columns[3];
if (!*expect) expect = columns[1];
if (!*expect) expect = columns[0];
error = columns[6];
if (!*error) error = columns[4];
if (!*error) error = columns[2];
SetLastError( 0xdeadbeef );
memset( dst, 0xcc, sizeof(dst) );
ret = pIdnToAscii( 0, columns[0], -1, dst, ARRAY_SIZE(dst) );
if (!is_idn_error( error ))
{
ok( ret, "line %u: toAscii failed for %s\n", line, debugstr_w(columns[0]) );
if (ret) ok( !wcscmp( dst, expect ), "line %u: got %s expected %s\n",
line, debugstr_w(dst), debugstr_w(expect) );
}
expect = columns[1];
if (!*expect) expect = columns[0];
error = columns[2];
SetLastError( 0xdeadbeef );
memset( dst, 0xcc, sizeof(dst) );
ret = pIdnToUnicode( 0, columns[0], -1, dst, ARRAY_SIZE(dst) );
for (i = 0; columns[0][i]; i++) if (columns[0][i] > 0x7f) break;
if (columns[0][i])
{
ok( !ret, "line %u: didn't fail for unicode chars in %s\n", line, debugstr_w(columns[0]) );
}
else if (!is_idn_error( error ))
{
ok( ret, "line %u: toUnicode failed for %s\n", line, debugstr_w(columns[0]) );
if (ret) ok( !wcscmp( dst, expect ), "line %u: got %s expected %s\n",
line, debugstr_w(dst), debugstr_w(expect) );
}
}
fclose( f );
}
}
static void test_GetLocaleInfoEx(void)
{
static const WCHAR enW[] = {'e','n',0};
@ -6618,9 +6612,7 @@ START_TEST(locale)
test_EnumUILanguageA();
test_GetCPInfo();
test_GetStringTypeW();
test_IdnToNameprepUnicode();
test_IdnToAscii();
test_IdnToUnicode();
test_Idn();
test_IsValidLocaleName();
test_CompareStringOrdinal();
test_GetGeoInfo();