Module: wine Branch: master Commit: 993068038e0958ccb3f866c7faf0ebe012b9fa21 URL: http://source.winehq.org/git/wine.git/?a=commit;h=993068038e0958ccb3f866c7fa...
Author: Juan Lang juan.lang@gmail.com Date: Mon Oct 18 17:23:05 2010 -0700
crypt32: Implement quoting of simple string types.
---
dlls/crypt32/str.c | 89 +++++++++++++++++++++++++++++++++++++--------- dlls/crypt32/tests/str.c | 8 ++-- 2 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index 914ccaa..d3a1a36 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -29,10 +29,29 @@
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+static inline BOOL is_quotable_char(char c) +{ + switch(c) + { + case '+': + case ',': + case '"': + case '=': + case '<': + case '>': + case ';': + case '#': + return TRUE; + default: + return FALSE; + } +} + DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, LPSTR psz, DWORD csz) { - DWORD ret = 0; + DWORD ret = 0, len, i; + BOOL needsQuotes = FALSE;
TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);
@@ -48,18 +67,37 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, case CERT_RDN_GRAPHIC_STRING: case CERT_RDN_VISIBLE_STRING: case CERT_RDN_GENERAL_STRING: + len = pValue->cbData; + if (pValue->cbData && isspace(pValue->pbData[0])) + needsQuotes = TRUE; + if (pValue->cbData && isspace(pValue->pbData[pValue->cbData - 1])) + needsQuotes = TRUE; + for (i = 0; i < pValue->cbData; i++) + { + if (is_quotable_char(pValue->pbData[i])) + needsQuotes = TRUE; + if (pValue->pbData[i] == '"') + len += 1; + } + if (needsQuotes) + len += 2; if (!psz || !csz) - ret = pValue->cbData; + ret = len; else { - DWORD chars = min(pValue->cbData, csz - 1); + char *ptr = psz;
- if (chars) + if (needsQuotes) + *ptr++ = '"'; + for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++) { - memcpy(psz, pValue->pbData, chars); - ret += chars; - csz -= chars; + *ptr = pValue->pbData[i]; + if (pValue->pbData[i] == '"' && ptr - psz < csz - 1) + *(++ptr) = '"'; } + if (needsQuotes && ptr - psz < csz) + *ptr++ = '"'; + ret = ptr - psz; } break; case CERT_RDN_UTF8_STRING: @@ -91,7 +129,8 @@ 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; + DWORD ret = 0, len, i; + BOOL needsQuotes = FALSE;
TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);
@@ -107,21 +146,37 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, case CERT_RDN_GRAPHIC_STRING: case CERT_RDN_VISIBLE_STRING: case CERT_RDN_GENERAL_STRING: + len = pValue->cbData; + if (pValue->cbData && isspace(pValue->pbData[0])) + needsQuotes = TRUE; + if (pValue->cbData && isspace(pValue->pbData[pValue->cbData - 1])) + needsQuotes = TRUE; + for (i = 0; i < pValue->cbData; i++) + { + if (is_quotable_char(pValue->pbData[i])) + needsQuotes = TRUE; + if (pValue->pbData[i] == '"') + len += 1; + } + if (needsQuotes) + len += 2; if (!psz || !csz) - ret = pValue->cbData; + ret = len; else { - DWORD chars = min(pValue->cbData, csz - 1); + WCHAR *ptr = psz;
- if (chars) + if (needsQuotes) + *ptr++ = '"'; + for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++) { - DWORD i; - - for (i = 0; i < chars; i++) - psz[i] = pValue->pbData[i]; - ret += chars; - csz -= chars; + *ptr = pValue->pbData[i]; + if (pValue->pbData[i] == '"' && ptr - psz < csz - 1) + *(++ptr) = '"'; } + if (needsQuotes && ptr - psz < csz) + *ptr++ = '"'; + ret = ptr - psz; } break; case CERT_RDN_UTF8_STRING: diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c index 573219d..3032b93 100644 --- a/dlls/crypt32/tests/str.c +++ b/dlls/crypt32/tests/str.c @@ -439,20 +439,20 @@ static void test_CertNameToStrA(void) test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN='1'", FALSE); blob.pbData = encodedSpacedCN; blob.cbData = sizeof(encodedSpacedCN); - test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=" 1 "", TRUE); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=" 1 "", FALSE); blob.pbData = encodedQuotedCN; blob.cbData = sizeof(encodedQuotedCN); test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="""1"""", TRUE); blob.pbData = encodedMultipleAttrCN; blob.cbData = sizeof(encodedMultipleAttrCN); - test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="1+2"", TRUE); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="1+2"", FALSE); blob.pbData = encodedCommaCN; blob.cbData = sizeof(encodedCommaCN); - test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="a,b"", TRUE); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="a,b"", FALSE); blob.pbData = encodedEqualCN; blob.cbData = sizeof(encodedEqualCN); - test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="a=b"", TRUE); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="a=b"", FALSE); blob.pbData = encodedLessThanCN; blob.cbData = sizeof(encodedLessThanCN); test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN="<"", TRUE);