imap: use a dynbuf in imap_atom

Avoid a calculation + malloc. Build the output in a dynbuf.

Closes #11672
This commit is contained in:
Daniel Stenberg 2023-08-14 11:41:03 +02:00
parent 67e9e3cb1e
commit de5f66595e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -1803,79 +1803,37 @@ static CURLcode imap_sendf(struct Curl_easy *data, const char *fmt, ...)
*/
static char *imap_atom(const char *str, bool escape_only)
{
/* !checksrc! disable PARENBRACE 1 */
const char atom_specials[] = "(){ %*]";
const char *p1;
char *p2;
size_t backsp_count = 0;
size_t quote_count = 0;
bool others_exists = FALSE;
size_t newlen = 0;
char *newstr = NULL;
struct dynbuf line;
size_t nclean;
size_t len;
if(!str)
return NULL;
/* Look for "atom-specials", counting the backslash and quote characters as
these will need escaping */
p1 = str;
while(*p1) {
if(*p1 == '\\')
backsp_count++;
else if(*p1 == '"')
quote_count++;
else if(!escape_only) {
const char *p3 = atom_specials;
while(*p3 && !others_exists) {
if(*p1 == *p3)
others_exists = TRUE;
p3++;
}
}
p1++;
}
/* Does the input contain any "atom-special" characters? */
if(!backsp_count && !quote_count && !others_exists)
len = strlen(str);
nclean = strcspn(str, "() {%*]\\\"");
if(len == nclean)
/* nothing to escape, return a strdup */
return strdup(str);
/* Calculate the new string length */
newlen = strlen(str) + backsp_count + quote_count + (escape_only ? 0 : 2);
Curl_dyn_init(&line, 2000);
/* Allocate the new string */
newstr = (char *) malloc((newlen + 1) * sizeof(char));
if(!newstr)
if(!escape_only && Curl_dyn_addn(&line, "\"", 1))
return NULL;
/* Surround the string in quotes if necessary */
p2 = newstr;
if(!escape_only) {
newstr[0] = '"';
newstr[newlen - 1] = '"';
p2++;
while(*str) {
if((*str == '\\' || *str == '"') &&
Curl_dyn_addn(&line, "\\", 1))
return NULL;
if(Curl_dyn_addn(&line, str, 1))
return NULL;
str++;
}
/* Copy the string, escaping backslash and quote characters along the way */
p1 = str;
while(*p1) {
if(*p1 == '\\' || *p1 == '"') {
*p2 = '\\';
p2++;
}
if(!escape_only && Curl_dyn_addn(&line, "\"", 1))
return NULL;
*p2 = *p1;
p1++;
p2++;
}
/* Terminate the string */
newstr[newlen] = '\0';
return newstr;
return Curl_dyn_ptr(&line);
}
/***********************************************************************