From bf2ab8f06ee5e13515251c3d0e8d8ce898a5d70f Mon Sep 17 00:00:00 2001 From: EyitopeIO Date: Wed, 17 Apr 2024 01:58:18 +0100 Subject: [PATCH] fix: Mount URL with spaces --- src/link.c | 4 +++- src/util.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 17 +++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/link.c b/src/link.c index 0119f7a..71a2bb1 100644 --- a/src/link.c +++ b/src/link.c @@ -77,7 +77,9 @@ static CURL *Link_to_curl(Link *link) if (ret) { lprintf(error, "%s", curl_easy_strerror(ret)); } - ret = curl_easy_setopt(curl, CURLOPT_URL, link->f_url); + char *escaped_spaces = escape_char(link->f_url, ESCAPED_CHAR_SPACE); + ret = curl_easy_setopt(curl, CURLOPT_URL, + escaped_spaces ? escaped_spaces : link->f_url); if (ret) { lprintf(error, "%s", curl_easy_strerror(ret)); } diff --git a/src/util.c b/src/util.c index 1e868f6..1d81410 100644 --- a/src/util.c +++ b/src/util.c @@ -49,6 +49,57 @@ char *path_append(const char *path, const char *filename) return str; } +char *escape_char(const char *url, const ESCAPE_CHAR c) +{ + static char escaped[MAX_PATH_LEN]; + char escape_me; + + /* A space, for example, becomes thrice bigger as '%20' after escaping */ + int how_bigger = 3; + + switch (c) { + case ESCAPED_CHAR_SPACE: + escape_me = ' '; + break; + default: + lprintf(error, "unknown character to escape: %d\n", c); + return NULL; + } + + if (!strchr(url, escape_me)) { + return NULL; + } + + int len = strnlen(url, MAX_PATH_LEN); + + /* Best case scenario of only one character to escape */ + if (strnlen(url,MAX_PATH_LEN) + 3 > MAX_PATH_LEN) { + lprintf(fatal, "URL too long: %s\n", url); + } + + memset(escaped, 0, MAX_PATH_LEN); + + int j = 0; + for (int i = 0; i < len; i++) { + if (url[i] == escape_me) { + switch (c) { + case ESCAPED_CHAR_SPACE: + strncpy(escaped + j, "%20", how_bigger); + break; + } + + j += how_bigger; + + } else { + escaped[j++] = url[i]; + } + } + + escaped[j] = '\0'; + return escaped; +} + + int64_t round_div(int64_t a, int64_t b) { return (a + (b / 2)) / b; diff --git a/src/util.h b/src/util.h index 5010de4..c07065a 100644 --- a/src/util.h +++ b/src/util.h @@ -9,6 +9,13 @@ #include #include +/** + * \brief URL characters that can be escaped + */ +typedef enum { + ESCAPED_CHAR_SPACE, +} ESCAPE_CHAR; + /** * \brief append a path * \details This function appends a path with the next level, while taking the @@ -17,6 +24,16 @@ */ char *path_append(const char *path, const char *filename); +/** + * \brief escape a single character in a URL + * \details This function escapes a character a URL and returns a pointer to + * the string with the escaped character. We don't use curl_easy_escape() on + * the entire URL because it would break the URL. For example, 'http://a c' + * becomes 'http:%2F%2Fa%20c', escaping more characters than we want. + * \note DO NOT free the char * after use. It is statically allocated. + */ +char *escape_char(const char *s, ESCAPE_CHAR c); + /** * \brief division, but rounded to the nearest integer rather than truncating */