Commit 66d9250c authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

crypt32: Fix filling short output in CertGetNameStringW().

parent a78f2319
...@@ -96,8 +96,8 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, ...@@ -96,8 +96,8 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
return ret; return ret;
} }
DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, static DWORD rdn_value_to_strW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
LPWSTR psz, DWORD csz) LPWSTR psz, DWORD csz, BOOL partial_copy)
{ {
DWORD ret = 0, len, i; DWORD ret = 0, len, i;
...@@ -117,8 +117,9 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, ...@@ -117,8 +117,9 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
case CERT_RDN_GENERAL_STRING: case CERT_RDN_GENERAL_STRING:
len = pValue->cbData; len = pValue->cbData;
if (!psz || !csz) ret = len; if (!psz || !csz) ret = len;
else if (len < csz) else if (len < csz || partial_copy)
{ {
len = min(len, csz - 1);
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
psz[i] = pValue->pbData[i]; psz[i] = pValue->pbData[i];
ret = len; ret = len;
...@@ -129,10 +130,11 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, ...@@ -129,10 +130,11 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
len = pValue->cbData / sizeof(WCHAR); len = pValue->cbData / sizeof(WCHAR);
if (!psz || !csz) if (!psz || !csz)
ret = len; ret = len;
else if (len < csz) else if (len < csz || partial_copy)
{ {
WCHAR *ptr = psz; WCHAR *ptr = psz;
len = min(len, csz - 1);
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
ptr[i] = ((LPCWSTR)pValue->pbData)[i]; ptr[i] = ((LPCWSTR)pValue->pbData)[i];
ret = len; ret = len;
...@@ -146,6 +148,12 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, ...@@ -146,6 +148,12 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
return ret + 1; return ret + 1;
} }
DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
LPWSTR psz, DWORD csz)
{
return rdn_value_to_strW(dwValueType, pValue, psz, csz, FALSE);
}
static inline BOOL is_quotable_char(WCHAR c) static inline BOOL is_quotable_char(WCHAR c)
{ {
switch(c) switch(c)
...@@ -1196,13 +1204,24 @@ static DWORD cert_get_name_from_rdn_attr(DWORD encodingType, ...@@ -1196,13 +1204,24 @@ static DWORD cert_get_name_from_rdn_attr(DWORD encodingType,
oid = szOID_RSA_emailAddr; oid = szOID_RSA_emailAddr;
nameAttr = CertFindRDNAttr(oid, nameInfo); nameAttr = CertFindRDNAttr(oid, nameInfo);
if (nameAttr) if (nameAttr)
ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value, ret = rdn_value_to_strW(nameAttr->dwValueType, &nameAttr->Value,
pszNameString, cchNameString); pszNameString, cchNameString, TRUE);
LocalFree(nameInfo); LocalFree(nameInfo);
} }
return ret; return ret;
} }
static DWORD copy_output_str(WCHAR *dst, const WCHAR *src, DWORD dst_size)
{
DWORD len = wcslen(src);
if (!dst || !dst_size) return len + 1;
len = min(len, dst_size - 1);
memcpy(dst, src, len * sizeof(*dst));
dst[len] = 0;
return len + 1;
}
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString) DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
{ {
...@@ -1235,23 +1254,14 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1235,23 +1254,14 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
altNameOID, CERT_ALT_NAME_RFC822_NAME, &info); altNameOID, CERT_ALT_NAME_RFC822_NAME, &info);
if (entry) if (entry) ret = copy_output_str(pszNameString, entry->u.pwszRfc822Name, cchNameString);
{
if (!pszNameString)
ret = lstrlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString)
{
ret = min(lstrlenW(entry->u.pwszRfc822Name), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}
if (info) if (info)
LocalFree(info); LocalFree(info);
if (!ret) if (!ret)
{
ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
name, szOID_RSA_emailAddr, pszNameString, cchNameString); name, szOID_RSA_emailAddr, pszNameString, cchNameString);
}
break; break;
} }
case CERT_NAME_RDN_TYPE: case CERT_NAME_RDN_TYPE:
...@@ -1308,8 +1318,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1308,8 +1318,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
for (i = 0; !nameAttr && i < ARRAY_SIZE(simpleAttributeOIDs); i++) for (i = 0; !nameAttr && i < ARRAY_SIZE(simpleAttributeOIDs); i++)
nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo); nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo);
if (nameAttr) if (nameAttr)
ret = CertRDNValueToStrW(nameAttr->dwValueType, ret = rdn_value_to_strW(nameAttr->dwValueType,
&nameAttr->Value, pszNameString, cchNameString); &nameAttr->Value, pszNameString, cchNameString, TRUE);
LocalFree(nameInfo); LocalFree(nameInfo);
} }
if (!ret) if (!ret)
...@@ -1322,19 +1332,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1322,19 +1332,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
{ {
if (!entry && altInfo->cAltEntry) if (!entry && altInfo->cAltEntry)
entry = &altInfo->rgAltEntry[0]; entry = &altInfo->rgAltEntry[0];
if (entry) if (entry) ret = copy_output_str(pszNameString, entry->u.pwszRfc822Name, cchNameString);
{
if (!pszNameString)
ret = lstrlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString)
{
ret = min(lstrlenW(entry->u.pwszRfc822Name),
cchNameString - 1);
memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}
LocalFree(altInfo); LocalFree(altInfo);
} }
} }
...@@ -1359,17 +1357,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1359,17 +1357,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
altNameOID, CERT_ALT_NAME_DNS_NAME, &info); altNameOID, CERT_ALT_NAME_DNS_NAME, &info);
if (entry) if (entry) ret = copy_output_str(pszNameString, entry->u.pwszDNSName, cchNameString);
{
if (!pszNameString)
ret = lstrlenW(entry->u.pwszDNSName) + 1;
else if (cchNameString)
{
ret = min(lstrlenW(entry->u.pwszDNSName), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}
if (info) if (info)
LocalFree(info); LocalFree(info);
if (!ret) if (!ret)
...@@ -1383,17 +1372,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1383,17 +1372,8 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
altNameOID, CERT_ALT_NAME_URL, &info); altNameOID, CERT_ALT_NAME_URL, &info);
if (entry) if (entry) ret = copy_output_str(pszNameString, entry->u.pwszURL, cchNameString);
{
if (!pszNameString)
ret = lstrlenW(entry->u.pwszURL) + 1;
else if (cchNameString)
{
ret = min(lstrlenW(entry->u.pwszURL), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}
if (info) if (info)
LocalFree(info); LocalFree(info);
break; break;
...@@ -1401,17 +1381,13 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, ...@@ -1401,17 +1381,13 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
default: default:
FIXME("unimplemented for type %ld\n", dwType); FIXME("unimplemented for type %ld\n", dwType);
ret = 0; ret = 0;
break;
} }
done: done:
if (!ret) if (!ret)
{ {
if (!pszNameString) ret = 1;
ret = 1; if (pszNameString && cchNameString) pszNameString[0] = 0;
else if (cchNameString)
{
pszNameString[0] = 0;
ret = 1;
}
} }
return ret; return ret;
} }
...@@ -774,8 +774,7 @@ static void test_CertGetNameString_value_(unsigned int line, PCCERT_CONTEXT cont ...@@ -774,8 +774,7 @@ 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)); ok(!wcscmp(strW, expectedW), "line %u: unexpected value %s.\n", line, debugstr_w(strW));
strW[0] = strW[1] = 0xcccc; strW[0] = strW[1] = 0xcccc;
retlen = CertGetNameStringW(context, type, 0, type_para, strW, len - 1); retlen = CertGetNameStringW(context, type, 0, type_para, strW, 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(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(!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); ok(!strW[retlen - 1], "line %u: string is not zero terminated.\n", line);
retlen = CertGetNameStringA(context, type, 0, type_para, NULL, len - 1); retlen = CertGetNameStringA(context, type, 0, type_para, NULL, len - 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment