{"record":{"id":"426bb8045df3369f","repo":"GitoxideLabs/gitoxide","slug":"valid-ref","errorCode":null,"errorMessage":"valid ref","messagePattern":"valid ref","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gix-ref/src/fullname.rs","lineNumber":255,"sourceCode":"    }\n\n    /// Classify this name, or return `None` if it's unclassified.\n    pub fn category(&self) -> Option<crate::Category<'_>> {\n        self.as_ref().category()\n    }\n\n    /// Classify this name, or return `None` if it's unclassified. If `Some`,\n    /// the shortened name is returned as well.\n    pub fn category_and_short_name(&self) -> Option<(crate::Category<'_>, &BStr)> {\n        self.as_ref().category_and_short_name()\n    }\n}\n\nimpl FullNameRef {\n    /// Return the file name portion of a full name, for instance `main` if the\n    /// full name was `refs/heads/main`.\n    pub fn file_name(&self) -> &BStr {\n        self.0.rsplitn(2, |b| *b == b'/').next().expect(\"valid ref\").as_bstr()\n    }\n}\n\nimpl Borrow<FullNameRef> for FullName {\n    #[inline]\n    fn borrow(&self) -> &FullNameRef {\n        FullNameRef::new_unchecked(self.0.as_bstr())\n    }\n}\n\nimpl AsRef<FullNameRef> for FullName {\n    fn as_ref(&self) -> &FullNameRef {\n        self.borrow()\n    }\n}\n\nimpl ToOwned for FullNameRef {\n    type Owned = FullName;","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-ref/src/fullname.rs#L237-L273","documentation":"This is a Rust `expect()` panic inside `FullNameRef::file_name()` in gix-ref. The method splits the full ref name on `/` with `rsplitn(2, ...)` and takes the last segment; the `expect(\"valid ref\")` asserts that `rsplitn` always yields at least one piece. Since `rsplitn` on any (even empty) byte string always returns at least one item, this panic fires only if the underlying `BStr` invariant of a `FullNameRef` was broken (e.g. the struct was constructed from a null/empty name via `new_unchecked` on garbage memory or via unsafe/FFI paths).","triggerScenarios":"Calling `FullNameRef::file_name()` on a `FullNameRef` whose inner bytes were constructed outside the library's validation (e.g. `FullName::try_from` was bypassed with `new_unchecked` on an empty or non-UTF8-safe buffer, or a ref name was hand-crafted from raw bytes read from disk).","commonSituations":"Users building `gix_ref::FullName` from raw bytes of their own ref-storage format; FFI/unsafe code reinterpreting a `FullNameRef`; corrupted ref files fed through low-level APIs instead of the validating constructors.","solutions":["Construct ref names only through validating APIs (`FullName::try_from`, `gix_ref::fullname::FullName::try_from(...)`) rather than `new_unchecked`.","Verify the name bytes are non-empty and contain no leading/trailing `/` before wrapping them as a `FullName`.","If you control input, sanitize it with the same rules git uses (see `gix_ref::validate::prelude` helpers) before conversion.","If the panic occurs on names produced by the library itself, report it upstream with the exact ref name bytes; it is an internal invariant violation."],"exampleFix":"// before\nlet name = unsafe { FullNameRef::new_unchecked(BStr::new(&raw_bytes)) };\nlet file = name.file_name(); // may panic\n// after\nlet name = FullName::try_from(raw_bytes.as_bstr())?; // validates\nlet file = name.as_ref().file_name();","handlingStrategy":"validation","validationCode":"fn is_valid_fullname(name: &gix_ref::FullNameRef) -> bool {\n    !name.as_bstr().is_empty()\n}\n// use validating constructor before calling file_name()\nlet name = gix_ref::FullName::try_from(bytes.as_bstr())?;","typeGuard":"fn file_name_safe(name: &gix_ref::FullNameRef) -> Option<&bstr::BStr> {\n    if name.as_bstr().is_empty() { None } else { Some(name.file_name()) }\n}","tryCatchPattern":null,"preventionTips":["Only create FullName/FullNameRef via try_from-style validating constructors","Never use new_unchecked on untrusted bytes","Sanitize ref names from external sources before wrapping them"],"tags":["rust","panic","ref-names","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}