From 5d45e68f8feb9e7192cf689a763645e32b0b6dd8 Mon Sep 17 00:00:00 2001 From: EyitopeIO Date: Sat, 20 Apr 2024 01:39:23 +0100 Subject: [PATCH] fix: mount URL with spaces --- src/link.c | 7 ++++++- src/util.c | 39 +++++++++++++++++++++++++++++++++++++++ src/util.h | 8 ++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/link.c b/src/link.c index 0119f7a..9b6d1b2 100644 --- a/src/link.c +++ b/src/link.c @@ -77,10 +77,15 @@ 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_spaces(link->f_url); + ret = curl_easy_setopt(curl, CURLOPT_URL, + escaped_spaces ? escaped_spaces : link->f_url); if (ret) { lprintf(error, "%s", curl_easy_strerror(ret)); } + free(escaped_spaces); + ret = curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1); if (ret) { lprintf(error, "%s", curl_easy_strerror(ret)); diff --git a/src/util.c b/src/util.c index 1e868f6..0abdd96 100644 --- a/src/util.c +++ b/src/util.c @@ -49,6 +49,45 @@ char *path_append(const char *path, const char *filename) return str; } +char *escape_spaces(const char *path) +{ + if (!strchr(path, ' ')) { + return NULL; + } + + int len = strnlen(path, MAX_PATH_LEN); + /* Best case scenario of only one character to escape and + * [MAX_PATH_LEN - 1] is '\0' + */ + if (len + 3 >= MAX_PATH_LEN - 1) { + lprintf(fatal, "path too long: %s\n", path); + } + + int replacement_len = 3; + const char* replacement = "%20"; + + char *escaped = CALLOC(MAX_PATH_LEN, sizeof(char)); + + int j = 0; + for (int i = 0; i < len; i++) { + /* Precaution against writing beyond the buffer, since we do not count + * all spaces beforehand to know the exact amount of memory to calloc + * for the escaped path. + */ + if (j >= MAX_PATH_LEN - 1) { + lprintf(fatal, "path too long: %s\n", path); + } + if (path[i] == ' ') { + mempcpy(escaped + j, replacement, replacement_len); + j += replacement_len; + } else { + escaped[j++] = path[i]; + } + } + 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..892f9aa 100644 --- a/src/util.h +++ b/src/util.h @@ -17,6 +17,14 @@ */ char *path_append(const char *path, const char *filename); +/** + * \brief escapes the space character in a path/URL + * \details This function escapes the space character in a path, and + * returns a pointer to the escaped path. + * \note You need to free the char * after use. + */ +char *escape_spaces(const char *path); + /** * \brief division, but rounded to the nearest integer rather than truncating */