| 382 | } |
| 383 | |
| 384 | int refname_is_safe(const char *refname) |
| 385 | { |
| 386 | const char *rest; |
| 387 | |
| 388 | if (skip_prefix(refname, "refs/", &rest)) { |
| 389 | char *buf; |
| 390 | int result; |
| 391 | size_t restlen = strlen(rest); |
| 392 | |
| 393 | /* rest must not be empty, or start or end with "/" */ |
| 394 | if (!restlen || *rest == '/' || rest[restlen - 1] == '/') |
| 395 | return 0; |
| 396 | |
| 397 | /* |
| 398 | * Does the refname try to escape refs/? |
| 399 | * For example: refs/foo/../bar is safe but refs/foo/../../bar |
| 400 | * is not. |
| 401 | */ |
| 402 | buf = xmallocz(restlen); |
| 403 | result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest); |
| 404 | free(buf); |
| 405 | return result; |
| 406 | } |
| 407 | |
| 408 | do { |
| 409 | if (!isupper(*refname) && *refname != '_') |
| 410 | return 0; |
| 411 | refname++; |
| 412 | } while (*refname); |
| 413 | return 1; |
| 414 | } |
| 415 | |
| 416 | /* |
| 417 | * Return true if refname, which has the specified oid and flags, can |
no test coverage detected