summaryrefslogtreecommitdiffstats
path: root/vendor/gix-validate/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/gix-validate/src
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-validate/src')
-rw-r--r--vendor/gix-validate/src/lib.rs11
-rw-r--r--vendor/gix-validate/src/reference.rs75
-rw-r--r--vendor/gix-validate/src/tag.rs61
3 files changed, 147 insertions, 0 deletions
diff --git a/vendor/gix-validate/src/lib.rs b/vendor/gix-validate/src/lib.rs
new file mode 100644
index 000000000..fd603aeb8
--- /dev/null
+++ b/vendor/gix-validate/src/lib.rs
@@ -0,0 +1,11 @@
+//! Validation for various kinds of git related items.
+#![deny(missing_docs, rust_2018_idioms)]
+#![forbid(unsafe_code)]
+
+///
+pub mod reference;
+pub use reference::name as refname;
+
+///
+pub mod tag;
+pub use tag::name as tagname;
diff --git a/vendor/gix-validate/src/reference.rs b/vendor/gix-validate/src/reference.rs
new file mode 100644
index 000000000..eb1f25a81
--- /dev/null
+++ b/vendor/gix-validate/src/reference.rs
@@ -0,0 +1,75 @@
+///
+pub mod name {
+ use std::convert::Infallible;
+
+ /// The error used in [name()][super::name()] and [name_partial()][super::name_partial()]
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error("A reference must be a valid tag name as well")]
+ Tag(#[from] crate::tag::name::Error),
+ #[error("Standalone references must be all uppercased, like 'HEAD'")]
+ SomeLowercase,
+ #[error("A reference name must not start with a slash '/'")]
+ StartsWithSlash,
+ #[error("Multiple slashes in a row are not allowed as they may change the reference's meaning")]
+ RepeatedSlash,
+ #[error("Names must not be a single '.', but may contain it.")]
+ SingleDot,
+ }
+
+ impl From<Infallible> for Error {
+ fn from(_: Infallible) -> Self {
+ unreachable!("this impl is needed to allow passing a known valid partial path as parameter")
+ }
+ }
+}
+
+use bstr::BStr;
+
+/// Validate a reference name running all the tests in the book. This disallows lower-case references, but allows
+/// ones like `HEAD`.
+pub fn name(path: &BStr) -> Result<&BStr, name::Error> {
+ validate(path, Mode::Complete)
+}
+
+/// Validate a partial reference name. As it is assumed to be partial, names like `some-name` is allowed
+/// even though these would be disallowed with when using [`name()`].
+pub fn name_partial(path: &BStr) -> Result<&BStr, name::Error> {
+ validate(path, Mode::Partial)
+}
+
+enum Mode {
+ Complete,
+ Partial,
+}
+
+fn validate(path: &BStr, mode: Mode) -> Result<&BStr, name::Error> {
+ crate::tagname(path)?;
+ if path[0] == b'/' {
+ return Err(name::Error::StartsWithSlash);
+ }
+ let mut previous = 0;
+ let mut one_before_previous = 0;
+ let mut saw_slash = false;
+ for byte in path.iter() {
+ match *byte {
+ b'/' if previous == b'.' && one_before_previous == b'/' => return Err(name::Error::SingleDot),
+ b'/' if previous == b'/' => return Err(name::Error::RepeatedSlash),
+ _ => {}
+ }
+
+ if *byte == b'/' {
+ saw_slash = true;
+ }
+ one_before_previous = previous;
+ previous = *byte;
+ }
+
+ if let Mode::Complete = mode {
+ if !saw_slash && !path.iter().all(|c| c.is_ascii_uppercase() || *c == b'_') {
+ return Err(name::Error::SomeLowercase);
+ }
+ }
+ Ok(path)
+}
diff --git a/vendor/gix-validate/src/tag.rs b/vendor/gix-validate/src/tag.rs
new file mode 100644
index 000000000..91ceec185
--- /dev/null
+++ b/vendor/gix-validate/src/tag.rs
@@ -0,0 +1,61 @@
+use bstr::BStr;
+
+///
+pub mod name {
+ use bstr::BString;
+
+ /// The error returned by [`name()`][super::name()].
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error("A ref must not contain invalid bytes or ascii control characters: {byte:?}")]
+ InvalidByte { byte: BString },
+ #[error("A ref must not contain '..' as it may be mistaken for a range")]
+ DoubleDot,
+ #[error("A ref must not end with '.lock'")]
+ LockFileSuffix,
+ #[error("A ref must not contain '@{{' which is a part of a ref-log")]
+ ReflogPortion,
+ #[error("A ref must not contain '*' character")]
+ Asterisk,
+ #[error("A ref must not start with a '.'")]
+ StartsWithDot,
+ #[error("A ref must not end with a '/'")]
+ EndsWithSlash,
+ #[error("A ref must not be empty")]
+ Empty,
+ }
+}
+
+/// Assure the given `input` resemble a valid git tag name, which is returned unchanged on success.
+pub fn name(input: &BStr) -> Result<&BStr, name::Error> {
+ if input.is_empty() {
+ return Err(name::Error::Empty);
+ }
+ if *input.last().expect("non-empty") == b'/' {
+ return Err(name::Error::EndsWithSlash);
+ }
+
+ let mut previous = 0;
+ for byte in input.iter() {
+ match byte {
+ b'\\' | b'^' | b':' | b'[' | b'?' | b' ' | b'~' | b'\0'..=b'\x1F' | b'\x7F' => {
+ return Err(name::Error::InvalidByte {
+ byte: (&[*byte][..]).into(),
+ })
+ }
+ b'*' => return Err(name::Error::Asterisk),
+ b'.' if previous == b'.' => return Err(name::Error::DoubleDot),
+ b'{' if previous == b'@' => return Err(name::Error::ReflogPortion),
+ _ => {}
+ }
+ previous = *byte;
+ }
+ if input[0] == b'.' {
+ return Err(name::Error::StartsWithDot);
+ }
+ if input.ends_with(b".lock") {
+ return Err(name::Error::LockFileSuffix);
+ }
+ Ok(input)
+}