Kevin,
While experimenting with OAuth2 to Microsoft (I'll report on that soon), I ran
into a mutt limit involving variable expansion. I was using a super-long token
parameter (taking up several lines) to the oauth_refresh_command that I didn't
want to repeat in two places, so I tried
set imap_oauth_refresh_command="/path/to/script.py HUGE_REFRESH_TOKEN"
set smtp_oauth_refresh_command=${imap_oauth_refresh_command}
but could not get SMTP to function until I switched to
set imap_oauth_refresh_command="/path/to/script.py HUGE_REFRESH_TOKEN"
set smtp_oauth_refresh_command="/path/to/script.py HUGE_REFRESH_TOKEN"
Turns out the dollar-variable-expansion in my first version wasn't extracting
the entire variable, thus cutting off part of the token being sent to
Microsoft. The end user will have to manually update this token value
periodically (at my institution they expire every 30 days), so having it in
just one place is preferable. Okay, I can move this long parameter to a
separate file to be read in by the script, but wanted to raise here for
possible consideration several little ideas related to .muttrc variable
expansion.
Although it seems that variable values themselves can be longer than 1022
bytes, if one places a dollar-variable-expansion inside another variable, then
only the first 1022 bytes will be expanded. The internal buffer has size 1024,
so why 1022 rather than 1023? The off-by-one error seems to be near the end of
var_to_string(), where escape_string(val, len - 1, tmp) should likely be
escape_string(val, len, tmp).
Looking at escape_string(), it incidentally seems there's an edge case where
the escaping of a quotation mark at the end of the destination buffer would
lead to not just truncation but also mutation (storing the incorrect last
character). I believe the following patch would eliminate that possibility:
diff --git a/init.c b/init.c
index 8cd97ca0..eab91b2a 100644
--- a/init.c
+++ b/init.c
@@ -1909,9 +1909,11 @@ static size_t escape_string (char *dst, size_t len,
const char* src)
case '\t':
ESC_CHAR('t');
break;
+ case '\\':
+ case '"':
+ ESC_CHAR(*src);
+ break;
default:
- if ((*src == '\\' || *src == '"') && p - dst < len - 1)
- *p++ = '\\';
*p++ = *src;
}
src++;
As for increasing the variable expansion limit: if I follow the parsing code
correctly, it mostly uses the BUFFER type, but parse_set() calls
mutt_extract_token() which for variable expansion uses a local stack-based
LONG_STRING (1024 bytes) to receive the value, and calls var_to_string(), which
constructs the value inside another local stack-based LONG_STRING. Could these
be changed to HUGE_STRING (8192 bytes)? This would allow for longer variable
expansions, sufficient for what I was trying to do with my OAuth2 token
parameter.
Thanks,
Alex