@@ -74,6 +74,10 @@ static int credential_config_callback(const char *var, const char *value,
7474 }
7575 else if (!strcmp (key , "usehttppath" ))
7676 c -> use_http_path = git_config_bool (var , value );
77+ else if (!strcmp (key , "sanitizeprompt" ))
78+ c -> sanitize_prompt = git_config_bool (var , value );
79+ else if (!strcmp (key , "protectprotocol" ))
80+ c -> protect_protocol = git_config_bool (var , value );
7781
7882 return 0 ;
7983}
@@ -171,7 +175,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
171175 strbuf_addch (out , '@' );
172176 }
173177 if (c -> host )
174- strbuf_addstr (out , c -> host );
178+ strbuf_add_percentencode (out , c -> host ,
179+ STRBUF_ENCODE_HOST_AND_PORT );
175180 if (c -> path ) {
176181 strbuf_addch (out , '/' );
177182 strbuf_add_percentencode (out , c -> path , 0 );
@@ -185,7 +190,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
185190 struct strbuf prompt = STRBUF_INIT ;
186191 char * r ;
187192
188- credential_describe (c , & desc );
193+ if (c -> sanitize_prompt )
194+ credential_format (c , & desc );
195+ else
196+ credential_describe (c , & desc );
189197 if (desc .len )
190198 strbuf_addf (& prompt , "%s for '%s': " , what , desc .buf );
191199 else
@@ -268,7 +276,8 @@ int credential_read(struct credential *c, FILE *fp)
268276 return 0 ;
269277}
270278
271- static void credential_write_item (FILE * fp , const char * key , const char * value ,
279+ static void credential_write_item (const struct credential * c ,
280+ FILE * fp , const char * key , const char * value ,
272281 int required )
273282{
274283 if (!value && required )
@@ -277,24 +286,28 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
277286 return ;
278287 if (strchr (value , '\n' ))
279288 die ("credential value for %s contains newline" , key );
289+ if (c -> protect_protocol && strchr (value , '\r' ))
290+ die ("credential value for %s contains carriage return\n"
291+ "If this is intended, set `credential.protectProtocol=false`" ,
292+ key );
280293 fprintf (fp , "%s=%s\n" , key , value );
281294}
282295
283296void credential_write (const struct credential * c , FILE * fp )
284297{
285- credential_write_item (fp , "protocol" , c -> protocol , 1 );
286- credential_write_item (fp , "host" , c -> host , 1 );
287- credential_write_item (fp , "path" , c -> path , 0 );
288- credential_write_item (fp , "username" , c -> username , 0 );
289- credential_write_item (fp , "password" , c -> password , 0 );
290- credential_write_item (fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
298+ credential_write_item (c , fp , "protocol" , c -> protocol , 1 );
299+ credential_write_item (c , fp , "host" , c -> host , 1 );
300+ credential_write_item (c , fp , "path" , c -> path , 0 );
301+ credential_write_item (c , fp , "username" , c -> username , 0 );
302+ credential_write_item (c , fp , "password" , c -> password , 0 );
303+ credential_write_item (c , fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
291304 if (c -> password_expiry_utc != TIME_MAX ) {
292305 char * s = xstrfmt ("%" PRItime , c -> password_expiry_utc );
293- credential_write_item (fp , "password_expiry_utc" , s , 0 );
306+ credential_write_item (c , fp , "password_expiry_utc" , s , 0 );
294307 free (s );
295308 }
296309 for (size_t i = 0 ; i < c -> wwwauth_headers .nr ; i ++ )
297- credential_write_item (fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
310+ credential_write_item (c , fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
298311}
299312
300313static int run_credential_helper (struct credential * c ,
0 commit comments