[4/5] advapi32: Set output type earlier in CredUnmarshalCredential.

Thomas Faber thomas.faber at reactos.org
Sat Mar 29 05:57:34 CDT 2014


As shown by the test, Windows sets the type output parameter before
performing the type-specific validity checks.
Additional tests show that char_decode should be used to determine
the type. These tests are added and fixed here as well.
-------------- next part --------------
From a2b27349155cb9d8c885b470cf8756d7613b6d21 Mon Sep 17 00:00:00 2001
From: Thomas Faber <thomas.faber at reactos.org>
Date: Sat, 29 Mar 2014 10:18:22 +0100
Subject: advapi32: Set output type earlier in CredUnmarshalCredential.

---
 dlls/advapi32/cred.c       | 11 ++++++-----
 dlls/advapi32/tests/cred.c | 26 +++++++++++++++++---------
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 2d98ecc..9ecfaee 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -2068,13 +2068,15 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
 
     TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
 
-    if (!cred || cred[0] != '@' || cred[1] != '@' || !cred[2] || !cred[3])
+    if (!cred || cred[0] != '@' || cred[1] != '@' ||
+        char_decode( cred[2] ) > 63)
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
     len = strlenW( cred + 3 );
-    switch (cred[2] - 'A')
+    *type = char_decode( cred[2] );
+    switch (*type)
     {
     case CertCredential:
     {
@@ -2089,7 +2091,6 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
         if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
         memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
         cert->cbSize = sizeof(*cert);
-        *type = CertCredential;
         *out = cert;
         break;
     }
@@ -2113,7 +2114,6 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
         }
         target->UserName = (WCHAR *)(target + 1);
         target->UserName[size / sizeof(WCHAR)] = 0;
-        *type = UsernameTargetCredential;
         *out = target;
         break;
     }
@@ -2121,7 +2121,8 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
         FIXME("BinaryBlobCredential not implemented\n");
         return FALSE;
     default:
-        WARN("unhandled type %u\n", cred[2] - 'A');
+        WARN("unhandled type %u\n", *type);
+        SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
     return TRUE;
diff --git a/dlls/advapi32/tests/cred.c b/dlls/advapi32/tests/cred.c
index e65a605..de05e30 100644
--- a/dlls/advapi32/tests/cred.c
+++ b/dlls/advapi32/tests/cred.c
@@ -580,9 +580,25 @@ static void test_CredUnmarshalCredentialA(void)
         CRED_MARSHAL_TYPE type;
         const void *unmarshaled;
     } tests[] = {
+        { "", 0, NULL },
+        { "@", 0, NULL },
+        { "@@", 0, NULL },
+        { "@@@", 0, NULL },
+        { "@@A", 0, NULL },
+        { "@@E", 4, NULL },
+        { "@@Z", 25, NULL },
+        { "@@a", 26, NULL },
+        { "@@0", 52, NULL },
+        { "@@#", 62, NULL },
+        { "@@-", 63, NULL },
+        { "@@B", CertCredential, NULL },
+        { "@@BA", CertCredential, NULL },
         { "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", CertCredential, cert_empty },
         { "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", CertCredential, cert_wine },
+        { "@@C", UsernameTargetCredential, NULL },
+        { "@@CA", UsernameTargetCredential, NULL },
         { "@@CAAAAAA", UsernameTargetCredential, NULL },
+        { "@@CAAAAAA0B", UsernameTargetCredential, NULL },
         { "@@CAAAAAA0BA", UsernameTargetCredential, NULL },
         { "@@CCAAAAA0BA", UsernameTargetCredential, tW },
         { "@@CIAAAAA0BQZAMHA0BA", UsernameTargetCredential, testW },
@@ -610,14 +626,6 @@ static void test_CredUnmarshalCredentialA(void)
     ok( !ret, "unexpected success\n" );
     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
 
-    type = 0;
-    cert = NULL;
-    SetLastError( 0xdeadbeef );
-    ret = pCredUnmarshalCredentialA( "", &type, (void **)&cert );
-    error = GetLastError();
-    ok( !ret, "unexpected success\n" );
-    ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
-
     if (0) { /* crash */
     SetLastError( 0xdeadbeef );
     ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, NULL );
@@ -665,7 +673,7 @@ static void test_CredUnmarshalCredentialA(void)
         {
             ok(!ret, "[%u] unexpected success\n", i);
             ok(error == ERROR_INVALID_PARAMETER, "[%u] got %u\n", i, error);
-            todo_wine ok(type == tests[i].type, "[%u] got %u\n", i, type);
+            ok(type == tests[i].type, "[%u] got %u\n", i, type);
             ok(p == NULL, "[%u] returned pointer is not NULL\n", i);
         }
 
-- 
1.8.3.2



More information about the wine-patches mailing list