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

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 20 06:20:25 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 9bce49543b6b3ae6a7e9cbd06bd57ed244660458
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=9bce49543b6b3ae6a7e9cbd06bd57ed244660458

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Wed Jul 19 12:30:43 2006 -0700

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

---

 dlls/crypt32/str.c       |   71 +++++++++++++++++++++++++---------------------
 dlls/crypt32/tests/str.c |    6 ++++
 2 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index ef67a9a..3298652 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -62,6 +62,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dw
     }
     else
         ret++;
+    TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
     return ret;
 }
 
@@ -106,6 +107,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dw
     }
     else
         ret++;
+    TRACE("returning %ld (%s)\n", ret, debugstr_w(psz));
     return ret;
 }
 
@@ -116,20 +118,21 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dw
  */
 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);
 
-    if (psz && chars)
-        memcpy(psz, prefix, chars);
-    csz -= chars;
-    if (csz > 1)
+    if (psz)
     {
-        if (psz)
-            *(psz + chars) = '=';
+        chars = min(lstrlenA(prefix), csz);
+        memcpy(psz, prefix, chars);
+        csz -= chars;
+        *(psz + chars) = '=';
         chars++;
         csz--;
     }
+    else
+        chars = lstrlenA(prefix) + 1;
     return chars;
 }
 
@@ -171,9 +174,9 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
         else
             rdnSep = plusSep;
         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;
                 char prefixBuf[10]; /* big enough for GivenName */
@@ -200,7 +203,8 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
                 if (prefix)
                 {
                     /* - 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;
                     csz -= chars;
                 }
@@ -208,7 +212,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
                 chars = CertRDNValueToStrA(
                  info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                  &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
-                 csz - ret - 1);
+                 psz ? csz - ret : 0);
                 if (chars)
                     ret += chars - 1;
                 if (j < info->rgRDN[i].cRDNAttr - 1)
@@ -235,6 +239,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
     }
     else
         ret++;
+    TRACE("Returning %s\n", debugstr_a(psz));
     return ret;
 }
 
@@ -246,25 +251,24 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
  */
 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);
 
-    if (psz && chars)
+    if (psz)
     {
         DWORD i;
 
+        chars = min(lstrlenA(prefix), csz);
         for (i = 0; i < chars; i++)
             *(psz + i) = prefix[i];
-    }
-    csz -= chars;
-    if (csz > 1)
-    {
-        if (psz)
-            *(psz + chars) = '=';
+        csz -= chars;
+        *(psz + chars) = '=';
         chars++;
         csz--;
     }
+    else
+        chars = lstrlenA(prefix) + 1;
     return chars;
 }
 
@@ -275,20 +279,21 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR 
  */
 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);
 
-    if (psz && chars)
-        memcpy(psz, prefix, chars * sizeof(WCHAR));
-    csz -= chars;
-    if (csz > 1)
+    if (psz)
     {
-        if (psz)
-            *(psz + chars) = '=';
+        chars = min(lstrlenW(prefix), csz);
+        memcpy(psz, prefix, chars * sizeof(WCHAR));
+        csz -= chars;
+        *(psz + chars) = '=';
         chars++;
         csz--;
     }
+    else
+        chars = lstrlenW(prefix) + 1;
     return chars;
 }
 
@@ -330,9 +335,9 @@ DWORD WINAPI CertNameToStrW(DWORD dwCert
         else
             rdnSep = plusSep;
         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;
                 LPCSTR prefixA = NULL;
@@ -355,15 +360,16 @@ DWORD WINAPI CertNameToStrW(DWORD dwCert
                 if (prefixW)
                 {
                     /* - 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;
                     csz -= chars;
                 }
                 else if (prefixA)
                 {
                     /* - 1 is needed to account for the NULL terminator. */
-                    chars = CRYPT_AddPrefixAToW(prefixA, psz + ret,
-                     csz - ret - 1);
+                    chars = CRYPT_AddPrefixAToW(prefixA,
+                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                     ret += chars;
                     csz -= chars;
                 }
@@ -371,7 +377,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCert
                 chars = CertRDNValueToStrW(
                  info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                  &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
-                 csz - ret - 1);
+                 psz ? csz - ret : 0);
                 if (chars)
                     ret += chars - 1;
                 if (j < info->rgRDN[i].cRDNAttr - 1)
@@ -398,6 +404,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCert
     }
     else
         ret++;
+    TRACE("Returning %s\n", debugstr_w(psz));
     return ret;
 }
 
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index abece9c..15a8a2b 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -297,6 +297,9 @@ static void test_NameToStrConversionA(PC
     char buffer[2000] = { 0 };
     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,
      sizeof(buffer));
     ok(i == strlen(expected) + 1, "Expected %d chars, got %ld\n",
@@ -363,6 +366,9 @@ static void test_NameToStrConversionW(PC
     WCHAR buffer[2000] = { 0 };
     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,
      sizeof(buffer) / sizeof(buffer[0]));
     ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %ld\n",




More information about the wine-cvs mailing list