[PATCH v2 2/7] crypt32: Fix filling short output in cert_name_to_str_with_indent().

Paul Gofman pgofman at codeweavers.com
Thu Apr 14 12:57:03 CDT 2022


Signed-off-by: Paul Gofman <pgofman at 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 c91a27a0995..757bd8a39bb 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -444,14 +444,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));
 }
 
@@ -767,7 +767,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);
-- 
2.35.1




More information about the wine-devel mailing list