|
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/unordered_flat_map.hpp> |
@@ -1388,63 +1390,33 @@ GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & |
1388 | 1390 | return workdirInfo; |
1389 | 1391 | } |
1390 | 1392 |
|
1391 | | -/** |
1392 | | - * Checks that the git reference is valid and normalizes slash '/' sequences. |
1393 | | - * |
1394 | | - * Accepts shorthand references (one-level refnames are allowed). |
1395 | | - */ |
1396 | | -bool isValidRefNameAllowNormalizations(const std::string & refName) |
1397 | | -{ |
1398 | | - /* Unfortunately libgit2 doesn't expose the limit in headers, but its internal |
1399 | | - limit is also 1024. */ |
1400 | | - std::array<char, 1024> normalizedRefBuffer; |
1401 | | - |
1402 | | - /* It would be nice to have a better API like git_reference_name_is_valid, but |
1403 | | - * with GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND flag. libgit2 uses it internally |
1404 | | - * but doesn't expose it in public headers [1]. |
1405 | | - * [1]: |
1406 | | - * https://github.com/libgit2/libgit2/blob/9d5f1bacc23594c2ba324c8f0d41b88bf0e9ef04/src/libgit2/refs.c#L1362-L1365 |
1407 | | - */ |
1408 | | - |
1409 | | - auto res = git_reference_normalize_name( |
1410 | | - normalizedRefBuffer.data(), |
1411 | | - normalizedRefBuffer.size(), |
1412 | | - refName.c_str(), |
1413 | | - GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL | GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND); |
1414 | | - |
1415 | | - return res == 0; |
1416 | | -} |
1417 | | - |
1418 | 1393 | bool isLegalRefName(const std::string & refName) |
1419 | 1394 | { |
1420 | 1395 | initLibGit2(); |
1421 | 1396 |
|
1422 | | - /* Since `git_reference_normalize_name` is the best API libgit2 has for verifying |
1423 | | - * reference names with shorthands (see comment in normalizeRefName), we need to |
1424 | | - * ensure that exceptions to the validity checks imposed by normalization [1] are checked |
1425 | | - * explicitly. |
1426 | | - * [1]: https://git-scm.com/docs/git-check-ref-format#Documentation/git-check-ref-format.txt---normalize |
1427 | | - */ |
1428 | | - |
1429 | 1397 | /* Check for cases that don't get rejected by libgit2. |
1430 | 1398 | * FIXME: libgit2 should reject this. */ |
1431 | 1399 | if (refName == "@") |
1432 | 1400 | return false; |
1433 | 1401 |
|
1434 | | - /* Leading slashes and consecutive slashes are stripped during normalizatiton. */ |
1435 | | - if (refName.starts_with('/') || refName.find("//") != refName.npos) |
1436 | | - return false; |
1437 | | - |
1438 | | - /* Refer to libgit2. */ |
1439 | | - if (!isValidRefNameAllowNormalizations(refName)) |
1440 | | - return false; |
1441 | | - |
1442 | 1402 | /* libgit2 doesn't barf on DEL symbol. |
1443 | 1403 | * FIXME: libgit2 should reject this. */ |
1444 | 1404 | if (refName.find('\177') != refName.npos) |
1445 | 1405 | return false; |
1446 | 1406 |
|
1447 | | - return true; |
| 1407 | + for (auto * func : { |
| 1408 | + git_reference_name_is_valid, |
| 1409 | + git_branch_name_is_valid, |
| 1410 | + git_tag_name_is_valid, |
| 1411 | + }) { |
| 1412 | + int valid = 0; |
| 1413 | + if (func(&valid, refName.c_str())) |
| 1414 | + throw Error("checking git reference '%s': %s", refName, git_error_last()->message); |
| 1415 | + if (valid) |
| 1416 | + return true; |
| 1417 | + } |
| 1418 | + |
| 1419 | + return false; |
1448 | 1420 | } |
1449 | 1421 |
|
1450 | 1422 | } // namespace nix |
0 commit comments