From: Kevin McCarthy Date: Sun, 14 Apr 2019 20:34:37 +0000 (-0700) Subject: Convert rfc1524_expand_command() implementation to use BUFFER. X-Git-Tag: mutt-1-12-rel~63 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d6e373b73909e8723ad7b5835f54599f5041d89d;p=mutt Convert rfc1524_expand_command() implementation to use BUFFER. Add mutt_buffer_sanitize_filename() helper. Add a few end-of-buffer checks while iterating over command. Convert the parameter name, paramater value, and types to use BUFFER instead of fixed size strings. --- diff --git a/muttlib.c b/muttlib.c index e611bc98..8ab8785f 100644 --- a/muttlib.c +++ b/muttlib.c @@ -1027,6 +1027,24 @@ void mutt_buffer_quote_filename (BUFFER *d, const char *f) mutt_buffer_addch (d, '\''); } +static const char safe_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+@{}._-:%/"; + +void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash) +{ + mutt_buffer_clear (d); + + if (!f) + return; + + for (; *f; f++) + { + if ((slash && *f == '/') || !strchr (safe_chars, *f)) + mutt_buffer_addch (d, '_'); + else + mutt_buffer_addch (d, *f); + } +} + void mutt_expand_file_fmt (BUFFER *dest, const char *fmt, const char *src) { BUFFER *tmp; diff --git a/protos.h b/protos.h index b906e0cc..1fd25fb4 100644 --- a/protos.h +++ b/protos.h @@ -173,6 +173,7 @@ void mutt_break_thread (HEADER *); void mutt_browser_cleanup (void); void mutt_buffer_concat_path (BUFFER *, const char *, const char *); void mutt_buffer_quote_filename (BUFFER *, const char *); +void mutt_buffer_sanitize_filename (BUFFER *d, const char *f, short slash); void mutt_canonical_charset (char *, size_t, const char *); void mutt_check_stats(void); int mutt_count_body_parts (CONTEXT *, HEADER *); diff --git a/rfc1524.c b/rfc1524.c index e5b1b85d..a7ae9cd2 100644 --- a/rfc1524.c +++ b/rfc1524.c @@ -42,18 +42,6 @@ #include #include -int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const char *_type, - BUFFER *command) -{ - int rc; - - mutt_buffer_increase_size (command, LONG_STRING); - rc = rfc1524_expand_command (a, filename, _type, command->data, command->dsize); - mutt_buffer_fix_dptr (command); - - return rc; -} - /* The command semantics include the following: * %s is the filename that contains the mail body data * %t is the content type, like text/plain @@ -67,79 +55,94 @@ int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const cha * In addition, this function returns a 0 if the command works on a file, * and 1 if the command works on a pipe. */ -int rfc1524_expand_command (BODY *a, const char *filename, const char *_type, - char *command, int clen) +int mutt_buffer_rfc1524_expand_command (BODY *a, const char *filename, const char *_type, + BUFFER *command) { - int x=0; + const char *cptr; int needspipe = TRUE; BUFFER *buf = NULL; BUFFER *quoted = NULL; - char type[LONG_STRING]; + BUFFER *param = NULL; + BUFFER *type = NULL; buf = mutt_buffer_pool_get (); quoted = mutt_buffer_pool_get (); - strfcpy (type, _type, sizeof (type)); - - if (option (OPTMAILCAPSANITIZE)) - mutt_sanitize_filename (type, 0); - - while (x < clen - 1 && command[x]) + cptr = mutt_b2s (command); + while (*cptr) { - if (command[x] == '\\') + if (*cptr == '\\') { - x++; - mutt_buffer_addch (buf, command[x++]); + cptr++; + if (*cptr) + mutt_buffer_addch (buf, *cptr++); } - else if (command[x] == '%') + else if (*cptr == '%') { - x++; - if (command[x] == '{') + cptr++; + if (*cptr == '{') { - char param[STRING]; - char pvalue[STRING]; - char *_pvalue; - int z = 0; + const char *_pvalue; + + if (!param) + param = mutt_buffer_pool_get (); + else + mutt_buffer_clear (param); - x++; - while (command[x] && command[x] != '}' && z < sizeof (param) - 1) - param[z++] = command[x++]; - param[z] = '\0'; + /* Copy parameter name into param buffer */ + cptr++; + while (*cptr && *cptr != '}') + mutt_buffer_addch (param, *cptr++); /* In send mode, use the current charset, since the message hasn't * been converted yet. If noconv is set, then we assume the * charset parameter has the correct value instead. */ - if ((ascii_strcasecmp (param, "charset") == 0) && a->charset && !a->noconv) + if ((ascii_strcasecmp (mutt_b2s (param), "charset") == 0) && a->charset && !a->noconv) _pvalue = a->charset; else - _pvalue = mutt_get_parameter (param, a->parameter); - strfcpy (pvalue, NONULL(_pvalue), sizeof (pvalue)); + _pvalue = mutt_get_parameter (mutt_b2s (param), a->parameter); + + /* Now copy the parameter value into param buffer */ if (option (OPTMAILCAPSANITIZE)) - mutt_sanitize_filename (pvalue, 0); + mutt_buffer_sanitize_filename (param, NONULL(_pvalue), 0); + else + mutt_buffer_strcpy (param, NONULL(_pvalue)); - mutt_buffer_quote_filename (quoted, pvalue); + mutt_buffer_quote_filename (quoted, mutt_b2s (param)); mutt_buffer_addstr (buf, mutt_b2s (quoted)); } - else if (command[x] == 's' && filename != NULL) + else if (*cptr == 's' && filename != NULL) { mutt_buffer_quote_filename (quoted, filename); mutt_buffer_addstr (buf, mutt_b2s (quoted)); needspipe = FALSE; } - else if (command[x] == 't') + else if (*cptr == 't') { - mutt_buffer_quote_filename (quoted, type); + if (!type) + { + type = mutt_buffer_pool_get (); + if (option (OPTMAILCAPSANITIZE)) + mutt_buffer_sanitize_filename (type, _type, 0); + else + mutt_buffer_strcpy (type, _type); + } + mutt_buffer_quote_filename (quoted, mutt_b2s (type)); mutt_buffer_addstr (buf, mutt_b2s (quoted)); } - x++; + + if (*cptr) + cptr++; } else - mutt_buffer_addch (buf, command[x++]); + mutt_buffer_addch (buf, *cptr++); } - strfcpy (command, mutt_b2s (buf), clen); + mutt_buffer_strcpy (command, mutt_b2s (buf)); mutt_buffer_pool_release (&buf); mutt_buffer_pool_release ("ed); + mutt_buffer_pool_release (¶m); + mutt_buffer_pool_release (&type); return needspipe; }