From: Paul Gofman pgofman@codeweavers.com
--- dlls/crypt32/str.c | 61 ++++++++++++++++++++-------------------- dlls/crypt32/tests/str.c | 7 +++-- 2 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index 277aeb70d4a..8a1684f07ad 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -375,14 +375,6 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, default: FIXME("string type %ld unimplemented\n", dwValueType); } - if (psz && csz) - { - *(psz + ret) = '\0'; - csz--; - ret++; - } - else - ret++; TRACE("returning %ld (%s)\n", ret, debugstr_w(psz)); return ret; } @@ -580,6 +572,7 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, DWORD ret = 0, bytes = 0; BOOL bRet; CERT_NAME_INFO *info; + DWORD chars;
if (dwStrType & unsupportedFlags) FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags); @@ -607,14 +600,17 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, else rdnSep = L" + "; rdnSepLen = lstrlenW(rdnSep); - for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++) + if (!csz) psz = NULL; + for (i = 0; i < info->cRDN; i++) { - for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++) + if (psz && ret + 1 == csz) break; + for (j = 0; j < rdn->cRDNAttr; j++) { - DWORD chars; LPCSTR prefixA = NULL; LPCWSTR prefixW = NULL;
+ if (psz && ret + 1 == csz) break; + if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR) prefixA = rdn->rgRDNAttr[j].pszObjId; else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR) @@ -644,6 +640,7 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, chars = lstrlenW(indent); ret += chars; } + if (psz && ret + 1 == csz) break; } if (prefixW) { @@ -659,38 +656,40 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0); ret += chars; } - chars = quote_rdn_value_to_str_w( - rdn->rgRDNAttr[j].dwValueType, - &rdn->rgRDNAttr[j].Value, psz ? psz + ret : NULL, - psz ? csz - ret : 0); - if (chars) - ret += chars - 1; + if (psz && ret + 1 == csz) break; + + chars = quote_rdn_value_to_str_w(rdn->rgRDNAttr[j].dwValueType, &rdn->rgRDNAttr[j].Value, + psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0); + ret += chars; if (j < rdn->cRDNAttr - 1) { - if (psz && ret < csz - rdnSepLen - 1) - memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR)); - ret += rdnSepLen; + if (psz) + { + chars = min(rdnSepLen, csz - ret - 1); + memcpy(psz + ret, rdnSep, chars * sizeof(WCHAR)); + ret += chars; + } + else ret += rdnSepLen; } } + if (psz && ret + 1 == csz) break; if (i < info->cRDN - 1) { - if (psz && ret < csz - sepLen - 1) - memcpy(psz + ret, sep, sepLen * sizeof(WCHAR)); - ret += sepLen; + if (psz) + { + chars = min(sepLen, csz - ret - 1); + memcpy(psz + ret, sep, chars * sizeof(WCHAR)); + ret += chars; + } + else ret += sepLen; } if(reverse) rdn--; else rdn++; } LocalFree(info); } - if (psz && csz) - { - *(psz + ret) = '\0'; - ret++; - } - else - ret++; - return ret; + if (psz && csz) psz[ret] = 0; + return ret + 1; }
DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c index e10d5a4fb29..f2ee5b96853 100644 --- a/dlls/crypt32/tests/str.c +++ b/dlls/crypt32/tests/str.c @@ -445,14 +445,14 @@ static void test_NameToStrConversionW_(unsigned int line, PCERT_NAME_BLOB pName,
memset(buffer, 0xcc, sizeof(buffer)); retlen = CertNameToStrW(X509_ASN_ENCODING, pName, dwStrType, buffer, len - 1); - todo_wine ok(retlen == len - 1, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); + ok(retlen == len - 1, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); ok(!wcsncmp(buffer, expected, retlen - 1), "line %u: expected %s, got %s\n", line, wine_dbgstr_w(expected), wine_dbgstr_w(buffer)); ok(!buffer[retlen - 1], "line %u: string is not zero terminated.\n", line);
memset(buffer, 0xcc, sizeof(buffer)); retlen = CertNameToStrW(X509_ASN_ENCODING, pName, dwStrType, buffer, 0); - todo_wine ok(retlen == len, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); + ok(retlen == len, "line %u: expected %lu chars, got %lu\n", line, len - 1, retlen); ok(buffer[0] == 0xcccc, "line %u: got %s\n", line, wine_dbgstr_w(buffer)); }
@@ -768,7 +768,8 @@ static void test_CertGetNameString_value_(unsigned int line, PCCERT_CONTEXT cont ok(!wcscmp(strW, expectedW), "line %u: unexpected value %s.\n", line, debugstr_w(strW)); strW[0] = strW[1] = 0xcccc; retlen = CertGetNameStringW(context, type, 0, type_para, strW, len - 1); - todo_wine ok(retlen == len - 1, "line %u: unexpected len %lu, expected %lu.\n", line, retlen, len - 1); + todo_wine_if(type != CERT_NAME_RDN_TYPE) + ok(retlen == len - 1, "line %u: unexpected len %lu, expected %lu.\n", line, retlen, len - 1); ok(!wcsncmp(strW, expectedW, retlen - 1), "line %u: string data mismatch.\n", line); ok(!strW[retlen - 1], "line %u: string is not zero terminated.\n", line); retlen = CertGetNameStringA(context, type, 0, type_para, NULL, len - 1);