* We fundamentally don't like some paths: we don't want * dot or dot-dot anywhere, and for obvious reasons don't * want to recurse into ".git" either. * * Also, we don't want double slashes or slashes at the * end that can make pathnames ambiguous. */
| 942 | * end that can make pathnames ambiguous. |
| 943 | */ |
| 944 | static int verify_dotfile(const char *rest, unsigned mode) |
| 945 | { |
| 946 | /* |
| 947 | * The first character was '.', but that |
| 948 | * has already been discarded, we now test |
| 949 | * the rest. |
| 950 | */ |
| 951 | |
| 952 | /* "." is not allowed */ |
| 953 | if (*rest == '\0' || is_dir_sep(*rest)) |
| 954 | return 0; |
| 955 | |
| 956 | switch (*rest) { |
| 957 | /* |
| 958 | * ".git" followed by NUL or slash is bad. Note that we match |
| 959 | * case-insensitively here, even if ignore_case is not set. |
| 960 | * This outlaws ".GIT" everywhere out of an abundance of caution, |
| 961 | * since there's really no good reason to allow it. |
| 962 | * |
| 963 | * Once we've seen ".git", we can also find ".gitmodules", etc (also |
| 964 | * case-insensitively). |
| 965 | */ |
| 966 | case 'g': |
| 967 | case 'G': |
| 968 | if (rest[1] != 'i' && rest[1] != 'I') |
| 969 | break; |
| 970 | if (rest[2] != 't' && rest[2] != 'T') |
| 971 | break; |
| 972 | if (rest[3] == '\0' || is_dir_sep(rest[3])) |
| 973 | return 0; |
| 974 | if (S_ISLNK(mode)) { |
| 975 | rest += 3; |
| 976 | if (skip_iprefix(rest, "modules", &rest) && |
| 977 | (*rest == '\0' || is_dir_sep(*rest))) |
| 978 | return 0; |
| 979 | } |
| 980 | break; |
| 981 | case '.': |
| 982 | if (rest[1] == '\0' || is_dir_sep(rest[1])) |
| 983 | return 0; |
| 984 | } |
| 985 | return 1; |
| 986 | } |
| 987 | |
| 988 | static enum verify_path_result verify_path_internal(const char *path, |
| 989 | unsigned mode) |
no outgoing calls
no test coverage detected