Signed-off-by: Esme Povirk esme@codeweavers.com --- dlls/advapi32/tests/security.c | 1 + dlls/sechost/security.c | 59 +++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 6037ddb2165..77748abe9ec 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -306,6 +306,7 @@ static void test_ConvertStringSidToSid(void) { "RS", "", 1 }, { "SA", "", 1 }, { "s-1-12-1", "S-1-12-1" }, + { "S-0x1-0XC-0x1a", "S-1-12-26" }, };
const char noSubAuthStr[] = "S-1-5"; diff --git a/dlls/sechost/security.c b/dlls/sechost/security.c index b4f00f5bdf5..4aee8c723d2 100644 --- a/dlls/sechost/security.c +++ b/dlls/sechost/security.c @@ -594,18 +594,42 @@ static BOOL get_computer_sid( PSID sid ) return TRUE; }
+static BOOL parse_token( const WCHAR *string, const WCHAR **end, DWORD *result ) +{ + if (string[0] == '0' && (string[1] == 'X' || string[1] == 'x')) + { + /* hexadecimal */ + *result = wcstoul( string + 2, (WCHAR**)&string, 16 ); + if (*string == '-') + string++; + *end = string; + return TRUE; + } + else if (iswdigit(string[0]) || string[0] == '-') + { + *result = wcstoul( string, (WCHAR**)&string, 10 ); + if (*string == '-') + string++; + *end = string; + return TRUE; + } + + *result = 0; + *end = string; + return FALSE; +} + static DWORD get_sid_size( const WCHAR *string, const WCHAR **end ) { if ((string[0] == 'S' || string[0] == 's') && string[1] == '-') /* S-R-I(-S)+ */ { int token_count = 0; - string++; - while (*string == '-' || iswdigit(*string)) - { - if (*string == '-') - token_count++; - string++; - } + DWORD value; + + string += 2; + + while (parse_token( string, &string, &value )) + token_count++;
if (end) *end = string; @@ -653,9 +677,11 @@ static BOOL parse_sid( const WCHAR *string, const WCHAR **end, SID *pisid, DWORD { DWORD i = 0, identAuth; DWORD csubauth = ((*size - GetSidLengthRequired(0)) / sizeof(DWORD)); + DWORD token;
string += 2; /* Advance to Revision */ - pisid->Revision = wcstoul( string, (WCHAR**)&string, 10 ); + parse_token( string, &string, &token ); + pisid->Revision = token;
if (pisid->Revision != SDDL_REVISION) { @@ -672,31 +698,20 @@ static BOOL parse_sid( const WCHAR *string, const WCHAR **end, SID *pisid, DWORD
pisid->SubAuthorityCount = csubauth;
- /* Advance to identifier authority */ - if (*string == '-') - string++; - /* MS' implementation can't handle values greater than 2^32 - 1, so * we don't either; assume most significant bytes are always 0 */ pisid->IdentifierAuthority.Value[0] = 0; pisid->IdentifierAuthority.Value[1] = 0; - identAuth = wcstoul( string, (WCHAR**)&string, 10 ); + parse_token( string, &string, &identAuth ); pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
- /* Advance to first sub authority */ - if (*string == '-') - string++; - - while (iswdigit(*string) || *string == '-') + while (parse_token( string, &string, &token )) { - pisid->SubAuthority[i++] = wcstoul( string, (WCHAR**)&string, 10 ); - - if (*string == '-') - string++; + pisid->SubAuthority[i++] = token; }
if (i != pisid->SubAuthorityCount)