Skip to content

Commit

Permalink
SourceId: some git branches aren't properly serialized
Browse files Browse the repository at this point in the history
This adds a failing test for rust-lang#11085.

For some branch names (or tags or refs), generate_lockfile will
serialize poorly.  Parsing the Cargo.lock will refer to a branch
that wasn't the intended one in Cargo.toml.

Because a branch name can contain the '#' character, the precise
reference could be corrupted through a branch/tag/ref as well.

This is because serialisation is done with a custom Display
implementation that concatenates strings as-is and is unaware
that some characters may need escaping; on the other hand,
deserialization uses url::Url::query_pairs which assumes
<https://url.spec.whatwg.org/#application/x-www-form-urlencoded>.
  • Loading branch information
g2p committed Sep 15, 2022
1 parent aaadab6 commit 2c7ae3d
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/cargo/core/source/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,4 +742,16 @@ mod tests {
let s3 = SourceId::new(foo, loc, None).unwrap();
assert_ne!(s1, s3);
}

#[test]
fn gitrefs_roundtrip() {
let base = "https://host/path".into_url().unwrap();
let branch = GitReference::Branch("*-._+20%30 Z/z#foo=bar&zap[]?to\\()'\"".to_string());
let s1 = SourceId::for_git(&base, branch).unwrap();
let ser1 = format!("{}", s1.as_url());
let s2 = SourceId::from_url(&ser1).expect("Failed to deserialize");
let ser2 = format!("{}", s2.as_url());
assert_eq!(ser1, ser2, "Serialized forms don't match");
assert_eq!(s1, s2, "SourceId doesn't round-trip");
}
}

0 comments on commit 2c7ae3d

Please sign in to comment.