diff options
Diffstat (limited to 'lib/dict.c')
-rw-r--r-- | lib/dict.c | 88 |
1 files changed, 43 insertions, 45 deletions
@@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -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 */ |