From: Aaro Altonen Subject: [PATCH v3 1/2] crypt32/tests: Add tests for CryptStringToBinaryW() Message-Id: Date: Fri, 27 Mar 2020 08:27:31 +0200 Add tests for CRYPT_STRING_HEX format Signed-off-by: Aaro Altonen --- v2: - Fix one test case to be actually invalid as claimed - Change parameter type for one test - Add test cases where the upper byte of a wchar has invalid data (thanks Nikolay) v3: - remove string duplication from tests, it's not needed - add test case for non-null but empty string - remove duplicate test case --- dlls/crypt32/tests/base64.c | 187 ++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c index 7b9f4c1077..981a7a0065 100644 --- a/dlls/crypt32/tests/base64.c +++ b/dlls/crypt32/tests/base64.c @@ -783,8 +783,195 @@ static void testStringToBinaryA(void) } } +static void testStringToBinaryW(void) +{ + BOOL ret; + DWORD skip_ = 0; + DWORD flags = 0; + DWORD data_len; + BYTE out[256]; + BYTE expected[256]; + const WCHAR *input; + WCHAR winput1[] = { 0xff42, 0x0042, 0xff45, 0xff45, 0x0046, 0xff46, 0 }; + WCHAR winput2[] = { 0x4242, 0x4242, 0x4545, 0x4545, 0x4646, 0x4646, 0 }; + + /* invalid parameters -> 87 */ + SetLastError(0xdeadbeef); + ret = CryptStringToBinaryW(NULL, 0, 0, NULL, NULL, NULL, NULL); + ok(!ret, "Got %u, expected zero\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got %u, expected 87\n", GetLastError()); + + /* otherwise valid parameters but invalid data_len -> 87 */ + SetLastError(0xdeadbeef); + input = L"213c73796d6c696e6b3efffe"; + ret = CryptStringToBinaryW(input, 24, CRYPT_STRING_HEX, NULL, NULL, NULL, NULL); + ok(!ret, "Got %u, expected zero\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got %d, expected 87\n", GetLastError()); + + /* non-null but empty string -> 87 */ + SetLastError(0xdeadbeef); + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(L"", 0, CRYPT_STRING_HEX, NULL, &data_len, NULL, NULL); + ok(!ret, "Got %u, expected zero\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + broken(GetLastError() == ERROR_INVALID_DATA) /* xp */, "Got %d, expected 87\n", GetLastError()); + ok(data_len == 0xdeadbeef || broken(data_len == 0) /* xp */, "Got %d, expected deadbeef\n", data_len); + + /* uneven amount of data -> 13 */ + SetLastError(0xdeadbeef); + input = L"111"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 0, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* length is uneven -> 13 */ + SetLastError(0xdeadbeef); + input = L"1111"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 3, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* invalid 0x prefix -> 13 */ + SetLastError(0xdeadbeef); + input = L"0x213c73796d6c696e6b3efffe"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 0, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* invalid characters -> 13 */ + SetLastError(0xdeadbeef); + input = L"abchhh"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 0, CRYPT_STRING_HEX, NULL, &data_len, NULL, NULL); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* insufficient buffer -> 234 */ + SetLastError(0xdeadbeef); + data_len = 4; + memset(out, 0, sizeof(out)); + expected[0] = 0x21; + expected[1] = 0x3c; + expected[2] = 0x73; + expected[3] = 0x79; + input = L"213c73796d6c696e6b3efffe"; + ret = CryptStringToBinaryW(input, 24, CRYPT_STRING_HEX, out, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_MORE_DATA, "Got %d, expected 234\n", GetLastError()); + ok(data_len == 4, "Got %u, expected 4\n", data_len); + todo_wine ok(!memcmp(out, expected, 4), "Invalid output from CryptStringToBinaryW()!\n"); + + /* valid data */ + SetLastError(0xdeadbeef); + input = L"213c73796d6c696e6b3efffe"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 24, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %x, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 12, "Got %u, expected 12\n", data_len); + + /* valid data with white spaces */ + SetLastError(0xdeadbeef); + input = L"21 3c\t\t \r\n 73 796d6c \t69\t"; + data_len = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = CryptStringToBinaryW(input, 25, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %d, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 7, "Got %u, expected 7\n", data_len); + + /* valid data with white spaces but spacing breaks the valid data into invalid chunks */ + SetLastError(0xdeadbeef); + input = L"21 3 c"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 0, CRYPT_STRING_HEX, NULL, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* if "input" contains both valid and invalid data and "out" is valid, "out" shall contain all valid bytes + * until an invalid sequence is reached */ + SetLastError(0xdeadbeef); + data_len = 4; + memset(out, 0, sizeof(out)); + input = L"21 3 c ff"; + ret = CryptStringToBinaryW(input, 0, CRYPT_STRING_HEX, out, &data_len, &skip_, &flags); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + ok(data_len == 4, "Got %u, expected 4\n", data_len); + + /* valid data */ + SetLastError(0xdeadbeef); + expected[0] = 0x21; expected[1] = 0x3c; expected[2] = 0x73; + expected[3] = 0x79; expected[4] = 0x6d; expected[5] = 0x6c; + expected[6] = 0x69; expected[7] = 0x6e; expected[8] = 0x6b; + expected[9] = 0x3e; expected[10] = 0xff; expected[11] = 0xfe; + input = L"213c73796d6c696e6b3efffe"; + data_len = 256; + ret = CryptStringToBinaryW(input, 24, CRYPT_STRING_HEX, out, &data_len, &skip_, &flags); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %x, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 12, "Got %u, expected 12\n", data_len); + todo_wine ok(!memcmp(out, expected, 12), "Invalid output from CryptStringToBinaryW()!\n"); + + /* invalid data but length small enough that it's never detected */ + SetLastError(0xdeadbeef); + input = L"abcdefhhh"; + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(input, 4, CRYPT_STRING_HEX, NULL, &data_len, NULL, NULL); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %x, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 2, "Got %u, expected 2\n", data_len); + + /* invalid data but length small enough that it's never detected, with whitespaces */ + SetLastError(0xdeadbeef); + memset(out, 0, sizeof(out)); + input = L"\t\t21 fe f f f"; + data_len = 256; + ret = CryptStringToBinaryW(input, 5, CRYPT_STRING_HEX, out, &data_len, &skip_, &flags); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %x, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 1, "Got %u, expected 1\n", data_len); + + SetLastError(0xdeadbeef); + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(winput1, 6, CRYPT_STRING_HEX, NULL, &data_len, NULL, NULL); + todo_wine ok(ret || broken(!ret), "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == 122), + "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 3 || broken(data_len == 0xdeadbeef), "Got %u, expected 3\n", data_len); + + SetLastError(0xdeadbeef); + data_len = 0xdeadbeef; + ret = CryptStringToBinaryW(winput2, 6, CRYPT_STRING_HEX, NULL, &data_len, NULL, NULL); + ok(!ret, "Got %u, expected zero\n", ret); + todo_wine ok(GetLastError() == ERROR_INVALID_DATA, "Got %d, expected 13\n", GetLastError()); + todo_wine ok(data_len == 0, "Got %u, expected 0\n", data_len); + + /* valid data but parse only the first 6 bytes (12 chars) */ + SetLastError(0xdeadbeef); + memset(out, 0, sizeof(out)); + expected[0] = 0x21; expected[1] = 0x3c; expected[2] = 0x73; + expected[3] = 0x79; expected[4] = 0x6d; expected[5] = 0x6c; + input = L"213c73796d6c696e6b3efffe"; + data_len = 256; + ret = CryptStringToBinaryW(input, 12, CRYPT_STRING_HEX, out, &data_len, &skip_, &flags); + todo_wine ok(ret, "Got %u, expected one\n", ret); + todo_wine ok(GetLastError() == 0xdeadbeef, "Got %x, expected 0xdeadbeef\n", GetLastError()); + todo_wine ok(data_len == 6, "Got %u, expected 6\n", data_len); + todo_wine ok(!memcmp(out, expected, 6), "Invalid output from CryptStringToBinaryW()!\n"); +} + START_TEST(base64) { test_CryptBinaryToString(); testStringToBinaryA(); + testStringToBinaryW(); } -- 2.25.2