From: Zhiyi Zhang <zzhang@codeweavers.com> --- dlls/iertutil/iertutil.spec | 1 + dlls/iertutil/uri.c | 139 +++++++++++++++++++++++++++++++++ dlls/urlmon/uri.c | 148 ------------------------------------ dlls/urlmon/urlmon.spec | 2 +- 4 files changed, 141 insertions(+), 149 deletions(-) diff --git a/dlls/iertutil/iertutil.spec b/dlls/iertutil/iertutil.spec index 9bf928370d2..3e92b413099 100644 --- a/dlls/iertutil/iertutil.spec +++ b/dlls/iertutil/iertutil.spec @@ -1,4 +1,5 @@ @ stdcall CreateIUriBuilder(ptr long long ptr) +@ stdcall CreateUri(wstr long long ptr) @ stdcall -private DllCanUnloadNow() @ stdcall -private DllGetActivationFactory(ptr ptr) @ stdcall -private DllGetClassObject(ptr ptr ptr) diff --git a/dlls/iertutil/uri.c b/dlls/iertutil/uri.c index 3b7ac6233fb..8a5af3537b9 100644 --- a/dlls/iertutil/uri.c +++ b/dlls/iertutil/uri.c @@ -671,6 +671,45 @@ static INT find_file_extension(const WCHAR *path, DWORD path_len) { return -1; } +/* Removes all the leading and trailing white spaces or + * control characters from the URI and removes all control + * characters inside of the URI string. + */ +static BSTR pre_process_uri(LPCWSTR uri) { + const WCHAR *start, *end, *ptr; + WCHAR *ptr2; + DWORD len; + BSTR ret; + + start = uri; + /* Skip leading controls and whitespace. */ + while(*start && (iswcntrl(*start) || iswspace(*start))) ++start; + + /* URI consisted only of control/whitespace. */ + if(!*start) + return SysAllocStringLen(NULL, 0); + + end = start + lstrlenW(start); + while(--end > start && (iswcntrl(*end) || iswspace(*end))); + + len = ++end - start; + for(ptr = start; ptr < end; ptr++) { + if(iswcntrl(*ptr)) + len--; + } + + ret = SysAllocStringLen(NULL, len); + if(!ret) + return NULL; + + for(ptr = start, ptr2=ret; ptr < end; ptr++) { + if(!iswcntrl(*ptr)) + *ptr2++ = *ptr; + } + + return ret; +} + /* Converts an IPv4 address in numerical form into its fully qualified * string form. This function returns the number of characters written * to 'dest'. If 'dest' is NULL this function will return the number of @@ -5328,6 +5367,106 @@ HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) return S_OK; } +/*********************************************************************** + * CreateUri (iertutil.@) + * + * Creates a new IUri object using the URI represented by pwzURI. This function + * parses and validates the components of pwzURI and then canonicalizes the + * parsed components. + * + * PARAMS + * pwzURI [I] The URI to parse, validate, and canonicalize. + * dwFlags [I] Flags which can affect how the parsing/canonicalization is performed. + * dwReserved [I] Reserved (not used). + * ppURI [O] The resulting IUri after parsing/canonicalization occurs. + * + * RETURNS + * Success: Returns S_OK. ppURI contains the pointer to the newly allocated IUri. + * Failure: E_INVALIDARG if there are invalid flag combinations in dwFlags, or an + * invalid parameter, or pwzURI doesn't represent a valid URI. + * E_OUTOFMEMORY if any memory allocation fails. + * + * NOTES + * Default flags: + * Uri_CREATE_CANONICALIZE, Uri_CREATE_DECODE_EXTRA_INFO, Uri_CREATE_CRACK_UNKNOWN_SCHEMES, + * Uri_CREATE_PRE_PROCESS_HTML_URI, Uri_CREATE_NO_IE_SETTINGS. + */ +HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI) +{ + const DWORD supported_flags = Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME| + Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|Uri_CREATE_NO_CANONICALIZE|Uri_CREATE_CANONICALIZE| + Uri_CREATE_DECODE_EXTRA_INFO|Uri_CREATE_NO_DECODE_EXTRA_INFO|Uri_CREATE_CRACK_UNKNOWN_SCHEMES| + Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES|Uri_CREATE_PRE_PROCESS_HTML_URI|Uri_CREATE_NO_PRE_PROCESS_HTML_URI| + Uri_CREATE_NO_IE_SETTINGS|Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS|Uri_CREATE_FILE_USE_DOS_PATH; + Uri *ret; + HRESULT hr; + parse_data data; + + TRACE("(%s %lx %Ix %p)\n", debugstr_w(pwzURI), dwFlags, dwReserved, ppURI); + + if(!ppURI) + return E_INVALIDARG; + + if(!pwzURI) { + *ppURI = NULL; + return E_INVALIDARG; + } + + /* Check for invalid flags. */ + if(has_invalid_flag_combination(dwFlags)) { + *ppURI = NULL; + return E_INVALIDARG; + } + + /* Currently unsupported. */ + if(dwFlags & ~supported_flags) + FIXME("Ignoring unsupported flag(s) %lx\n", dwFlags & ~supported_flags); + + hr = Uri_Construct(NULL, (void**)&ret); + if(FAILED(hr)) { + *ppURI = NULL; + return hr; + } + + /* Explicitly set the default flags if it doesn't cause a flag conflict. */ + apply_default_flags(&dwFlags); + + /* Pre process the URI, unless told otherwise. */ + if(!(dwFlags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI)) + ret->raw_uri = pre_process_uri(pwzURI); + else + ret->raw_uri = SysAllocString(pwzURI); + + if(!ret->raw_uri) { + free(ret); + return E_OUTOFMEMORY; + } + + memset(&data, 0, sizeof(parse_data)); + data.uri = ret->raw_uri; + + /* Validate and parse the URI into its components. */ + if(!parse_uri(&data, dwFlags)) { + /* Encountered an unsupported or invalid URI */ + IUri_Release(&ret->IUri_iface); + *ppURI = NULL; + return E_INVALIDARG; + } + + /* Canonicalize the URI. */ + hr = canonicalize_uri(&data, ret, dwFlags); + if(FAILED(hr)) { + IUri_Release(&ret->IUri_iface); + *ppURI = NULL; + return hr; + } + + ret->create_flags = dwFlags; + + *ppURI = &ret->IUri_iface; + return S_OK; +} + static HRESULT build_uri(const UriBuilder *builder, IUri **uri, DWORD create_flags, DWORD use_orig_flags, DWORD encoding_mask) { diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c index 498e2e57ae4..62773d3183d 100644 --- a/dlls/urlmon/uri.c +++ b/dlls/urlmon/uri.c @@ -365,15 +365,6 @@ static inline BOOL is_hierarchical_scheme(URL_SCHEME type) { type == URL_SCHEME_RES); } -/* Checks if 'flags' contains an invalid combination of Uri_CREATE flags. */ -static inline BOOL has_invalid_flag_combination(DWORD flags) { - return((flags & Uri_CREATE_DECODE_EXTRA_INFO && flags & Uri_CREATE_NO_DECODE_EXTRA_INFO) || - (flags & Uri_CREATE_CANONICALIZE && flags & Uri_CREATE_NO_CANONICALIZE) || - (flags & Uri_CREATE_CRACK_UNKNOWN_SCHEMES && flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES) || - (flags & Uri_CREATE_PRE_PROCESS_HTML_URI && flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI) || - (flags & Uri_CREATE_IE_SETTINGS && flags & Uri_CREATE_NO_IE_SETTINGS)); -} - /* Applies each default Uri_CREATE flags to 'flags' if it * doesn't cause a flag conflict. */ @@ -659,45 +650,6 @@ static INT find_file_extension(const WCHAR *path, DWORD path_len) { return -1; } -/* Removes all the leading and trailing white spaces or - * control characters from the URI and removes all control - * characters inside of the URI string. - */ -static BSTR pre_process_uri(LPCWSTR uri) { - const WCHAR *start, *end, *ptr; - WCHAR *ptr2; - DWORD len; - BSTR ret; - - start = uri; - /* Skip leading controls and whitespace. */ - while(*start && (iswcntrl(*start) || iswspace(*start))) ++start; - - /* URI consisted only of control/whitespace. */ - if(!*start) - return SysAllocStringLen(NULL, 0); - - end = start + lstrlenW(start); - while(--end > start && (iswcntrl(*end) || iswspace(*end))); - - len = ++end - start; - for(ptr = start; ptr < end; ptr++) { - if(iswcntrl(*ptr)) - len--; - } - - ret = SysAllocStringLen(NULL, len); - if(!ret) - return NULL; - - for(ptr = start, ptr2=ret; ptr < end; ptr++) { - if(!iswcntrl(*ptr)) - *ptr2++ = *ptr; - } - - return ret; -} - /* Converts an IPv4 address in numerical form into its fully qualified * string form. This function returns the number of characters written * to 'dest'. If 'dest' is NULL this function will return the number of @@ -4900,106 +4852,6 @@ HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) return S_OK; } -/*********************************************************************** - * CreateUri (urlmon.@) - * - * Creates a new IUri object using the URI represented by pwzURI. This function - * parses and validates the components of pwzURI and then canonicalizes the - * parsed components. - * - * PARAMS - * pwzURI [I] The URI to parse, validate, and canonicalize. - * dwFlags [I] Flags which can affect how the parsing/canonicalization is performed. - * dwReserved [I] Reserved (not used). - * ppURI [O] The resulting IUri after parsing/canonicalization occurs. - * - * RETURNS - * Success: Returns S_OK. ppURI contains the pointer to the newly allocated IUri. - * Failure: E_INVALIDARG if there are invalid flag combinations in dwFlags, or an - * invalid parameter, or pwzURI doesn't represent a valid URI. - * E_OUTOFMEMORY if any memory allocation fails. - * - * NOTES - * Default flags: - * Uri_CREATE_CANONICALIZE, Uri_CREATE_DECODE_EXTRA_INFO, Uri_CREATE_CRACK_UNKNOWN_SCHEMES, - * Uri_CREATE_PRE_PROCESS_HTML_URI, Uri_CREATE_NO_IE_SETTINGS. - */ -HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI) -{ - const DWORD supported_flags = Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME| - Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|Uri_CREATE_NO_CANONICALIZE|Uri_CREATE_CANONICALIZE| - Uri_CREATE_DECODE_EXTRA_INFO|Uri_CREATE_NO_DECODE_EXTRA_INFO|Uri_CREATE_CRACK_UNKNOWN_SCHEMES| - Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES|Uri_CREATE_PRE_PROCESS_HTML_URI|Uri_CREATE_NO_PRE_PROCESS_HTML_URI| - Uri_CREATE_NO_IE_SETTINGS|Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS|Uri_CREATE_FILE_USE_DOS_PATH; - Uri *ret; - HRESULT hr; - parse_data data; - - TRACE("(%s %lx %Ix %p)\n", debugstr_w(pwzURI), dwFlags, dwReserved, ppURI); - - if(!ppURI) - return E_INVALIDARG; - - if(!pwzURI) { - *ppURI = NULL; - return E_INVALIDARG; - } - - /* Check for invalid flags. */ - if(has_invalid_flag_combination(dwFlags)) { - *ppURI = NULL; - return E_INVALIDARG; - } - - /* Currently unsupported. */ - if(dwFlags & ~supported_flags) - FIXME("Ignoring unsupported flag(s) %lx\n", dwFlags & ~supported_flags); - - hr = Uri_Construct(NULL, (void**)&ret); - if(FAILED(hr)) { - *ppURI = NULL; - return hr; - } - - /* Explicitly set the default flags if it doesn't cause a flag conflict. */ - apply_default_flags(&dwFlags); - - /* Pre process the URI, unless told otherwise. */ - if(!(dwFlags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI)) - ret->raw_uri = pre_process_uri(pwzURI); - else - ret->raw_uri = SysAllocString(pwzURI); - - if(!ret->raw_uri) { - free(ret); - return E_OUTOFMEMORY; - } - - memset(&data, 0, sizeof(parse_data)); - data.uri = ret->raw_uri; - - /* Validate and parse the URI into its components. */ - if(!parse_uri(&data, dwFlags)) { - /* Encountered an unsupported or invalid URI */ - IUri_Release(&ret->IUri_iface); - *ppURI = NULL; - return E_INVALIDARG; - } - - /* Canonicalize the URI. */ - hr = canonicalize_uri(&data, ret, dwFlags); - if(FAILED(hr)) { - IUri_Release(&ret->IUri_iface); - *ppURI = NULL; - return hr; - } - - ret->create_flags = dwFlags; - - *ppURI = &ret->IUri_iface; - return S_OK; -} - /*********************************************************************** * CreateUriWithFragment (urlmon.@) * diff --git a/dlls/urlmon/urlmon.spec b/dlls/urlmon/urlmon.spec index 6a5ef515b44..d975cbb9746 100644 --- a/dlls/urlmon/urlmon.spec +++ b/dlls/urlmon/urlmon.spec @@ -34,7 +34,7 @@ @ stdcall CreateAsyncBindCtxEx(ptr long ptr ptr ptr long) @ stdcall CreateFormatEnumerator(long ptr ptr) @ stdcall CreateIUriBuilder(ptr long long ptr) iertutil.CreateIUriBuilder -@ stdcall CreateUri(wstr long long ptr) +@ stdcall CreateUri(wstr long long ptr) iertutil.CreateUri @ stdcall CreateUriWithFragment(wstr wstr long long ptr) @ stdcall CreateURLMoniker(ptr wstr ptr) @ stdcall CreateURLMonikerEx(ptr wstr ptr long) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9131