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

Reply via email to