Skip to content

Commit 3932e8d

Browse files
Merge pull request #591 from sgrif/sg-check-canon-crate-name-on-upload
canonicalize crate name before checking if it's reserved
2 parents 9cb919f + a740f39 commit 3932e8d

File tree

4 files changed

+59
-44
lines changed

4 files changed

+59
-44
lines changed

src/bin/migrate.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,43 @@ fn migrations() -> Vec<Migration> {
831831
tx.execute("DROP INDEX badges_crate_type", &[])?;
832832
Ok(())
833833
}),
834+
Migration::new(20170305095748, |tx| {
835+
tx.batch_execute("
836+
CREATE TABLE reserved_crate_names (
837+
name TEXT PRIMARY KEY
838+
);
839+
CREATE UNIQUE INDEX ON reserved_crate_names (canon_crate_name(name));
840+
INSERT INTO reserved_crate_names (name) VALUES
841+
('alloc'), ('arena'), ('ast'), ('builtins'), ('collections'),
842+
('compiler-builtins'), ('compiler-rt'), ('compiletest'), ('core'), ('coretest'),
843+
('debug'), ('driver'), ('flate'), ('fmt_macros'), ('grammar'), ('graphviz'),
844+
('macro'), ('macros'), ('proc_macro'), ('rbml'), ('rust-installer'), ('rustbook'),
845+
('rustc'), ('rustc_back'), ('rustc_borrowck'), ('rustc_driver'), ('rustc_llvm'),
846+
('rustc_resolve'), ('rustc_trans'), ('rustc_typeck'), ('rustdoc'), ('rustllvm'),
847+
('rustuv'), ('serialize'), ('std'), ('syntax'), ('test'), ('unicode');
848+
849+
CREATE FUNCTION ensure_crate_name_not_reserved() RETURNS trigger AS $$
850+
BEGIN
851+
IF canon_crate_name(NEW.name) IN (
852+
SELECT canon_crate_name(name) FROM reserved_crate_names
853+
) THEN
854+
RAISE EXCEPTION 'cannot upload crate with reserved name';
855+
END IF;
856+
RETURN NEW;
857+
END;
858+
$$ LANGUAGE plpgsql;
859+
860+
CREATE TRIGGER trigger_ensure_crate_name_not_reserved
861+
BEFORE INSERT OR UPDATE ON crates
862+
FOR EACH ROW EXECUTE PROCEDURE ensure_crate_name_not_reserved();
863+
")?;
864+
Ok(())
865+
}, |tx| {
866+
tx.execute("DROP TRIGGER trigger_ensure_crate_name_not_reserved ON crates", &[])?;
867+
tx.execute("DROP FUNCTION ensure_crate_name_not_reserved()", &[])?;
868+
tx.execute("DROP TABLE reserved_crate_names", &[])?;
869+
Ok(())
870+
}),
834871
];
835872
// NOTE: Generate a new id via `date +"%Y%m%d%H%M%S"`
836873

src/krate.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ impl Crate {
152152
None => {}
153153
}
154154

155-
// Blacklist the current set of crates in the rust distribution
156-
const RESERVED: &'static str = include_str!("reserved_crates.txt");
157-
158-
if RESERVED.lines().any(|krate| name == krate) {
155+
let stmt = conn.prepare("SELECT 1 FROM reserved_crate_names
156+
WHERE canon_crate_name(name) =
157+
canon_crate_name($1)")?;
158+
let rows = stmt.query(&[&name])?;
159+
if !rows.is_empty() {
159160
return Err(human("cannot upload a crate with a reserved name"))
160161
}
161162

src/reserved_crates.txt

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/tests/krate.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,23 @@ fn new_krate() {
346346
assert_eq!(json.krate.max_version, "1.0.0");
347347
}
348348

349+
#[test]
350+
fn new_krate_with_reserved_name() {
351+
fn test_bad_name(name: &str) {
352+
let (_b, app, middle) = ::app();
353+
let mut req = ::new_req(app, name, "1.0.0");
354+
::mock_user(&mut req, ::user("foo"));
355+
let json = bad_resp!(middle.call(&mut req));
356+
assert!(json.errors[0].detail.contains("cannot upload a crate with a reserved name"));
357+
}
358+
359+
test_bad_name("std");
360+
test_bad_name("STD");
361+
test_bad_name("compiler-rt");
362+
test_bad_name("compiler_rt");
363+
test_bad_name("coMpiLer_Rt");
364+
}
365+
349366
#[test]
350367
fn new_krate_weird_version() {
351368
let (_b, app, middle) = ::app();

0 commit comments

Comments
 (0)