History

fix: Don't panic when rev-parsing `^^^` and similar (#1914)

Sebastian Thiel committed 1 year ago

Commit aa8daf81 parent 12cb8477 files · +29 −3Browse files

Unified · Split

7 files
  1. gix/src/revision/spec/parse/delegate/navigate.rs +7 −1
  2. gix/src/revision/spec/parse/error.rs +0 −1
  3. gix/src/revision/spec/parse/types.rs +2 −0
  4. gix/tests/fixtures/generated-archives/make_rev_spec_parse_repos.tar +0 −0
  5. gix/tests/fixtures/make_rev_spec_parse_repos.sh +5 −0
  6. gix/tests/gix/revision/spec/from_bytes/mod.rs +6 −0
  7. gix/tests/gix/revision/spec/from_bytes/traverse.rs +10 −2
gix/src/revision/spec/parse/delegate/navigate.rs+7−1
@@ -25,7 +25,13 @@ impl delegate::Navigate for Delegate<'_> { · 24 unmodified lines
2525
2626 let mut replacements = Replacements::default();
2727 let mut errors = Vec::new();
28− let objs = self.objs[self.idx].as_mut()?;
28+ let objs = match self.objs[self.idx].as_mut() {
29+ Some(objs) => objs,
30+ None => {
31+ self.err.push(Error::TraversalWithoutStartObject);
32+ return None;
33+ }
34+ };
2935 let repo = self.repo;
3036
3137 for obj in objs.iter() {
gix/src/revision/spec/parse/error.rs+0−1
@@ -105,7 +105,6 @@ impl Error { · 104 unmodified lines
105105 }
106106
107107 pub(crate) fn from_errors(errors: Vec<Self>) -> Self {
108− assert!(!errors.is_empty());
109108 match errors.len() {
110109 0 => unreachable!(
111110 "BUG: cannot create something from nothing, must have recorded some errors to call from_errors()"
gix/src/revision/spec/parse/types.rs+2−0
@@ -188,6 +188,8 @@ pub enum Error { · 187 unmodified lines
188188 },
189189 #[error(transparent)]
190190 Traverse(#[from] crate::revision::walk::iter::Error),
191+ #[error("Tried to navigate the commit-graph without providing an anchor first")]
192+ TraversalWithoutStartObject,
191193 #[error(transparent)]
192194 Walk(#[from] crate::revision::walk::Error),
193195 #[error("Spec does not contain a single object id")]
gix/tests/fixtures/generated-archives/make_rev_spec_parse_repos.tar+0−0

Binary file not shown.

gix/tests/fixtures/make_rev_spec_parse_repos.sh+5−0
@@ -356,6 +356,7 @@ EOF · 355 unmodified lines
356356 baseline "@^{/!-B}" # negation from branch
357357 baseline ":file" # index lookup, default stage 0
358358 baseline ":1:file" # stage 1
359+ baseline ":5:file" # invalid stage
359360 baseline ":foo" # not found
360361 # parents
361362 baseline "a"
@@ -381,6 +382,10 @@ EOF · 19 unmodified lines
381382 baseline "b^3^2"
382383 baseline "a^^3^2"
383384
385+ # invalid
386+ baseline "^^"
387+ baseline "^^HEAD"
388+
384389 baseline "@{-1}"
385390 baseline "@{-2}"
386391 baseline "@{-3}"
gix/tests/gix/revision/spec/from_bytes/mod.rs+6−0
@@ -64,6 +64,12 @@ mod index { · 63 unmodified lines
6464 "Path \"file\" did not exist in index at stage 1. It does exist at stage 0. It exists on disk",
6565 );
6666
67+ assert_eq!(
68+ parse_spec(":5:file", &repo).unwrap_err().to_string(),
69+ "Path \"5:file\" did not exist in index at stage 0. It does not exist on disk",
70+ "invalid stage ids are interpreted as part of the filename"
71+ );
72+
6773 assert_eq!(
6874 parse_spec(":foo", &repo).unwrap_err().to_string(),
6975 "Path \"foo\" did not exist in index at stage 0. It does not exist on disk",
gix/tests/gix/revision/spec/from_bytes/traverse.rs+10−2
@@ -24,8 +24,16 @@ fn complex() -> crate::Result { · 23 unmodified lines
2424 #[test]
2525 fn freestanding_negation_yields_descriptive_error() -> crate::Result {
2626 let repo = repo("complex_graph")?;
27− let expected = "The rev-spec is malformed and misses a ref name";
28− assert_eq!(parse_spec("^", &repo).unwrap_err().to_string(), expected);
27+ for revspec in ["^^", "^^HEAD"] {
28+ assert_eq!(
29+ parse_spec(revspec, &repo).unwrap_err().to_string(),
30+ "Tried to navigate the commit-graph without providing an anchor first"
31+ );
32+ }
33+ assert_eq!(
34+ parse_spec("^", &repo).unwrap_err().to_string(),
35+ "The rev-spec is malformed and misses a ref name"
36+ );
2937 assert_eq!(
3038 parse_spec("^!", &repo).unwrap_err().to_string(),
3139 "The ref partially named \"!\" could not be found"