From: Paul Gofman pgofman@codeweavers.com
--- dlls/crypt32/str.c | 80 ++++++++++++---------------------------- dlls/crypt32/tests/str.c | 52 ++++++++++++++------------ 2 files changed, 53 insertions(+), 79 deletions(-)
diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index 5ddad1ff4e6..29882ab771e 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -29,70 +29,38 @@
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
-DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPSTR psz, DWORD csz) +DWORD WINAPI CertRDNValueToStrA(DWORD type, PCERT_RDN_VALUE_BLOB value_blob, + LPSTR value, DWORD value_len) { - DWORD ret = 0, len; + DWORD len, len_mb, ret; + LPWSTR valueW;
- TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz); + TRACE("(%ld, %p, %p, %ld)\n", type, value_blob, value, value_len);
- switch (dwValueType) - { - case CERT_RDN_ANY_TYPE: - break; - case CERT_RDN_NUMERIC_STRING: - case CERT_RDN_PRINTABLE_STRING: - case CERT_RDN_TELETEX_STRING: - case CERT_RDN_VIDEOTEX_STRING: - case CERT_RDN_IA5_STRING: - case CERT_RDN_GRAPHIC_STRING: - case CERT_RDN_VISIBLE_STRING: - case CERT_RDN_GENERAL_STRING: - len = pValue->cbData; - if (!psz || !csz) - ret = len; - else - { - DWORD chars = min(len, csz - 1); + len = CertRDNValueToStrW(type, value_blob, NULL, 0);
- if (chars) - { - memcpy(psz, pValue->pbData, chars); - ret += chars; - csz -= chars; - } - } - break; - case CERT_RDN_BMP_STRING: - case CERT_RDN_UTF8_STRING: - len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData, - pValue->cbData / sizeof(WCHAR), NULL, 0, NULL, NULL); - if (!psz || !csz) - ret = len; - else - { - DWORD chars = min(pValue->cbData / sizeof(WCHAR), csz - 1); + if (!(valueW = CryptMemAlloc(len * sizeof(*valueW)))) + { + ERR("No memory.\n"); + if (value && value_len) *value = 0; + return 1; + }
- if (chars) - { - ret = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData, - chars, psz, csz - 1, NULL, NULL); - csz -= ret; - } - } - break; - default: - FIXME("string type %ld unimplemented\n", dwValueType); + len = CertRDNValueToStrW(type, value_blob, valueW, len); + len_mb = WideCharToMultiByte(CP_ACP, 0, valueW, len, NULL, 0, NULL, NULL); + if (!value || !value_len) + { + CryptMemFree(valueW); + return len_mb; } - if (psz && csz) + + ret = WideCharToMultiByte(CP_ACP, 0, valueW, len, value, value_len, NULL, NULL); + if (ret < len_mb) { - *(psz + ret) = '\0'; - csz--; - ret++; + value[0] = 0; + ret = 1; } - else - ret++; - TRACE("returning %ld (%s)\n", ret, debugstr_a(psz)); + CryptMemFree(valueW); return ret; }
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c index 1cfdf8ee7b7..be95a796846 100644 --- a/dlls/crypt32/tests/str.c +++ b/dlls/crypt32/tests/str.c @@ -31,7 +31,6 @@ typedef struct _CertRDNAttrEncoding { DWORD dwValueType; CERT_RDN_VALUE_BLOB Value; LPCSTR str; - BOOL todo; } CertRDNAttrEncoding, *PCertRDNAttrEncoding;
typedef struct _CertRDNAttrEncodingW { @@ -133,33 +132,34 @@ static void test_CertRDNValueToStrA(void) { CertRDNAttrEncoding attrs[] = { { "2.5.4.6", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin1), bin1 }, "US", FALSE }, + { sizeof(bin1), bin1 }, "US" }, { "2.5.4.8", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin2), bin2 }, "Minnesota", FALSE }, + { sizeof(bin2), bin2 }, "Minnesota" }, { "2.5.4.7", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin3), bin3 }, "Minneapolis", FALSE }, + { sizeof(bin3), bin3 }, "Minneapolis" }, { "2.5.4.10", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin4), bin4 }, "CodeWeavers", FALSE }, + { sizeof(bin4), bin4 }, "CodeWeavers" }, { "2.5.4.11", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin5), bin5 }, "Wine Development", FALSE }, + { sizeof(bin5), bin5 }, "Wine Development" }, { "2.5.4.3", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin6), bin6 }, "localhost", FALSE }, + { sizeof(bin6), bin6 }, "localhost" }, { "1.2.840.113549.1.9.1", CERT_RDN_IA5_STRING, - { sizeof(bin7), bin7 }, "aric@codeweavers.com", FALSE }, + { sizeof(bin7), bin7 }, "aric@codeweavers.com" }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin9), bin9 }, "abc"def", FALSE }, + { sizeof(bin9), bin9 }, "abc"def" }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin10), bin10 }, "abc'def", FALSE }, + { sizeof(bin10), bin10 }, "abc'def" }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin11), bin11 }, "abc, def", FALSE }, + { sizeof(bin11), bin11 }, "abc, def" }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin12), bin12 }, " abc ", FALSE }, + { sizeof(bin12), bin12 }, " abc " }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin13), bin13 }, ""def"", FALSE }, + { sizeof(bin13), bin13 }, ""def"" }, { "0", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin14), bin14 }, "1;3", FALSE }, + { sizeof(bin14), bin14 }, "1;3" }, }; - DWORD i, ret; + unsigned int i; + DWORD ret, len; char buffer[2000]; CERT_RDN_VALUE_BLOB blob = { 0, NULL }; static const char ePKI[] = "ePKI Root Certification Authority"; @@ -177,15 +177,21 @@ static void test_CertRDNValueToStrA(void)
for (i = 0; i < ARRAY_SIZE(attrs); i++) { - ret = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, + len = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, buffer, sizeof(buffer)); - todo_wine_if (attrs[i].todo) - { - ok(ret == strlen(attrs[i].str) + 1, "Expected length %d, got %ld\n", - lstrlenA(attrs[i].str) + 1, ret); - ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n", - attrs[i].str, buffer); - } + ok(len == strlen(attrs[i].str) + 1, "Expected length %d, got %ld\n", + lstrlenA(attrs[i].str) + 1, ret); + ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n", + attrs[i].str, buffer); + memset(buffer, 0xcc, sizeof(buffer)); + ret = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, buffer, len - 1); + ok(ret == 1, "Unexpected ret %lu, expected 1, test %u.\n", ret, i); + ok(!buffer[0], "Unexpected value %#x, test %u.\n", buffer[0], i); + ok(!strncmp(buffer + 1, attrs[i].str + 1, len - 2), "Strings do not match, test %u.\n", i); + memset(buffer, 0xcc, sizeof(buffer)); + ret = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, buffer, 0); + ok(ret == len, "Unexpected ret %lu, expected %lu, test %u.\n", ret, len, i); + ok((unsigned char)buffer[0] == 0xcc, "Unexpected value %#x, test %u.\n", buffer[0], i); } blob.pbData = bin8; blob.cbData = sizeof(bin8);