diff options
author | Daniel Stenberg <daniel@haxx.se> | 2023-01-28 22:05:11 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2023-01-29 16:03:40 +0100 |
commit | 0c3d54269ec0de0364fb09e9f3a38622a8120ece (patch) | |
tree | 67b44ade0787137a51623ea034a61192c6894b3e /lib/dict.c | |
parent | 22d3e89e6f087053a9e525e45b121f93fc1f5407 (diff) | |
download | curl-0c3d54269ec0de0364fb09e9f3a38622a8120ece.tar.gz |
dict: URL decode the entire path always
Reported-by: dekerser on github
Fixes #10298
Closes #10354
Diffstat (limited to 'lib/dict.c')
-rw-r--r-- | lib/dict.c | 86 |
1 files changed, 42 insertions, 44 deletions
diff --git a/lib/dict.c b/lib/dict.c index 3cdd966b6..0ce62a00e 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -98,37 +98,27 @@ const struct Curl_handler Curl_handler_dict = { PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ }; -static char *unescape_word(const char *inputbuff) +#define DYN_DICT_WORD 10000 +static char *unescape_word(const char *input) { - char *newp = NULL; - char *dictp; - size_t len; - - CURLcode result = Curl_urldecode(inputbuff, 0, &newp, &len, - REJECT_NADA); - if(!newp || result) - return NULL; - - dictp = malloc(len*2 + 1); /* add one for terminating zero */ - if(dictp) { - char *ptr; - char ch; - int olen = 0; - /* According to RFC2229 section 2.2, these letters need to be escaped with - \[letter] */ - for(ptr = newp; - (ch = *ptr) != 0; - ptr++) { - if((ch <= 32) || (ch == 127) || - (ch == '\'') || (ch == '\"') || (ch == '\\')) { - dictp[olen++] = '\\'; - } - dictp[olen++] = ch; - } - dictp[olen] = 0; + struct dynbuf out; + const char *ptr; + CURLcode result = CURLE_OK; + Curl_dyn_init(&out, DYN_DICT_WORD); + + /* According to RFC2229 section 2.2, these letters need to be escaped with + \[letter] */ + for(ptr = input; *ptr; ptr++) { + char ch = *ptr; + if((ch <= 32) || (ch == 127) || + (ch == '\'') || (ch == '\"') || (ch == '\\')) + result = Curl_dyn_addn(&out, "\\", 1); + if(!result) + result = Curl_dyn_addn(&out, ptr, 1); + if(result) + return NULL; } - free(newp); - return dictp; + return Curl_dyn_ptr(&out); } /* sendf() sends formatted data to the server */ @@ -178,20 +168,25 @@ static CURLcode sendf(curl_socket_t sockfd, struct Curl_easy *data, static CURLcode dict_do(struct Curl_easy *data, bool *done) { char *word; - char *eword; + char *eword = NULL; char *ppath; char *database = NULL; char *strategy = NULL; char *nthdef = NULL; /* This is not part of the protocol, but required by RFC 2229 */ - CURLcode result = CURLE_OK; + CURLcode result; struct connectdata *conn = data->conn; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - char *path = data->state.up.path; + char *path; *done = TRUE; /* unconditionally */ + /* url-decode path before further evaluation */ + result = Curl_urldecode(data->state.up.path, 0, &path, NULL, REJECT_CTRL); + if(result) + return result; + if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { @@ -225,8 +220,10 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } eword = unescape_word(word); - if(!eword) - return CURLE_OUT_OF_MEMORY; + if(!eword) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } result = sendf(sockfd, data, "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" @@ -239,11 +236,9 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) strategy, eword); - free(eword); - if(result) { failf(data, "Failed sending DICT request"); - return result; + goto error; } Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */ } @@ -273,8 +268,10 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } eword = unescape_word(word); - if(!eword) - return CURLE_OUT_OF_MEMORY; + if(!eword) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } result = sendf(sockfd, data, "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" @@ -285,11 +282,9 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) database, eword); - free(eword); - if(result) { failf(data, "Failed sending DICT request"); - return result; + goto error; } Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } @@ -310,13 +305,16 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) "QUIT\r\n", ppath); if(result) { failf(data, "Failed sending DICT request"); - return result; + goto error; } Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } } - return CURLE_OK; + error: + free(eword); + free(path); + return result; } #endif /* CURL_DISABLE_DICT */ |