Thomas Mullaly : urlmon: Implemented validation for the userinfo component when create an IUri with IUriBuilder .
Alexandre Julliard
julliard at winehq.org
Mon Sep 20 12:12:19 CDT 2010
Module: wine
Branch: master
Commit: e48b81036aa36e91458e68745608de48650e8b8e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e48b81036aa36e91458e68745608de48650e8b8e
Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date: Sat Sep 18 17:10:33 2010 -0400
urlmon: Implemented validation for the userinfo component when create an IUri with IUriBuilder.
---
dlls/urlmon/tests/uri.c | 84 ++++++++++++++++++++++++++++++++++++
dlls/urlmon/uri.c | 108 +++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 185 insertions(+), 7 deletions(-)
diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index 617486f..3bbb578 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -5124,6 +5124,90 @@ static const uri_builder_test uri_builder_tests[] = {
0,INET_E_INVALID_URL,FALSE,
0,INET_E_INVALID_URL,FALSE,
0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ /* UserName can't contain any character that is a delimeter for another
+ * component that appears after it in a normal URI.
+ */
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"user:pass",NULL,Uri_PROPERTY_USER_NAME,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"user at google.com",NULL,Uri_PROPERTY_USER_NAME,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"user/path",NULL,Uri_PROPERTY_USER_NAME,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"user?Query",NULL,Uri_PROPERTY_USER_NAME,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"user#Frag",NULL,Uri_PROPERTY_USER_NAME,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"pass at google.com",NULL,Uri_PROPERTY_PASSWORD,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"pass/path",NULL,Uri_PROPERTY_PASSWORD,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"pass?query",NULL,Uri_PROPERTY_PASSWORD,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
+ },
+ { "http://google.com/",0,S_OK,FALSE,
+ {
+ {TRUE,"pass#frag",NULL,Uri_PROPERTY_PASSWORD,S_OK,FALSE}
+ },
+ {FALSE},
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,INET_E_INVALID_URL,FALSE,
+ 0,0,0,INET_E_INVALID_URL,FALSE
}
};
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index f46cbfb..eaf8c83 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -26,7 +26,9 @@
#define UINT_MAX 0xffffffff
#define USHORT_MAX 0xffff
-#define ALLOW_NULL_TERM_SCHEME 0x1
+#define ALLOW_NULL_TERM_SCHEME 0x1
+#define ALLOW_NULL_TERM_USER_NAME 0x2
+#define ALLOW_NULL_TERM_PASSWORD 0x4
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@@ -1281,7 +1283,7 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD
return TRUE;
}
-static BOOL parse_username(const WCHAR **ptr, parse_data *data, DWORD flags) {
+static BOOL parse_username(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
data->username = *ptr;
while(**ptr != ':' && **ptr != '@') {
@@ -1294,7 +1296,9 @@ static BOOL parse_username(const WCHAR **ptr, parse_data *data, DWORD flags) {
}
} else
continue;
- } else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
+ } else if(extras & ALLOW_NULL_TERM_USER_NAME && !**ptr)
+ break;
+ else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
*ptr = data->username;
data->username = NULL;
return FALSE;
@@ -1307,7 +1311,7 @@ static BOOL parse_username(const WCHAR **ptr, parse_data *data, DWORD flags) {
return TRUE;
}
-static BOOL parse_password(const WCHAR **ptr, parse_data *data, DWORD flags) {
+static BOOL parse_password(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
const WCHAR *start = *ptr;
if(**ptr != ':')
@@ -1326,7 +1330,9 @@ static BOOL parse_password(const WCHAR **ptr, parse_data *data, DWORD flags) {
}
} else
continue;
- } else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
+ } else if(extras & ALLOW_NULL_TERM_PASSWORD && !**ptr)
+ break;
+ else if(is_auth_delim(**ptr, data->scheme_type != URL_SCHEME_UNKNOWN)) {
*ptr = start;
data->password = NULL;
return FALSE;
@@ -1361,12 +1367,12 @@ static BOOL parse_password(const WCHAR **ptr, parse_data *data, DWORD flags) {
static void parse_userinfo(const WCHAR **ptr, parse_data *data, DWORD flags) {
const WCHAR *start = *ptr;
- if(!parse_username(ptr, data, flags)) {
+ if(!parse_username(ptr, data, flags, 0)) {
TRACE("(%p %p %x): URI contained no userinfo.\n", ptr, data, flags);
return;
}
- if(!parse_password(ptr, data, flags)) {
+ if(!parse_password(ptr, data, flags, 0)) {
*ptr = start;
data->username = NULL;
data->username_len = 0;
@@ -3561,6 +3567,90 @@ static HRESULT validate_scheme_name(const UriBuilder *builder, parse_data *data,
return S_OK;
}
+static HRESULT validate_username(const UriBuilder *builder, parse_data *data, DWORD flags) {
+ const WCHAR *ptr;
+ const WCHAR **pptr;
+ DWORD expected_len;
+
+ if(builder->username) {
+ ptr = builder->username;
+ expected_len = builder->username_len;
+ } else if(!(builder->modified_props & Uri_HAS_USER_NAME) && builder->uri &&
+ builder->uri->userinfo_start > -1 && builder->uri->userinfo_split != 0) {
+ /* Just use the username from the base Uri. */
+ data->username = builder->uri->canon_uri+builder->uri->userinfo_start;
+ data->username_len = (builder->uri->userinfo_split > -1) ?
+ builder->uri->userinfo_split : builder->uri->userinfo_len;
+ ptr = NULL;
+ } else {
+ ptr = NULL;
+ expected_len = 0;
+ }
+
+ if(ptr) {
+ pptr = &ptr;
+ if(parse_username(pptr, data, flags, ALLOW_NULL_TERM_USER_NAME) &&
+ data->username_len == expected_len)
+ TRACE("(%p %p %x): Found valid username component %s.\n", builder, data, flags,
+ debugstr_wn(data->username, data->username_len));
+ else {
+ TRACE("(%p %p %x): Invalid username component found %s.\n", builder, data, flags,
+ debugstr_wn(ptr, expected_len));
+ return INET_E_INVALID_URL;
+ }
+ }
+
+ return S_OK;
+}
+
+static HRESULT validate_password(const UriBuilder *builder, parse_data *data, DWORD flags) {
+ const WCHAR *ptr;
+ const WCHAR **pptr;
+ DWORD expected_len;
+
+ if(builder->password) {
+ ptr = builder->password;
+ expected_len = builder->password_len;
+ } else if(!(builder->modified_props & Uri_HAS_PASSWORD) && builder->uri &&
+ builder->uri->userinfo_split > -1) {
+ data->password = builder->uri->canon_uri+builder->uri->userinfo_start+builder->uri->userinfo_split+1;
+ data->password_len = builder->uri->userinfo_len-builder->uri->userinfo_split-1;
+ ptr = NULL;
+ } else {
+ ptr = NULL;
+ expected_len = 0;
+ }
+
+ if(ptr) {
+ pptr = &ptr;
+ if(parse_password(pptr, data, flags, ALLOW_NULL_TERM_PASSWORD) &&
+ data->password_len == expected_len)
+ TRACE("(%p %p %x): Found valid password component %s.\n", builder, data, flags,
+ debugstr_wn(data->password, data->password_len));
+ else {
+ TRACE("(%p %p %x): Invalid password component found %s.\n", builder, data, flags,
+ debugstr_wn(ptr, expected_len));
+ return INET_E_INVALID_URL;
+ }
+ }
+
+ return S_OK;
+}
+
+static HRESULT validate_userinfo(const UriBuilder *builder, parse_data *data, DWORD flags) {
+ HRESULT hr;
+
+ hr = validate_username(builder, data, flags);
+ if(FAILED(hr))
+ return hr;
+
+ hr = validate_password(builder, data, flags);
+ if(FAILED(hr))
+ return hr;
+
+ return S_OK;
+}
+
static HRESULT validate_components(const UriBuilder *builder, parse_data *data, DWORD flags) {
HRESULT hr;
@@ -3582,6 +3672,10 @@ static HRESULT validate_components(const UriBuilder *builder, parse_data *data,
}
}
+ hr = validate_userinfo(builder, data, flags);
+ if(FAILED(hr))
+ return hr;
+
return E_NOTIMPL;
}
More information about the wine-cvs
mailing list