[PATCH v2 6/7] crypt32: Reimplement CertRDNValueToStrA() on top of CertRDNValueToStrW().

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


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/crypt32/str.c       | 80 ++++++++++++----------------------------
 dlls/crypt32/tests/str.c | 52 ++++++++++++++------------
 2 files changed, 53 insertions(+), 79 deletions(-)

diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index 5ddad1ff4e6..29882ab771e 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -29,70 +29,38 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
-DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
- LPSTR psz, DWORD csz)
+DWORD WINAPI CertRDNValueToStrA(DWORD type, PCERT_RDN_VALUE_BLOB value_blob,
+                                LPSTR value, DWORD value_len)
 {
-    DWORD ret = 0, len;
+    DWORD len, len_mb, ret;
+    LPWSTR valueW;
 
-    TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
+    TRACE("(%ld, %p, %p, %ld)\n", type, value_blob, value, value_len);
 
-    switch (dwValueType)
-    {
-    case CERT_RDN_ANY_TYPE:
-        break;
-    case CERT_RDN_NUMERIC_STRING:
-    case CERT_RDN_PRINTABLE_STRING:
-    case CERT_RDN_TELETEX_STRING:
-    case CERT_RDN_VIDEOTEX_STRING:
-    case CERT_RDN_IA5_STRING:
-    case CERT_RDN_GRAPHIC_STRING:
-    case CERT_RDN_VISIBLE_STRING:
-    case CERT_RDN_GENERAL_STRING:
-        len = pValue->cbData;
-        if (!psz || !csz)
-            ret = len;
-        else
-        {
-            DWORD chars = min(len, csz - 1);
+    len = CertRDNValueToStrW(type, value_blob, NULL, 0);
 
-            if (chars)
-            {
-                memcpy(psz, pValue->pbData, chars);
-                ret += chars;
-                csz -= chars;
-            }
-        }
-        break;
-    case CERT_RDN_BMP_STRING:
-    case CERT_RDN_UTF8_STRING:
-        len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData,
-         pValue->cbData / sizeof(WCHAR), NULL, 0, NULL, NULL);
-        if (!psz || !csz)
-            ret = len;
-        else
-        {
-            DWORD chars = min(pValue->cbData / sizeof(WCHAR), csz - 1);
+    if (!(valueW = CryptMemAlloc(len * sizeof(*valueW))))
+    {
+        ERR("No memory.\n");
+        if (value && value_len) *value = 0;
+        return 1;
+    }
 
-            if (chars)
-            {
-                ret = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData,
-                 chars, psz, csz - 1, NULL, NULL);
-                csz -= ret;
-            }
-        }
-        break;
-    default:
-        FIXME("string type %ld unimplemented\n", dwValueType);
+    len = CertRDNValueToStrW(type, value_blob, valueW, len);
+    len_mb = WideCharToMultiByte(CP_ACP, 0, valueW, len, NULL, 0, NULL, NULL);
+    if (!value || !value_len)
+    {
+        CryptMemFree(valueW);
+        return len_mb;
     }
-    if (psz && csz)
+
+    ret = WideCharToMultiByte(CP_ACP, 0, valueW, len, value, value_len, NULL, NULL);
+    if (ret < len_mb)
     {
-        *(psz + ret) = '\0';
-        csz--;
-        ret++;
+        value[0] = 0;
+        ret = 1;
     }
-    else
-        ret++;
-    TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
+    CryptMemFree(valueW);
     return ret;
 }
 
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index 2d36b787921..41ae96d4c4e 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -31,7 +31,6 @@ typedef struct _CertRDNAttrEncoding {
     DWORD  dwValueType;
     CERT_RDN_VALUE_BLOB Value;
     LPCSTR str;
-    BOOL todo;
 } CertRDNAttrEncoding, *PCertRDNAttrEncoding;
 
 typedef struct _CertRDNAttrEncodingW {
@@ -133,33 +132,34 @@ static void test_CertRDNValueToStrA(void)
 {
     CertRDNAttrEncoding attrs[] = {
      { "2.5.4.6", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin1), bin1 }, "US", FALSE },
+       { sizeof(bin1), bin1 }, "US" },
      { "2.5.4.8", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin2), bin2 }, "Minnesota", FALSE },
+       { sizeof(bin2), bin2 }, "Minnesota" },
      { "2.5.4.7", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin3), bin3 }, "Minneapolis", FALSE },
+       { sizeof(bin3), bin3 }, "Minneapolis" },
      { "2.5.4.10", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin4), bin4 }, "CodeWeavers", FALSE },
+       { sizeof(bin4), bin4 }, "CodeWeavers" },
      { "2.5.4.11", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin5), bin5 }, "Wine Development", FALSE },
+       { sizeof(bin5), bin5 }, "Wine Development" },
      { "2.5.4.3", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin6), bin6 }, "localhost", FALSE },
+       { sizeof(bin6), bin6 }, "localhost" },
      { "1.2.840.113549.1.9.1", CERT_RDN_IA5_STRING,
-       { sizeof(bin7), bin7 }, "aric at codeweavers.com", FALSE },
+       { sizeof(bin7), bin7 }, "aric at codeweavers.com" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin9), bin9 }, "abc\"def", FALSE },
+       { sizeof(bin9), bin9 }, "abc\"def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin10), bin10 }, "abc'def", FALSE },
+       { sizeof(bin10), bin10 }, "abc'def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin11), bin11 }, "abc, def", FALSE },
+       { sizeof(bin11), bin11 }, "abc, def" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin12), bin12 }, " abc ", FALSE },
+       { sizeof(bin12), bin12 }, " abc " },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin13), bin13 }, "\"def\"", FALSE },
+       { sizeof(bin13), bin13 }, "\"def\"" },
      { "0", CERT_RDN_PRINTABLE_STRING,
-       { sizeof(bin14), bin14 }, "1;3", FALSE },
+       { sizeof(bin14), bin14 }, "1;3" },
     };
-    DWORD i, ret;
+    unsigned int i;
+    DWORD ret, len;
     char buffer[2000];
     CERT_RDN_VALUE_BLOB blob = { 0, NULL };
     static const char ePKI[] = "ePKI Root Certification Authority";
@@ -177,15 +177,21 @@ static void test_CertRDNValueToStrA(void)
 
     for (i = 0; i < ARRAY_SIZE(attrs); i++)
     {
-        ret = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value,
+        len = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value,
          buffer, sizeof(buffer));
-        todo_wine_if (attrs[i].todo)
-        {
-            ok(ret == strlen(attrs[i].str) + 1, "Expected length %d, got %ld\n",
-             lstrlenA(attrs[i].str) + 1, ret);
-            ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n",
-             attrs[i].str, buffer);
-        }
+        ok(len == strlen(attrs[i].str) + 1, "Expected length %d, got %ld\n",
+         lstrlenA(attrs[i].str) + 1, ret);
+        ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n",
+         attrs[i].str, buffer);
+        memset(buffer, 0xcc, sizeof(buffer));
+        ret = CertRDNValueToStrA(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(!strncmp(buffer + 1, attrs[i].str + 1, len - 2), "Strings do not match, test %u.\n", i);
+        memset(buffer, 0xcc, sizeof(buffer));
+        ret = CertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, buffer, 0);
+        ok(ret == len, "Unexpected ret %lu, expected %lu, test %u.\n", ret, len, i);
+        ok((unsigned char)buffer[0] == 0xcc, "Unexpected value %#x, test %u.\n", buffer[0], i);
     }
     blob.pbData = bin8;
     blob.cbData = sizeof(bin8);
-- 
2.35.1




More information about the wine-devel mailing list