Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/crypt32/base64.c | 98 +++++++++++++++++-------------- dlls/crypt32/tests/base64.c | 111 ++++++++++++++++++++++++++---------- 2 files changed, 136 insertions(+), 73 deletions(-)
diff --git a/dlls/crypt32/base64.c b/dlls/crypt32/base64.c index bc30779098..e25e4c10ff 100644 --- a/dlls/crypt32/base64.c +++ b/dlls/crypt32/base64.c @@ -215,36 +215,41 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, charsNeeded += strlen(header) + strlen(sep); if (trailer) charsNeeded += strlen(trailer) + strlen(sep); - if (charsNeeded <= *pcchString) - { - LPSTR ptr = pszString; - DWORD size = charsNeeded;
- if (header) + if (pszString) + { + if (charsNeeded <= *pcchString) { - strcpy(ptr, header); - ptr += strlen(ptr); - strcpy(ptr, sep); - ptr += strlen(sep); + LPSTR ptr = pszString; + DWORD size = charsNeeded; + + if (header) + { + strcpy(ptr, header); + ptr += strlen(ptr); + strcpy(ptr, sep); + ptr += strlen(sep); + } + encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); + ptr += size - 1; + if (trailer) + { + strcpy(ptr, trailer); + ptr += strlen(ptr); + strcpy(ptr, sep); + } + *pcchString = charsNeeded - 1; } - encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); - ptr += size - 1; - if (trailer) + else { - strcpy(ptr, trailer); - ptr += strlen(ptr); - strcpy(ptr, sep); + *pcchString = charsNeeded; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + ret = FALSE; } - *pcchString = charsNeeded - 1; - } - else if (pszString) - { - *pcchString = charsNeeded; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - ret = FALSE; } else *pcchString = charsNeeded; + return ret; }
@@ -409,36 +414,41 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, charsNeeded += strlenW(header) + strlenW(sep); if (trailer) charsNeeded += strlenW(trailer) + strlenW(sep); - if (charsNeeded <= *pcchString) - { - LPWSTR ptr = pszString; - DWORD size = charsNeeded;
- if (header) + if (pszString) + { + if (charsNeeded <= *pcchString) { - strcpyW(ptr, header); - ptr += strlenW(ptr); - strcpyW(ptr, sep); - ptr += strlenW(sep); + LPWSTR ptr = pszString; + DWORD size = charsNeeded; + + if (header) + { + strcpyW(ptr, header); + ptr += strlenW(ptr); + strcpyW(ptr, sep); + ptr += strlenW(sep); + } + encodeBase64W(pbBinary, cbBinary, sep, ptr, &size); + ptr += size - 1; + if (trailer) + { + strcpyW(ptr, trailer); + ptr += strlenW(ptr); + strcpyW(ptr, sep); + } + *pcchString = charsNeeded - 1; } - encodeBase64W(pbBinary, cbBinary, sep, ptr, &size); - ptr += size - 1; - if (trailer) + else { - strcpyW(ptr, trailer); - ptr += strlenW(ptr); - strcpyW(ptr, sep); + *pcchString = charsNeeded; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + ret = FALSE; } - *pcchString = charsNeeded - 1; - } - else if (pszString) - { - *pcchString = charsNeeded; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - ret = FALSE; } else *pcchString = charsNeeded; + return ret; }
diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c index 7bc1ec7d0e..2249e1bf5a 100644 --- a/dlls/crypt32/tests/base64.c +++ b/dlls/crypt32/tests/base64.c @@ -96,60 +96,113 @@ static WCHAR *strdupAtoW(const char *str) static void encodeAndCompareBase64_A(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const char *expected, const char *header, const char *trailer) { - DWORD strLen = 0; + DWORD strLen, strLen2; + const char *ptr; LPSTR str = NULL; BOOL ret;
+ strLen = 0; ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen); ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); - str = HeapAlloc(GetProcessHeap(), 0, strLen); - if (str) - { - DWORD strLen2 = strLen; - LPCSTR ptr = str; + ok(strLen > 0, "Unexpected required length.\n");
- ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, str, - &strLen2); - ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); - ok(strLen2 == strLen - 1, "Expected length %d, got %d\n", - strLen - 1, strLen); - if (header) - { - ok(!strncmp(header, ptr, strlen(header)), - "Expected header %s, got %s\n", header, ptr); - ptr += strlen(header); - } - ok(!strncmp(expected, ptr, strlen(expected)), - "Expected %s, got %s\n", expected, ptr); - ptr += strlen(expected); - if (trailer) - ok(!strncmp(trailer, ptr, strlen(trailer)), - "Expected trailer %s, got %s\n", trailer, ptr); - HeapFree(GetProcessHeap(), 0, str); + strLen2 = strLen; + ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen2); + ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); + ok(strLen == strLen2, "Unexpected required length.\n"); + + strLen2 = strLen - 1; + ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen2); + ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); + ok(strLen == strLen2, "Unexpected required length.\n"); + + str = heap_alloc(strLen); + + /* Partially filled output buffer. */ + strLen2 = strLen - 1; + str[0] = 0x12; + ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, str, &strLen2); +todo_wine + ok((!ret && GetLastError() == ERROR_MORE_DATA) || broken(ret) /* XP */, "CryptBinaryToStringA failed %d, error %d.\n", + ret, GetLastError()); + ok(strLen2 == strLen || broken(strLen2 == strLen - 1), "Expected length %d, got %d\n", strLen - 1, strLen); +todo_wine { + if (header) + ok(str[0] == header[0], "Unexpected buffer contents %#x.\n", str[0]); + else + ok(str[0] == expected[0], "Unexpected buffer contents %#x.\n", str[0]); +} + strLen2 = strLen; + ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, str, &strLen2); + ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); + ok(strLen2 == strLen - 1, "Expected length %d, got %d\n", strLen - 1, strLen); + + ptr = str; + if (header) + { + ok(!strncmp(header, ptr, strlen(header)), "Expected header %s, got %s\n", header, ptr); + ptr += strlen(header); } + ok(!strncmp(expected, ptr, strlen(expected)), "Expected %s, got %s\n", expected, ptr); + ptr += strlen(expected); + if (trailer) + ok(!strncmp(trailer, ptr, strlen(trailer)), "Expected trailer %s, got %s\n", trailer, ptr); + + heap_free(str); }
static void encode_compare_base64_W(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const WCHAR *expected, const char *header, const char *trailer) { WCHAR *headerW, *trailerW; - DWORD strLen = 0, strLen2; + DWORD strLen, strLen2; + WCHAR *strW = NULL; const WCHAR *ptr; - WCHAR *strW; BOOL ret;
+ strLen = 0; ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, NULL, &strLen); ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); + ok(strLen > 0, "Unexpected required length.\n");
+ /* Same call with non-zero length value. */ strLen2 = strLen; - strW = heap_alloc(strLen * sizeof(WCHAR)); - ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, strW, &strLen2); + ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, NULL, &strLen2); ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); - ok(strLen2 == strLen - 1, "Expected length %d, got %d\n", strLen - 1, strLen); + ok(strLen == strLen2, "Unexpected required length.\n"); + + strLen2 = strLen - 1; + ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, NULL, &strLen2); + ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); + ok(strLen == strLen2, "Unexpected required length.\n"); + + strLen2 = strLen - 1; + ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, NULL, &strLen2); + ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); + ok(strLen == strLen2, "Unexpected required length.\n"); + + strW = heap_alloc(strLen * sizeof(WCHAR));
headerW = strdupAtoW(header); trailerW = strdupAtoW(trailer);
+ strLen2 = strLen - 1; + strW[0] = 0x1234; + ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, strW, &strLen2); +todo_wine + ok((!ret && GetLastError() == ERROR_MORE_DATA) || broken(ret) /* XP */, "CryptBinaryToStringW failed, %d, error %d\n", + ret, GetLastError()); + if (headerW) + ok(strW[0] == 0x1234, "Unexpected buffer contents %#x.\n", strW[0]); + else + ok(strW[0] == 0x1234 || broken(strW[0] != 0x1234) /* XP */, "Unexpected buffer contents %#x.\n", strW[0]); + + strLen2 = strLen; + ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, strW, &strLen2); + ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); + + ok(strLen2 == strLen - 1, "Expected length %d, got %d\n", strLen - 1, strLen); + ptr = strW; if (headerW) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/crypt32/base64.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/dlls/crypt32/base64.c b/dlls/crypt32/base64.c index e25e4c10ff..5caab97b17 100644 --- a/dlls/crypt32/base64.c +++ b/dlls/crypt32/base64.c @@ -77,23 +77,20 @@ static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary, { BOOL ret = TRUE;
- if (*pcchString < cbBinary) + if (pszString) { - if (!pszString) - *pcchString = cbBinary; - else + if (*pcchString < cbBinary) { SetLastError(ERROR_INSUFFICIENT_BUFFER); - *pcchString = cbBinary; ret = FALSE; } - } - else - { - if (cbBinary) + else if (cbBinary) memcpy(pszString, pbBinary, cbBinary); - *pcchString = cbBinary; } + else + + *pcchString = cbBinary; + return ret; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/crypt32/base64.c | 10 ++++++---- dlls/crypt32/tests/base64.c | 26 ++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/dlls/crypt32/base64.c b/dlls/crypt32/base64.c index 5caab97b17..ac288b7c5e 100644 --- a/dlls/crypt32/base64.c +++ b/dlls/crypt32/base64.c @@ -104,8 +104,9 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, LPSTR ptr;
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); - needed = bytes + pad_bytes + 1; - needed += (needed / 64 + 1) * strlen(sep); + needed = bytes + pad_bytes; + needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlen(sep); + needed++;
if (needed > *out_len) { @@ -303,8 +304,9 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, LPWSTR ptr;
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); - needed = bytes + pad_bytes + 1; - needed += (needed / 64 + 1) * strlenW(sep); + needed = bytes + pad_bytes; + needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlenW(sep); + needed++;
if (needed > *out_len) { diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c index 2249e1bf5a..e6adc7ab38 100644 --- a/dlls/crypt32/tests/base64.c +++ b/dlls/crypt32/tests/base64.c @@ -55,6 +55,8 @@ static const BYTE toEncode4[] = "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; +static const BYTE toEncode5[] = + "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHI";
static const struct BinTests tests[] = { { toEncode1, sizeof(toEncode1), "AA==\r\n", }, @@ -66,6 +68,8 @@ static const struct BinTests tests[] = { "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\r\n" "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\r\n" "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\r\n" }, + { toEncode5, sizeof(toEncode5), + "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\r\n" }, };
static const struct BinTests testsNoCR[] = { @@ -78,6 +82,8 @@ static const struct BinTests testsNoCR[] = { "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\n" "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\n" "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\n" }, + { toEncode5, sizeof(toEncode5), + "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\n" }, };
static WCHAR *strdupAtoW(const char *str) @@ -96,15 +102,21 @@ static WCHAR *strdupAtoW(const char *str) static void encodeAndCompareBase64_A(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const char *expected, const char *header, const char *trailer) { - DWORD strLen, strLen2; + DWORD strLen, strLen2, required; const char *ptr; LPSTR str = NULL; BOOL ret;
+ required = strlen(expected) + 1; + if (header) + required += strlen(header); + if (trailer) + required += strlen(trailer); + strLen = 0; ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen); ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); - ok(strLen > 0, "Unexpected required length.\n"); + ok(strLen == required, "Unexpected required length %u, expected %u.\n", required, strLen);
strLen2 = strLen; ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen2); @@ -154,16 +166,22 @@ todo_wine { static void encode_compare_base64_W(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const WCHAR *expected, const char *header, const char *trailer) { - WCHAR *headerW, *trailerW; + WCHAR *headerW, *trailerW, required; DWORD strLen, strLen2; WCHAR *strW = NULL; const WCHAR *ptr; BOOL ret;
+ required = lstrlenW(expected) + 1; + if (header) + required += strlen(header); + if (trailer) + required += strlen(trailer); + strLen = 0; ret = CryptBinaryToStringW(toEncode, toEncodeLen, format, NULL, &strLen); ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError()); - ok(strLen > 0, "Unexpected required length.\n"); + ok(strLen == required, "Unexpected required length %u, expected %u.\n", strLen, required);
/* Same call with non-zero length value. */ strLen2 = strLen;