Skip to content

Commit ea957da

Browse files
committed
add the Cows back in and add a test to keep them
1 parent a9f2942 commit ea957da

File tree

4 files changed

+65
-28
lines changed

4 files changed

+65
-28
lines changed

src/cargo/core/summary.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use std::borrow::Borrow;
12
use std::collections::{BTreeMap, HashMap};
3+
use std::fmt::Display;
24
use std::mem;
35
use std::rc::Rc;
46

@@ -30,13 +32,14 @@ struct Inner {
3032
}
3133

3234
impl Summary {
33-
pub fn new(
35+
pub fn new<K>(
3436
pkg_id: PackageId,
3537
dependencies: Vec<Dependency>,
36-
features: BTreeMap<&str, Vec<&str>>,
37-
links: Option<&str>,
38+
features: BTreeMap<K, Vec<impl AsRef<str>>>,
39+
links: Option<impl AsRef<str>>,
3840
namespaced_features: bool,
39-
) -> CargoResult<Summary> {
41+
) -> CargoResult<Summary>
42+
where K: Borrow<str> + Ord + Display {
4043
for dep in dependencies.iter() {
4144
if !namespaced_features && features.get(&*dep.name()).is_some() {
4245
bail!(
@@ -59,7 +62,7 @@ impl Summary {
5962
dependencies,
6063
features: feature_map,
6164
checksum: None,
62-
links: links.map(|l| InternedString::new(&l)),
65+
links: links.map(|l| InternedString::new(l.as_ref())),
6366
namespaced_features,
6467
}),
6568
})
@@ -134,11 +137,12 @@ impl PartialEq for Summary {
134137

135138
// Checks features for errors, bailing out a CargoResult:Err if invalid,
136139
// and creates FeatureValues for each feature.
137-
fn build_feature_map(
138-
features: BTreeMap<&str, Vec<&str>>,
140+
fn build_feature_map<K>(
141+
features: BTreeMap<K, Vec<impl AsRef<str>>>,
139142
dependencies: &[Dependency],
140143
namespaced: bool,
141-
) -> CargoResult<FeatureMap> {
144+
) -> CargoResult<FeatureMap>
145+
where K: Borrow<str> + Ord + Display {
142146
use self::FeatureValue::*;
143147
let mut dep_map = HashMap::new();
144148
for dep in dependencies.iter() {
@@ -149,7 +153,7 @@ fn build_feature_map(
149153
}
150154

151155
let mut map = BTreeMap::new();
152-
for (&feature, list) in features.iter() {
156+
for (feature, list) in features.iter() {
153157
// If namespaced features is active and the key is the same as that of an
154158
// optional dependency, that dependency must be included in the values.
155159
// Thus, if a `feature` is found that has the same name as a dependency, we
@@ -160,7 +164,7 @@ fn build_feature_map(
160164
// as the name of an optional dependency. If so, it gets set to true during
161165
// iteration over the list if the dependency is found in the list.
162166
let mut dependency_found = if namespaced {
163-
match dep_map.get(feature) {
167+
match dep_map.get(feature.borrow()) {
164168
Some(ref dep_data) => {
165169
if !dep_data.iter().any(|d| d.is_optional()) {
166170
bail!(
@@ -186,7 +190,7 @@ fn build_feature_map(
186190
let mut values = vec![];
187191
for dep in list {
188192
let val = FeatureValue::build(
189-
InternedString::new(dep),
193+
InternedString::new(dep.as_ref()),
190194
|fs| features.contains_key(fs.as_str()),
191195
namespaced,
192196
);
@@ -206,7 +210,7 @@ fn build_feature_map(
206210
if let FeatureValue::Crate(ref dep_name) = val {
207211
// If we have a dependency value, check if this is the dependency named
208212
// the same as the feature that we were looking for.
209-
if !dependency_found && feature == dep_name.as_str() {
213+
if !dependency_found && feature.borrow() == dep_name.as_str() {
210214
dependency_found = true;
211215
}
212216
}
@@ -316,7 +320,7 @@ fn build_feature_map(
316320
)
317321
}
318322

319-
map.insert(InternedString::new(&feature), values);
323+
map.insert(InternedString::new(feature.borrow()), values);
320324
}
321325
Ok(map)
322326
}

src/cargo/sources/registry/mod.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,15 @@
158158
//! ...
159159
//! ```
160160
161+
use std::borrow::Cow;
161162
use std::collections::BTreeMap;
162163
use std::fs::File;
163164
use std::path::{Path, PathBuf};
164165

165166
use flate2::read::GzDecoder;
166167
use semver::Version;
168+
#[cfg(test)]
169+
use serde_json;
167170
use tar::Archive;
168171

169172
use core::dependency::{Dependency, Kind};
@@ -211,13 +214,43 @@ pub struct RegistryConfig {
211214

212215
#[derive(Deserialize)]
213216
pub struct RegistryPackage<'a> {
214-
name: &'a str,
217+
name: Cow<'a, str>,
215218
vers: Version,
216219
deps: Vec<RegistryDependency<'a>>,
217-
features: BTreeMap<&'a str, Vec<&'a str>>,
220+
features: BTreeMap<Cow<'a, str>, Vec<Cow<'a, str>>>,
218221
cksum: String,
219222
yanked: Option<bool>,
220-
links: Option<&'a str>,
223+
links: Option<Cow<'a, str>>,
224+
}
225+
226+
#[test]
227+
fn escaped_cher_in_json() {
228+
let _: RegistryPackage = serde_json::from_str(
229+
r#"{"name":"a","vers":"0.0.1","deps":[],"cksum":"bae3","features":{}}"#
230+
).unwrap();
231+
let _: RegistryPackage = serde_json::from_str(
232+
r#"{"name":"a","vers":"0.0.1","deps":[],"cksum":"bae3","features":{"test":["k","q"]},"links":"a-sys"}"#
233+
).unwrap();
234+
235+
// Now we add escaped cher all the places they can go
236+
// these are not valid, but it should error later than json parsing
237+
let _: RegistryPackage = serde_json::from_str(r#"{
238+
"name":"This name has a escaped cher in it \n\t\" ",
239+
"vers":"0.0.1",
240+
"deps":[{
241+
"name": " \n\t\" ",
242+
"req": " \n\t\" ",
243+
"features": [" \n\t\" "],
244+
"optional": true,
245+
"default_features": true,
246+
"target": " \n\t\" ",
247+
"kind": " \n\t\" ",
248+
"registry": " \n\t\" "
249+
}],
250+
"cksum":"bae3",
251+
"features":{"test \n\t\" ":["k \n\t\" ","q \n\t\" "]},
252+
"links":" \n\t\" "}"#
253+
).unwrap();
221254
}
222255

223256
#[derive(Deserialize)]
@@ -234,14 +267,14 @@ enum Field {
234267

235268
#[derive(Deserialize)]
236269
struct RegistryDependency<'a> {
237-
name: &'a str,
238-
req: &'a str,
239-
features: Vec<&'a str>,
270+
name: Cow<'a, str>,
271+
req: Cow<'a, str>,
272+
features: Vec<Cow<'a, str>>,
240273
optional: bool,
241274
default_features: bool,
242-
target: Option<&'a str>,
243-
kind: Option<&'a str>,
244-
registry: Option<&'a str>,
275+
target: Option<Cow<'a, str>>,
276+
kind: Option<Cow<'a, str>>,
277+
registry: Option<Cow<'a, str>>,
245278
}
246279

247280
impl<'a> RegistryDependency<'a> {

src/cargo/util/toml/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ impl TomlManifest {
889889
.as_ref()
890890
.map(|x| {
891891
x.iter()
892-
.map(|(k, v)| (k.as_str(), v.iter().map(|s| s.as_str()).collect()))
892+
.map(|(k, v)| (k.as_str(), v.iter().collect()))
893893
.collect()
894894
})
895895
.unwrap_or_else(BTreeMap::new),

tests/testsuite/resolve.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn resolve_with_config(
3838
}
3939
}
4040
let mut registry = MyRegistry(registry);
41-
let summary = Summary::new(pkg.clone(), deps, BTreeMap::new(), None, false).unwrap();
41+
let summary = Summary::new(pkg.clone(), deps, BTreeMap::<String, Vec<String>>::new(), None::<String>, false).unwrap();
4242
let method = Method::Everything;
4343
let resolve = resolver::resolve(
4444
&[(summary, method)],
@@ -100,13 +100,13 @@ macro_rules! pkg {
100100
let pkgid = $pkgid.to_pkgid();
101101
let link = if pkgid.name().ends_with("-sys") {Some(pkgid.name().as_str())} else {None};
102102

103-
Summary::new(pkgid, d, BTreeMap::new(), link, false).unwrap()
103+
Summary::new(pkgid, d, BTreeMap::<String, Vec<String>>::new(), link, false).unwrap()
104104
});
105105

106106
($pkgid:expr) => ({
107107
let pkgid = $pkgid.to_pkgid();
108108
let link = if pkgid.name().ends_with("-sys") {Some(pkgid.name().as_str())} else {None};
109-
Summary::new(pkgid, Vec::new(), BTreeMap::new(), link, false).unwrap()
109+
Summary::new(pkgid, Vec::new(), BTreeMap::<String, Vec<String>>::new(), link, false).unwrap()
110110
})
111111
}
112112

@@ -121,7 +121,7 @@ fn pkg(name: &str) -> Summary {
121121
} else {
122122
None
123123
};
124-
Summary::new(pkg_id(name), Vec::new(), BTreeMap::new(), link, false).unwrap()
124+
Summary::new(pkg_id(name), Vec::new(), BTreeMap::<String, Vec<String>>::new(), link, false).unwrap()
125125
}
126126

127127
fn pkg_id(name: &str) -> PackageId {
@@ -145,7 +145,7 @@ fn pkg_loc(name: &str, loc: &str) -> Summary {
145145
Summary::new(
146146
pkg_id_loc(name, loc),
147147
Vec::new(),
148-
BTreeMap::new(),
148+
BTreeMap::<String, Vec<String>>::new(),
149149
link,
150150
false,
151151
).unwrap()

0 commit comments

Comments
 (0)