crypt32: Correct handling of empty output buffer in CertRDNValueToStr and CertNameToStr.

This commit is contained in:
Juan Lang 2006-07-19 12:30:43 -07:00 committed by Alexandre Julliard
parent 07253473d4
commit 9bce49543b
2 changed files with 45 additions and 32 deletions

View File

@ -62,6 +62,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
} }
else else
ret++; ret++;
TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
return ret; return ret;
} }
@ -106,6 +107,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
} }
else else
ret++; ret++;
TRACE("returning %ld (%s)\n", ret, debugstr_w(psz));
return ret; return ret;
} }
@ -116,20 +118,21 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
*/ */
static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz) static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
{ {
DWORD chars = min(lstrlenA(prefix), csz); DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
if (psz && chars) if (psz)
memcpy(psz, prefix, chars);
csz -= chars;
if (csz > 1)
{ {
if (psz) chars = min(lstrlenA(prefix), csz);
*(psz + chars) = '='; memcpy(psz, prefix, chars);
csz -= chars;
*(psz + chars) = '=';
chars++; chars++;
csz--; csz--;
} }
else
chars = lstrlenA(prefix) + 1;
return chars; return chars;
} }
@ -171,9 +174,9 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
else else
rdnSep = plusSep; rdnSep = plusSep;
rdnSepLen = strlen(rdnSep); rdnSepLen = strlen(rdnSep);
for (i = 0; ret < csz && i < info->cRDN; i++) for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
{ {
for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++) for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
{ {
DWORD chars; DWORD chars;
char prefixBuf[10]; /* big enough for GivenName */ char prefixBuf[10]; /* big enough for GivenName */
@ -200,7 +203,8 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
if (prefix) if (prefix)
{ {
/* - 1 is needed to account for the NULL terminator. */ /* - 1 is needed to account for the NULL terminator. */
chars = CRYPT_AddPrefixA(prefix, psz + ret, csz - ret - 1); chars = CRYPT_AddPrefixA(prefix,
psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars; ret += chars;
csz -= chars; csz -= chars;
} }
@ -208,7 +212,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
chars = CertRDNValueToStrA( chars = CertRDNValueToStrA(
info->rgRDN[i].rgRDNAttr[j].dwValueType, info->rgRDN[i].rgRDNAttr[j].dwValueType,
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL, &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
csz - ret - 1); psz ? csz - ret : 0);
if (chars) if (chars)
ret += chars - 1; ret += chars - 1;
if (j < info->rgRDN[i].cRDNAttr - 1) if (j < info->rgRDN[i].cRDNAttr - 1)
@ -235,6 +239,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
} }
else else
ret++; ret++;
TRACE("Returning %s\n", debugstr_a(psz));
return ret; return ret;
} }
@ -246,25 +251,24 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
*/ */
static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz) static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
{ {
DWORD chars = min(lstrlenA(prefix), csz); DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
if (psz && chars) if (psz)
{ {
DWORD i; DWORD i;
chars = min(lstrlenA(prefix), csz);
for (i = 0; i < chars; i++) for (i = 0; i < chars; i++)
*(psz + i) = prefix[i]; *(psz + i) = prefix[i];
} csz -= chars;
csz -= chars; *(psz + chars) = '=';
if (csz > 1)
{
if (psz)
*(psz + chars) = '=';
chars++; chars++;
csz--; csz--;
} }
else
chars = lstrlenA(prefix) + 1;
return chars; return chars;
} }
@ -275,20 +279,21 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
*/ */
static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz) static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
{ {
DWORD chars = min(lstrlenW(prefix), csz); DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz); TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz);
if (psz && chars) if (psz)
memcpy(psz, prefix, chars * sizeof(WCHAR));
csz -= chars;
if (csz > 1)
{ {
if (psz) chars = min(lstrlenW(prefix), csz);
*(psz + chars) = '='; memcpy(psz, prefix, chars * sizeof(WCHAR));
csz -= chars;
*(psz + chars) = '=';
chars++; chars++;
csz--; csz--;
} }
else
chars = lstrlenW(prefix) + 1;
return chars; return chars;
} }
@ -330,9 +335,9 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
else else
rdnSep = plusSep; rdnSep = plusSep;
rdnSepLen = lstrlenW(rdnSep); rdnSepLen = lstrlenW(rdnSep);
for (i = 0; ret < csz && i < info->cRDN; i++) for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
{ {
for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++) for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
{ {
DWORD chars; DWORD chars;
LPCSTR prefixA = NULL; LPCSTR prefixA = NULL;
@ -355,15 +360,16 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
if (prefixW) if (prefixW)
{ {
/* - 1 is needed to account for the NULL terminator. */ /* - 1 is needed to account for the NULL terminator. */
chars = CRYPT_AddPrefixW(prefixW, psz + ret, csz - ret - 1); chars = CRYPT_AddPrefixW(prefixW,
psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars; ret += chars;
csz -= chars; csz -= chars;
} }
else if (prefixA) else if (prefixA)
{ {
/* - 1 is needed to account for the NULL terminator. */ /* - 1 is needed to account for the NULL terminator. */
chars = CRYPT_AddPrefixAToW(prefixA, psz + ret, chars = CRYPT_AddPrefixAToW(prefixA,
csz - ret - 1); psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars; ret += chars;
csz -= chars; csz -= chars;
} }
@ -371,7 +377,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
chars = CertRDNValueToStrW( chars = CertRDNValueToStrW(
info->rgRDN[i].rgRDNAttr[j].dwValueType, info->rgRDN[i].rgRDNAttr[j].dwValueType,
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL, &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
csz - ret - 1); psz ? csz - ret : 0);
if (chars) if (chars)
ret += chars - 1; ret += chars - 1;
if (j < info->rgRDN[i].cRDNAttr - 1) if (j < info->rgRDN[i].cRDNAttr - 1)
@ -398,6 +404,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
} }
else else
ret++; ret++;
TRACE("Returning %s\n", debugstr_w(psz));
return ret; return ret;
} }

View File

@ -297,6 +297,9 @@ static void test_NameToStrConversionA(PCERT_NAME_BLOB pName, DWORD dwStrType,
char buffer[2000] = { 0 }; char buffer[2000] = { 0 };
DWORD i; DWORD i;
i = pCertNameToStrA(X509_ASN_ENCODING, pName, dwStrType, NULL, 0);
ok(i == strlen(expected) + 1, "Expected %d chars, got %ld\n",
lstrlenA(expected) + 1, i);
i = pCertNameToStrA(X509_ASN_ENCODING,pName, dwStrType, buffer, i = pCertNameToStrA(X509_ASN_ENCODING,pName, dwStrType, buffer,
sizeof(buffer)); sizeof(buffer));
ok(i == strlen(expected) + 1, "Expected %d chars, got %ld\n", ok(i == strlen(expected) + 1, "Expected %d chars, got %ld\n",
@ -363,6 +366,9 @@ static void test_NameToStrConversionW(PCERT_NAME_BLOB pName, DWORD dwStrType,
WCHAR buffer[2000] = { 0 }; WCHAR buffer[2000] = { 0 };
DWORD i; DWORD i;
i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, NULL, 0);
ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %ld\n",
lstrlenW(expected) + 1, i);
i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, buffer, i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, buffer,
sizeof(buffer) / sizeof(buffer[0])); sizeof(buffer) / sizeof(buffer[0]));
ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %ld\n", ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %ld\n",