|
15 | 15 |
|
16 | 16 | #include <git2/attr.h> |
17 | 17 | #include <git2/blob.h> |
| 18 | +#include <git2/branch.h> |
18 | 19 | #include <git2/commit.h> |
19 | 20 | #include <git2/config.h> |
20 | 21 | #include <git2/describe.h> |
|
31 | 32 | #include <git2/submodule.h> |
32 | 33 | #include <git2/sys/odb_backend.h> |
33 | 34 | #include <git2/sys/mempack.h> |
| 35 | +#include <git2/tag.h> |
34 | 36 | #include <git2/tree.h> |
35 | 37 |
|
36 | 38 | #include <boost/unordered/concurrent_flat_set.hpp> |
@@ -1413,63 +1415,33 @@ GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & |
1413 | 1415 | return workdirInfo; |
1414 | 1416 | } |
1415 | 1417 |
|
1416 | | -/** |
1417 | | - * Checks that the git reference is valid and normalizes slash '/' sequences. |
1418 | | - * |
1419 | | - * Accepts shorthand references (one-level refnames are allowed). |
1420 | | - */ |
1421 | | -bool isValidRefNameAllowNormalizations(const std::string & refName) |
1422 | | -{ |
1423 | | - /* Unfortunately libgit2 doesn't expose the limit in headers, but its internal |
1424 | | - limit is also 1024. */ |
1425 | | - std::array<char, 1024> normalizedRefBuffer; |
1426 | | - |
1427 | | - /* It would be nice to have a better API like git_reference_name_is_valid, but |
1428 | | - * with GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND flag. libgit2 uses it internally |
1429 | | - * but doesn't expose it in public headers [1]. |
1430 | | - * [1]: |
1431 | | - * https://github.com/libgit2/libgit2/blob/9d5f1bacc23594c2ba324c8f0d41b88bf0e9ef04/src/libgit2/refs.c#L1362-L1365 |
1432 | | - */ |
1433 | | - |
1434 | | - auto res = git_reference_normalize_name( |
1435 | | - normalizedRefBuffer.data(), |
1436 | | - normalizedRefBuffer.size(), |
1437 | | - refName.c_str(), |
1438 | | - GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL | GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND); |
1439 | | - |
1440 | | - return res == 0; |
1441 | | -} |
1442 | | - |
1443 | 1418 | bool isLegalRefName(const std::string & refName) |
1444 | 1419 | { |
1445 | 1420 | initLibGit2(); |
1446 | 1421 |
|
1447 | | - /* Since `git_reference_normalize_name` is the best API libgit2 has for verifying |
1448 | | - * reference names with shorthands (see comment in normalizeRefName), we need to |
1449 | | - * ensure that exceptions to the validity checks imposed by normalization [1] are checked |
1450 | | - * explicitly. |
1451 | | - * [1]: https://git-scm.com/docs/git-check-ref-format#Documentation/git-check-ref-format.txt---normalize |
1452 | | - */ |
1453 | | - |
1454 | 1422 | /* Check for cases that don't get rejected by libgit2. |
1455 | 1423 | * FIXME: libgit2 should reject this. */ |
1456 | 1424 | if (refName == "@") |
1457 | 1425 | return false; |
1458 | 1426 |
|
1459 | | - /* Leading slashes and consecutive slashes are stripped during normalizatiton. */ |
1460 | | - if (refName.starts_with('/') || refName.find("//") != refName.npos) |
1461 | | - return false; |
1462 | | - |
1463 | | - /* Refer to libgit2. */ |
1464 | | - if (!isValidRefNameAllowNormalizations(refName)) |
1465 | | - return false; |
1466 | | - |
1467 | 1427 | /* libgit2 doesn't barf on DEL symbol. |
1468 | 1428 | * FIXME: libgit2 should reject this. */ |
1469 | 1429 | if (refName.find('\177') != refName.npos) |
1470 | 1430 | return false; |
1471 | 1431 |
|
1472 | | - return true; |
| 1432 | + for (auto * func : { |
| 1433 | + git_reference_name_is_valid, |
| 1434 | + git_branch_name_is_valid, |
| 1435 | + git_tag_name_is_valid, |
| 1436 | + }) { |
| 1437 | + int valid = 0; |
| 1438 | + if (func(&valid, refName.c_str())) |
| 1439 | + throw Error("checking git reference '%s': %s", refName, git_error_last()->message); |
| 1440 | + if (valid) |
| 1441 | + return true; |
| 1442 | + } |
| 1443 | + |
| 1444 | + return false; |
1473 | 1445 | } |
1474 | 1446 |
|
1475 | 1447 | } // namespace nix |
0 commit comments