This commit is contained in:
EyitopeIO 2024-04-18 01:42:21 +00:00 committed by GitHub
commit f701eab688
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 1 deletions

View File

@ -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_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));
}
free(escaped_spaces);
ret = curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
if (ret) {
lprintf(error, "%s", curl_easy_strerror(ret));

View File

@ -49,6 +49,61 @@ char *path_append(const char *path, const char *filename)
return str;
}
char *escape_char(const char *url, const ESCAPE_CHAR c)
{
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 (len + 3 > MAX_PATH_LEN) {
lprintf(fatal, "URL too long: %s\n", url);
}
char *escaped = CALLOC(MAX_PATH_LEN, sizeof(char));
int j = 0, k = 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 URL.
*/
if (k > MAX_PATH_LEN) {
lprintf(fatal, "URL too long: %s\n", url);
}
if (url[i] == escape_me) {
switch (c) {
case ESCAPED_CHAR_SPACE:
strncpy(escaped + j, "%20", how_bigger);
break;
}
k = j + how_bigger;
j = k;
} else {
escaped[j++] = url[i];
}
}
return escaped;
}
int64_t round_div(int64_t a, int64_t b)
{
return (a + (b / 2)) / b;

View File

@ -9,6 +9,13 @@
#include <stdint.h>
#include <stdio.h>
/**
* \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 You need to free the char * after use.
*/
char *escape_char(const char *s, ESCAPE_CHAR c);
/**
* \brief division, but rounded to the nearest integer rather than truncating
*/