@@ -200,7 +200,7 @@ void ppl_convert(const char** from, const char* to, char** dst, const char* dste
200200
201201
202202void find_end_of_posix_list (const char ** to, int * in_string) {
203- for (; **to != ' \0 ' && (in_string ? ( **to != *in_string) : **to != ' ' ); ++*to) {
203+ for (; **to != ' \0 ' && (! in_string || **to != *in_string); ++*to) {
204204 }
205205
206206 if (**to == *in_string) {
@@ -237,6 +237,7 @@ void find_end_of_rooted_path(const char** from, const char** to, int* in_string)
237237void sub_convert (const char ** from, const char ** to, char ** dst, const char * dstend, int * in_string) {
238238 const char * copy_from = *from;
239239 path_type type = find_path_start_and_type (from, false , *to);
240+ debug_printf (" found type %d for path %s" , type, copy_from);
240241
241242 if (type == POSIX_PATH_LIST) {
242243 find_end_of_posix_list (to, in_string);
@@ -300,12 +301,6 @@ const char* convert(char *dst, size_t dstlen, const char *src) {
300301 }
301302 continue ;
302303 }
303-
304- if (isspace (*srcit)) {
305- // sub_convert(&srcbeg, &srcit, &dstit, dstend, &in_string);
306- // srcbeg = srcit + 1;
307- break ;
308- }
309304 }
310305
311306 sub_convert (&srcbeg, &srcit, &dstit, dstend, &in_string);
@@ -341,8 +336,67 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en
341336
342337 if (*it == ' \0 ' || it == end) return NONE;
343338
344- if (!isalnum (*it) && *it != ' /' && *it != ' \\ ' && *it != ' :' && *it != ' -' && *it != ' .' ) {
345- return find_path_start_and_type (move (src, 1 ), true , end);
339+ /* Let's not convert ~/.file to ~C:\msys64\.file */
340+ if (*it == ' ~' ) {
341+ skip_p2w:
342+ *src = end;
343+ return NONE;
344+ }
345+
346+ /*
347+ * Skip path mangling when environment indicates it.
348+ */
349+ const char *no_pathconv = getenv (" MSYS_NO_PATHCONV" );
350+
351+ if (no_pathconv)
352+ goto skip_p2w;
353+
354+ /*
355+ * Prevent Git's :file.txt and :/message syntax from beeing modified.
356+ */
357+ if (*it == ' :' )
358+ goto skip_p2w;
359+
360+ while (it != end && *it) {
361+ switch (*it) {
362+ case ' `' :
363+ case ' \' ' :
364+ case ' "' :
365+ case ' *' :
366+ case ' ?' :
367+ case ' [' :
368+ case ' ]' :
369+ goto skip_p2w;
370+ case ' /' :
371+ if (it + 1 < end && it[1 ] == ' ~' )
372+ goto skip_p2w;
373+ break ;
374+ case ' :' :
375+ // Avoid mangling IPv6 addresses
376+ if (it + 1 < end && it[1 ] == ' :' )
377+ goto skip_p2w;
378+
379+ // Leave Git's <rev>:./name syntax alone
380+ if (it + 1 < end && it[1 ] == ' .' ) {
381+ if (it + 2 < end && it[2 ] == ' /' )
382+ goto skip_p2w;
383+ if (it + 3 < end && it[2 ] == ' .' && it[3 ] == ' /' )
384+ goto skip_p2w;
385+ }
386+ break ;
387+ case ' @' :
388+ // Paths do not contain '@@'
389+ if (it + 1 < end && it[1 ] == ' @' )
390+ goto skip_p2w;
391+ }
392+ ++it;
393+ }
394+ it = *src;
395+
396+ while (!isalnum (*it) && !(0x80 & *it) && *it != ' /' && *it != ' \\ ' && *it != ' :' && *it != ' -' && *it != ' .' ) {
397+ recurse = true ;
398+ it = ++*src;
399+ if (it == end || *it == ' \0 ' ) return NONE;
346400 }
347401
348402 path_type result = NONE;
@@ -404,6 +458,8 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en
404458
405459 int starts_with_minus = 0 ;
406460 int starts_with_minus_alpha = 0 ;
461+ int only_dots = *it == ' .' ;
462+ int has_slashes = 0 ;
407463 if (*it == ' -' ) {
408464 starts_with_minus = 1 ;
409465 it += 1 ;
@@ -447,11 +503,17 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en
447503 if (ch == ' /' && *(it2 + 1 ) == ' /' ) {
448504 return URL;
449505 } else {
506+ if (!only_dots && !has_slashes)
507+ goto skip_p2w;
450508 return POSIX_PATH_LIST;
451509 }
452510 } else if (memchr (it2, ' =' , end - it) == NULL ) {
453511 return SIMPLE_WINDOWS_PATH;
454512 }
513+ } else if (ch != ' .' ) {
514+ only_dots = 0 ;
515+ if (ch == ' /' || ch == ' \\ ' )
516+ has_slashes = 1 ;
455517 }
456518 }
457519
0 commit comments