[PATCH 3/7] crypt32: Fix filling short output in CertRDNValueToStrW().

Paul Gofman wine at gitlab.winehq.org
Thu Apr 28 18:51:37 CDT 2022


From: Paul Gofman <pgofman at codeweavers.com>

---
 dlls/crypt32/str.c       | 38 +++++++++++------------------
 dlls/crypt32/tests/str.c | 52 ++++++++++++++++++++++------------------
 2 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index 8a1684f07ad..732dcb5ae33 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -99,7 +99,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
 DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
  LPWSTR psz, DWORD csz)
 {
-    DWORD ret = 0, len, i, strLen;
+    DWORD ret = 0, len, i;
 
     TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
 
@@ -116,44 +116,34 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
     case CERT_RDN_VISIBLE_STRING:
     case CERT_RDN_GENERAL_STRING:
         len = pValue->cbData;
-        if (!psz || !csz)
-            ret = len;
-        else
+        if (!psz || !csz) ret = len;
+        else if (len < csz)
         {
-            WCHAR *ptr = psz;
-
-            for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++)
-                *ptr = pValue->pbData[i];
-            ret = ptr - psz;
+            for (i = 0; i < len; ++i)
+                psz[i] = pValue->pbData[i];
+            ret = len;
         }
         break;
     case CERT_RDN_BMP_STRING:
     case CERT_RDN_UTF8_STRING:
-        strLen = len = pValue->cbData / sizeof(WCHAR);
+        len = pValue->cbData / sizeof(WCHAR);
         if (!psz || !csz)
             ret = len;
-        else
+        else if (len < csz)
         {
             WCHAR *ptr = psz;
 
-            for (i = 0; i < strLen && ptr - psz < csz; ptr++, i++)
-                *ptr = ((LPCWSTR)pValue->pbData)[i];
-            ret = ptr - psz;
+            for (i = 0; i < len; ++i)
+                ptr[i] = ((LPCWSTR)pValue->pbData)[i];
+            ret = len;
         }
         break;
     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;
+    if (psz && csz) psz[ret] = 0;
+    TRACE("returning %ld (%s)\n", ret + 1, debugstr_w(psz));
+    return ret + 1;
 }
 
 static inline BOOL is_quotable_char(WCHAR c)
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index f2ee5b96853..62889242e94 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -39,7 +39,6 @@ typedef struct _CertRDNAttrEncodingW {
     DWORD  dwValueType;
     CERT_RDN_VALUE_BLOB Value;
     LPCWSTR str;
-    BOOL todo;
 } CertRDNAttrEncodingW, *PCertRDNAttrEncodingW;
 
 static BYTE bin1[] = { 0x55, 0x53 };
@@ -202,33 +201,34 @@ static void test_CertRDNValueToStrW(void)
     static const WCHAR ePKIW[] = L"ePKI Root Certification Authority";
     CertRDNAttrEncodingW attrs[] = {
      { "2.5.4.6", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin1), bin1 }, L"US", FALSE },
+       { sizeof(bin1), bin1 }, L"US" },
      { "2.5.4.8", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin2), bin2 }, L"Minnesota", FALSE },
+       { sizeof(bin2), bin2 }, L"Minnesota" },
      { "2.5.4.7", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin3), bin3 }, L"Minneapolis", FALSE },
+       { sizeof(bin3), bin3 }, L"Minneapolis" },
      { "2.5.4.10", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin4), bin4 }, L"CodeWeavers", FALSE },
+       { sizeof(bin4), bin4 }, L"CodeWeavers" },
      { "2.5.4.11", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin5), bin5 }, L"Wine Development", FALSE },
+       { sizeof(bin5), bin5 }, L"Wine Development" },
      { "2.5.4.3", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin6), bin6 }, L"localhost", FALSE },
+       { sizeof(bin6), bin6 }, L"localhost" },
      { "1.2.840.113549.1.9.1", CERT_RDN_IA5_STRING,
-       { sizeof(bin7), bin7 }, L"aric at codeweavers.com", FALSE },
+       { sizeof(bin7), bin7 }, L"aric at codeweavers.com" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin9), bin9 }, L"abc\"def", FALSE },
+       { sizeof(bin9), bin9 }, L"abc\"def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin10), bin10 }, L"abc'def", FALSE },
+       { sizeof(bin10), bin10 }, L"abc'def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin11), bin11 }, L"abc, def", FALSE },
+       { sizeof(bin11), bin11 }, L"abc, def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin12), bin12 }, L" abc ", FALSE },
+       { sizeof(bin12), bin12 }, L" abc " },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin13), bin13 }, L"\"def\"", FALSE },
+       { sizeof(bin13), bin13 }, L"\"def\"" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin14), bin14 }, L"1;3", FALSE },
+       { sizeof(bin14), bin14 }, L"1;3" },
     };
-    DWORD i, ret;
+    unsigned int i;
+    DWORD ret, len;
     WCHAR buffer[2000];
     CERT_RDN_VALUE_BLOB blob = { 0, NULL };
 
@@ -245,14 +245,20 @@ static void test_CertRDNValueToStrW(void)
 
     for (i = 0; i < ARRAY_SIZE(attrs); i++)
     {
-        ret = CertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, ARRAY_SIZE(buffer));
-        todo_wine_if (attrs[i].todo)
-        {
-            ok(ret == lstrlenW(attrs[i].str) + 1,
-             "Expected length %d, got %ld\n", lstrlenW(attrs[i].str) + 1, ret);
-            ok(!lstrcmpW(buffer, attrs[i].str), "Expected %s, got %s\n",
-             wine_dbgstr_w(attrs[i].str), wine_dbgstr_w(buffer));
-        }
+        len = CertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, ARRAY_SIZE(buffer));
+        ok(len == lstrlenW(attrs[i].str) + 1,
+         "Expected length %d, got %ld\n", lstrlenW(attrs[i].str) + 1, ret);
+        ok(!lstrcmpW(buffer, attrs[i].str), "Expected %s, got %s\n",
+         wine_dbgstr_w(attrs[i].str), wine_dbgstr_w(buffer));
+        memset(buffer, 0xcc, sizeof(buffer));
+        ret = CertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, len - 1);
+        ok(ret == 1, "Unexpected ret %lu, expected 1, test %u.\n", ret, i);
+        ok(!buffer[0], "Unexpected value %#x, test %u.\n", buffer[0], i);
+        ok(buffer[1] == 0xcccc, "Unexpected value %#x, test %u.\n", buffer[1], i);
+        memset(buffer, 0xcc, sizeof(buffer));
+        ret = CertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, 0);
+        ok(ret == len, "Unexpected ret %lu, expected %lu, test %u.\n", ret, len, i);
+        ok(buffer[0] == 0xcccc, "Unexpected value %#x, test %u.\n", buffer[0], i);
     }
     blob.pbData = bin8;
     blob.cbData = sizeof(bin8);
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/12



More information about the wine-devel mailing list