[winpr,string] add uriparse as optional
This commit is contained in:
parent
8be124b4a2
commit
8dedcc9068
@ -103,6 +103,13 @@ endmacro()
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES rt)
|
||||
|
||||
option(WITH_URIPARSER "use uriparser library to handle URIs" OFF)
|
||||
if (WITH_URIPARSER)
|
||||
find_package(uriparser CONFIG REQUIRED char)
|
||||
add_definitions("-DWITH_URIPARSER")
|
||||
winpr_library_add_private(uriparser::uriparser)
|
||||
endif()
|
||||
|
||||
if(NOT IOS)
|
||||
check_function_exists(timer_create TIMER_CREATE)
|
||||
check_function_exists(timer_delete TIMER_DELETE)
|
||||
|
@ -134,83 +134,6 @@ void free_synthetic_file(struct synthetic_file* file)
|
||||
free(file);
|
||||
}
|
||||
|
||||
static unsigned char hex_to_dec(char c, BOOL* valid)
|
||||
{
|
||||
WINPR_ASSERT(valid);
|
||||
|
||||
if (('0' <= c) && (c <= '9'))
|
||||
return (c - '0');
|
||||
|
||||
if (('a' <= c) && (c <= 'f'))
|
||||
return (c - 'a') + 10;
|
||||
|
||||
if (('A' <= c) && (c <= 'F'))
|
||||
return (c - 'A') + 10;
|
||||
|
||||
*valid = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL decode_percent_encoded_byte(const char* str, const char* end, char* value)
|
||||
{
|
||||
BOOL valid = TRUE;
|
||||
|
||||
WINPR_ASSERT(str);
|
||||
WINPR_ASSERT(end);
|
||||
WINPR_ASSERT(value);
|
||||
|
||||
if ((end < str) || ((size_t)(end - str) < strlen("%20")))
|
||||
return FALSE;
|
||||
|
||||
*value = 0;
|
||||
*value |= hex_to_dec(str[1], &valid);
|
||||
*value <<= 4;
|
||||
*value |= hex_to_dec(str[2], &valid);
|
||||
return valid;
|
||||
}
|
||||
|
||||
static char* decode_percent_encoded_string(const char* str, size_t len)
|
||||
{
|
||||
char* buffer = NULL;
|
||||
char* next = NULL;
|
||||
const char* cur = str;
|
||||
const char* lim = str + len;
|
||||
|
||||
WINPR_ASSERT(str);
|
||||
|
||||
/* Percent decoding shrinks data length, so len bytes will be enough. */
|
||||
buffer = calloc(len + 1, sizeof(char));
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
next = buffer;
|
||||
|
||||
while (cur < lim)
|
||||
{
|
||||
if (*cur != '%')
|
||||
{
|
||||
*next++ = *cur++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!decode_percent_encoded_byte(cur, lim, next))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid percent encoding");
|
||||
goto error;
|
||||
}
|
||||
|
||||
cur += strlen("%20");
|
||||
next += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
error:
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the function converts a single file name component,
|
||||
* it does not take care of component separators.
|
||||
@ -457,16 +380,10 @@ static BOOL process_uri(wClipboard* clipboard, const char* uri, size_t uri_len)
|
||||
// URI is specified by RFC 8089: https://datatracker.ietf.org/doc/html/rfc8089
|
||||
BOOL result = FALSE;
|
||||
char* name = NULL;
|
||||
char* localName = NULL;
|
||||
|
||||
WINPR_ASSERT(clipboard);
|
||||
|
||||
localName = parse_uri_to_local_file(uri, uri_len);
|
||||
if (localName)
|
||||
{
|
||||
name = decode_percent_encoded_string(localName, strlen(localName));
|
||||
free(localName);
|
||||
}
|
||||
name = parse_uri_to_local_file(uri, uri_len);
|
||||
if (name)
|
||||
{
|
||||
WCHAR* wname = NULL;
|
||||
|
@ -30,6 +30,10 @@
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/endian.h>
|
||||
|
||||
#if defined(WITH_URIPARSER)
|
||||
#include <uriparser/Uri.h>
|
||||
#endif
|
||||
|
||||
/* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
|
||||
|
||||
#include "../log.h"
|
||||
@ -39,6 +43,37 @@
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#if defined(WITH_URIPARSER)
|
||||
char* winpr_str_url_decode(const char* str, size_t len)
|
||||
{
|
||||
char* dst = strndup(str, len);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
if (!uriUnescapeInPlaceExA(dst, URI_FALSE, URI_FALSE))
|
||||
{
|
||||
free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
char* winpr_str_url_encode(const char* str, size_t len)
|
||||
{
|
||||
char* dst = calloc(len + 1, sizeof(char) * 3);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
if (!uriEscapeA(str, dst, URI_FALSE, URI_FALSE))
|
||||
{
|
||||
free(dst);
|
||||
return NULL;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
#else
|
||||
static const char rfc3986[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -77,9 +112,6 @@ static char unescape(const char* what, size_t* px)
|
||||
return 16 * hex2bin(what[1]) + hex2bin(what[2]);
|
||||
}
|
||||
|
||||
if (*what == '+')
|
||||
return ' ';
|
||||
|
||||
return *what;
|
||||
}
|
||||
|
||||
@ -124,6 +156,7 @@ char* winpr_str_url_encode(const char* str, size_t len)
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL winpr_str_append(const char* what, char* buffer, size_t size, const char* separator)
|
||||
{
|
||||
|
@ -38,7 +38,8 @@ static const struct url_test_pair url_tests[] = {
|
||||
"xxx%25bar%20ga%3Cka%3Eee%23%25%25%23%25%7Bh%7Dg%7Bf%7Be%25d%7Cc%5Cb%5Ea~p%5Bq%5Dr%60s%3Bt%"
|
||||
"2Fu%3Fv%3Aw%40x%3Dy%26z%24xxx" },
|
||||
{ "äöúëü", "%C3%A4%C3%B6%C3%BA%C3%AB%C3%BC" },
|
||||
{ "🎅🏄🤘😈", "%F0%9F%8E%85%F0%9F%8F%84%F0%9F%A4%98%F0%9F%98%88" }
|
||||
{ "🎅🏄🤘😈", "%F0%9F%8E%85%F0%9F%8F%84%F0%9F%A4%98%F0%9F%98%88" },
|
||||
{ "foo$.%.^.&.\\.txt+", "foo%24.%25.%5E.%26.%5C.txt%2B" }
|
||||
};
|
||||
|
||||
static BOOL test_url_escape(void)
|
||||
|
Loading…
Reference in New Issue
Block a user