diff --git a/winsup/cygwin/msys2_path_conv.cc b/winsup/cygwin/msys2_path_conv.cc index 4c0cc82cf2..49caac99a6 100644 --- a/winsup/cygwin/msys2_path_conv.cc +++ b/winsup/cygwin/msys2_path_conv.cc @@ -238,7 +238,7 @@ void find_end_of_rooted_path(const char** from, const char** to, int* in_string) void sub_convert(const char** from, const char** to, char** dst, const char* dstend, int* in_string) { const char* copy_from = *from; path_type type = find_path_start_and_type(from, false, *to); - debug_printf("found type %d for path %s", type, copy_from); + debug_printf("found type %d for path %s\n", type, copy_from); if (type == POSIX_PATH_LIST) { find_end_of_posix_list(to, in_string); @@ -358,6 +358,40 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en return NONE; } + /* + * Discern between Git's `:`, SCP's `:` pattern + * (which is not a path list but may naively look like one) on the one + * hand, and path lists starting with `/`, `./` or `../` + * on the other hand. + */ + bool potential_path_list = *it == '/' || + (*it == '.' && + (it + 1 == end || it[1] == '\0' || it[1] == ':' || it[1] == '/' || + (it[1] == '.' && + (it + 2 == end || it[2] == '\0' || it[2] == ':' || it[2] == '/')))); + + /* + * Determine if assignment to an environment variable takes place (and + * skip Git/SCP handling if so) + */ + bool potential_command_scope_env = false; + if (isalpha(*it) || *it == '_' || *it == '-') { + ++it; + + if (it != end) { + if (*it == '-') + ++it; + + while (it != end && *it && (isalnum(*it) || *it == '_')) { + ++it; + } + + if (*it == '=') + potential_command_scope_env = true; + } + it = *src; + } + /* * Prevent Git's :file.txt and :/message syntax from beeing modified. */ @@ -383,7 +417,7 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en goto skip_p2w; // Leave Git's :./name syntax alone - if (it + 1 < end && it[1] == '.') { + if (!potential_path_list && !potential_command_scope_env && it + 1 < end && it[1] == '.') { if (it + 2 < end && it[2] == '/') goto skip_p2w; if (it + 3 < end && it[2] == '.' && it[3] == '/') @@ -706,4 +740,3 @@ void posix_to_win32_path(const char* from, const char* to, char** dst, const cha } } } -