Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
Add Size Limits to TypeName
Merged fintohaps opened 2 months ago

Domain Names have restrictions on their total length, and the length of individual labels1.

Since TypeNames are expected to be reverse domain name strings, the total length of the internal string should not exceed 255 and each component should not exceed 63.

1

https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4

3 files changed +37 -1 1cab036c 82ad52b1
modified CHANGELOG.md
@@ -27,6 +27,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
  pushed the default branch to the local user's namespace. The command is now
  deprecated, and the user should use `git push` instead.

+
## Breaking Changes
+

+
- The `TypeName` strings defined in `radicle-cob` are restricted to reflect the
+
  size limits on domain names as specified in
+
  [RFC-1035](https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4).
+

## 1.6.1

## Fixed Bugs
modified crates/radicle-cob/Cargo.toml
@@ -28,7 +28,7 @@ nonempty = { workspace = true, features = ["serialize"] }
radicle-crypto = { workspace = true, features = ["ssh"] }
radicle-dag = { workspace = true }
radicle-git-metadata = { workspace = true }
-
radicle-oid = { workspace = true, features = ["git2", "serde", "std"] }
+
radicle-oid = { workspace = true, features = ["git2", "serde", "std", "sha1"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
signature = { workspace = true }
modified crates/radicle-cob/src/type_name.rs
@@ -10,6 +10,9 @@ use thiserror::Error;
/// alphanumeric characters or hyphens separated by a period. Each
/// component must start and end with an alphanumeric character.
///
+
/// The total length of a typename MUST NOT exceed 255, and each component
+
/// length MUST NOT exceed 63.
+
///
/// # Examples
///
/// * `abc.def`
@@ -19,6 +22,9 @@ use thiserror::Error;
pub struct TypeName(String);

impl TypeName {
+
    const MAX_LENGTH: usize = 255;
+
    const MAX_COMPONENT: usize = 63;
+

    pub fn as_str(&self) -> &str {
        &self.0
    }
@@ -40,8 +46,18 @@ impl FromStr for TypeName {
    type Err = TypeNameParse;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
+
        if s.len() > Self::MAX_LENGTH {
+
            return Err(TypeNameParse {
+
                invalid: s.to_string(),
+
            });
+
        }
        let split = s.split('.');
        for component in split {
+
            if component.len() > Self::MAX_COMPONENT {
+
                return Err(TypeNameParse {
+
                    invalid: s.to_string(),
+
                });
+
            }
            if component.is_empty() {
                return Err(TypeNameParse {
                    invalid: s.to_string(),
@@ -89,6 +105,10 @@ mod test {
        assert!(TypeName::from_str("abc.123.ghi").is_ok());
        assert!(TypeName::from_str("1bc.123.ghi").is_ok());
        assert!(TypeName::from_str("1bc-123.ghi").is_ok());
+
    }
+

+
    #[test]
+
    fn invalid_typenames() {
        assert!(TypeName::from_str("").is_err());
        assert!(TypeName::from_str(".").is_err());
        assert!(TypeName::from_str(".abc.123.ghi").is_err());
@@ -96,5 +116,15 @@ mod test {
        assert!(TypeName::from_str("abc..ghi").is_err());
        assert!(TypeName::from_str("abc.-123.ghi").is_err());
        assert!(TypeName::from_str("abc.123-.ghi").is_err());
+
        assert!(TypeName::from_str(&format!(
+
            "a.very.long.name.that.exceeds.the.two-hundred-and-fifty-five.length.limit.{}",
+
            "a".repeat(255)
+
        ))
+
        .is_err());
+
        assert!(TypeName::from_str(&format!(
+
            "component.exceeds.sixty-three.limit.{}",
+
            "a".repeat(64)
+
        ))
+
        .is_err());
    }
}