Skip to content

Commit da2f573

Browse files
committed
SourceId: some git branches aren't properly serialized
This adds a failing test for #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>.
1 parent 22dd4bf commit da2f573

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

src/cargo/core/source/source_id.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,4 +742,16 @@ mod tests {
742742
let s3 = SourceId::new(foo, loc, None).unwrap();
743743
assert_ne!(s1, s3);
744744
}
745+
746+
#[test]
747+
fn gitrefs_roundtrip() {
748+
let base = "https://host/path".into_url().unwrap();
749+
let branch = GitReference::Branch("*-._+20%30 Z/z#foo".to_string());
750+
let s1 = SourceId::for_git(&base, branch).unwrap();
751+
let ser1 = format!("{}", s1.as_url());
752+
let s2 = SourceId::from_url(&ser1).expect("Failed to deserialize");
753+
let ser2 = format!("{}", s2.as_url());
754+
assert_eq!(ser1, ser2, "Serialized forms don't match");
755+
assert_eq!(s1, s2, "SourceId doesn't round-trip");
756+
}
745757
}

0 commit comments

Comments
 (0)