@@ -208,6 +208,58 @@ int has_non_ascii(const char *s)
208208 return 0 ;
209209}
210210
211+ static int is_rfc822_special (char ch )
212+ {
213+ switch (ch ) {
214+ case '(' :
215+ case ')' :
216+ case '<' :
217+ case '>' :
218+ case '[' :
219+ case ']' :
220+ case ':' :
221+ case ';' :
222+ case '@' :
223+ case ',' :
224+ case '.' :
225+ case '"' :
226+ case '\\' :
227+ return 1 ;
228+ default :
229+ return 0 ;
230+ }
231+ }
232+
233+ static int has_rfc822_specials (const char * s , int len )
234+ {
235+ int i ;
236+ for (i = 0 ; i < len ; i ++ )
237+ if (is_rfc822_special (s [i ]))
238+ return 1 ;
239+ return 0 ;
240+ }
241+
242+ static void add_rfc822_quoted (struct strbuf * out , const char * s , int len )
243+ {
244+ int i ;
245+
246+ /* just a guess, we may have to also backslash-quote */
247+ strbuf_grow (out , len + 2 );
248+
249+ strbuf_addch (out , '"' );
250+ for (i = 0 ; i < len ; i ++ ) {
251+ switch (s [i ]) {
252+ case '"' :
253+ case '\\' :
254+ strbuf_addch (out , '\\' );
255+ /* fall through */
256+ default :
257+ strbuf_addch (out , s [i ]);
258+ }
259+ }
260+ strbuf_addch (out , '"' );
261+ }
262+
211263static int is_rfc2047_special (char ch )
212264{
213265 return (non_ascii (ch ) || (ch == '=' ) || (ch == '?' ) || (ch == '_' ));
@@ -293,7 +345,14 @@ void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
293345 name_tail -- ;
294346 display_name_length = name_tail - line ;
295347 strbuf_addstr (sb , "From: " );
296- add_rfc2047 (sb , line , display_name_length , encoding );
348+ if (!has_rfc822_specials (line , display_name_length )) {
349+ add_rfc2047 (sb , line , display_name_length , encoding );
350+ } else {
351+ struct strbuf quoted = STRBUF_INIT ;
352+ add_rfc822_quoted (& quoted , line , display_name_length );
353+ add_rfc2047 (sb , quoted .buf , quoted .len , encoding );
354+ strbuf_release (& quoted );
355+ }
297356 strbuf_add (sb , name_tail , namelen - display_name_length );
298357 strbuf_addch (sb , '\n' );
299358 } else {
0 commit comments