|
12 | 12 |
|
13 | 13 | #include <git2/attr.h> |
14 | 14 | #include <git2/blob.h> |
| 15 | +#include <git2/branch.h> |
15 | 16 | #include <git2/commit.h> |
16 | 17 | #include <git2/config.h> |
17 | 18 | #include <git2/describe.h> |
|
28 | 29 | #include <git2/submodule.h> |
29 | 30 | #include <git2/sys/odb_backend.h> |
30 | 31 | #include <git2/sys/mempack.h> |
| 32 | +#include <git2/tag.h> |
31 | 33 | #include <git2/tree.h> |
32 | 34 |
|
33 | 35 | #include <boost/unordered/unordered_flat_map.hpp> |
@@ -1323,63 +1325,33 @@ GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & |
1323 | 1325 | return workdirInfo; |
1324 | 1326 | } |
1325 | 1327 |
|
1326 | | -/** |
1327 | | - * Checks that the git reference is valid and normalizes slash '/' sequences. |
1328 | | - * |
1329 | | - * Accepts shorthand references (one-level refnames are allowed). |
1330 | | - */ |
1331 | | -bool isValidRefNameAllowNormalizations(const std::string & refName) |
1332 | | -{ |
1333 | | - /* Unfortunately libgit2 doesn't expose the limit in headers, but its internal |
1334 | | - limit is also 1024. */ |
1335 | | - std::array<char, 1024> normalizedRefBuffer; |
1336 | | - |
1337 | | - /* It would be nice to have a better API like git_reference_name_is_valid, but |
1338 | | - * with GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND flag. libgit2 uses it internally |
1339 | | - * but doesn't expose it in public headers [1]. |
1340 | | - * [1]: |
1341 | | - * https://github.com/libgit2/libgit2/blob/9d5f1bacc23594c2ba324c8f0d41b88bf0e9ef04/src/libgit2/refs.c#L1362-L1365 |
1342 | | - */ |
1343 | | - |
1344 | | - auto res = git_reference_normalize_name( |
1345 | | - normalizedRefBuffer.data(), |
1346 | | - normalizedRefBuffer.size(), |
1347 | | - refName.c_str(), |
1348 | | - GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL | GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND); |
1349 | | - |
1350 | | - return res == 0; |
1351 | | -} |
1352 | | - |
1353 | 1328 | bool isLegalRefName(const std::string & refName) |
1354 | 1329 | { |
1355 | 1330 | initLibGit2(); |
1356 | 1331 |
|
1357 | | - /* Since `git_reference_normalize_name` is the best API libgit2 has for verifying |
1358 | | - * reference names with shorthands (see comment in normalizeRefName), we need to |
1359 | | - * ensure that exceptions to the validity checks imposed by normalization [1] are checked |
1360 | | - * explicitly. |
1361 | | - * [1]: https://git-scm.com/docs/git-check-ref-format#Documentation/git-check-ref-format.txt---normalize |
1362 | | - */ |
1363 | | - |
1364 | 1332 | /* Check for cases that don't get rejected by libgit2. |
1365 | 1333 | * FIXME: libgit2 should reject this. */ |
1366 | 1334 | if (refName == "@") |
1367 | 1335 | return false; |
1368 | 1336 |
|
1369 | | - /* Leading slashes and consecutive slashes are stripped during normalizatiton. */ |
1370 | | - if (refName.starts_with('/') || refName.find("//") != refName.npos) |
1371 | | - return false; |
1372 | | - |
1373 | | - /* Refer to libgit2. */ |
1374 | | - if (!isValidRefNameAllowNormalizations(refName)) |
1375 | | - return false; |
1376 | | - |
1377 | 1337 | /* libgit2 doesn't barf on DEL symbol. |
1378 | 1338 | * FIXME: libgit2 should reject this. */ |
1379 | 1339 | if (refName.find('\177') != refName.npos) |
1380 | 1340 | return false; |
1381 | 1341 |
|
1382 | | - return true; |
| 1342 | + for (auto * func : { |
| 1343 | + git_reference_name_is_valid, |
| 1344 | + git_branch_name_is_valid, |
| 1345 | + git_tag_name_is_valid, |
| 1346 | + }) { |
| 1347 | + int valid = 0; |
| 1348 | + if (func(&valid, refName.c_str())) |
| 1349 | + throw Error("checking git reference '%s': %s", refName, git_error_last()->message); |
| 1350 | + if (valid) |
| 1351 | + return true; |
| 1352 | + } |
| 1353 | + |
| 1354 | + return false; |
1383 | 1355 | } |
1384 | 1356 |
|
1385 | 1357 | } // namespace nix |
0 commit comments