| 3270 | } |
| 3271 | |
| 3272 | char *git_url_basename(const char *repo, int is_bundle, int is_bare) |
| 3273 | { |
| 3274 | const char *end = repo + strlen(repo), *start, *ptr; |
| 3275 | size_t len; |
| 3276 | char *dir; |
| 3277 | |
| 3278 | /* |
| 3279 | * Skip scheme. |
| 3280 | */ |
| 3281 | start = strstr(repo, "://"); |
| 3282 | if (!start) |
| 3283 | start = repo; |
| 3284 | else |
| 3285 | start += 3; |
| 3286 | |
| 3287 | /* |
| 3288 | * Skip authentication data. The stripping does happen |
| 3289 | * greedily, such that we strip up to the last '@' inside |
| 3290 | * the host part. |
| 3291 | */ |
| 3292 | for (ptr = start; ptr < end && !is_dir_sep(*ptr); ptr++) { |
| 3293 | if (*ptr == '@') |
| 3294 | start = ptr + 1; |
| 3295 | } |
| 3296 | |
| 3297 | /* |
| 3298 | * Strip trailing spaces, slashes and /.git |
| 3299 | */ |
| 3300 | while (start < end && (is_dir_sep(end[-1]) || isspace(end[-1]))) |
| 3301 | end--; |
| 3302 | if (end - start > 5 && is_dir_sep(end[-5]) && |
| 3303 | !strncmp(end - 4, ".git", 4)) { |
| 3304 | end -= 5; |
| 3305 | while (start < end && is_dir_sep(end[-1])) |
| 3306 | end--; |
| 3307 | } |
| 3308 | |
| 3309 | /* |
| 3310 | * It should not be possible to overflow `ptrdiff_t` by passing in an |
| 3311 | * insanely long URL, but GCC does not know that and will complain |
| 3312 | * without this check. |
| 3313 | */ |
| 3314 | if (end - start < 0) |
| 3315 | die(_("No directory name could be guessed.\n" |
| 3316 | "Please specify a directory on the command line")); |
| 3317 | |
| 3318 | /* |
| 3319 | * Strip trailing port number if we've got only a |
| 3320 | * hostname (that is, there is no dir separator but a |
| 3321 | * colon). This check is required such that we do not |
| 3322 | * strip URI's like '/foo/bar:2222.git', which should |
| 3323 | * result in a dir '2222' being guessed due to backwards |
| 3324 | * compatibility. |
| 3325 | */ |
| 3326 | if (memchr(start, '/', end - start) == NULL |
| 3327 | && memchr(start, ':', end - start) != NULL) { |
| 3328 | ptr = end; |
| 3329 | while (start < ptr && isdigit(ptr[-1]) && ptr[-1] != ':') |
no test coverage detected