Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+182
View File
@@ -0,0 +1,182 @@
//! 自有签名、归档和 Lib 输入验证;不连接生产 deverd 或修改机器缓存。
mod central;
mod pep517;
mod pep517_fixture;
mod python;
mod python_fixture;
use super::{Fixture, fixture::digest, write};
use dever::compiler::project::dependency::{
library::{Spec, archive},
worker::signed::SignedResources,
};
use ring::signature::{Ed25519KeyPair, KeyPair};
use std::io::Write;
#[test]
fn lib_identities_normalize_extras_and_reject_ranges_and_path_injection() {
assert_eq!(
"pip:Some_Name[TEST,docs]@1.2.3"
.parse::<Spec>()
.unwrap()
.key(),
"pip:some-name[docs,test]@1.2.3"
);
assert_eq!(
"go:example.org/widget@v1.2.3"
.parse::<Spec>()
.unwrap()
.version,
"1.2.3"
);
assert_eq!(
"npm:@scope/name@1.2.3".parse::<Spec>().unwrap().name,
"@scope/name"
);
for value in [
"npm:thing@^1",
"npm:../thing@1.2.3",
"pip:thing[]@1",
"pip:thing@>=1",
"go:../thing@1.2.3",
"npm:@scope/../thing@1.2.3",
] {
assert!(value.parse::<Spec>().is_err(), "accepted {value}");
}
}
#[test]
fn installed_resources_require_independent_signature_and_exact_catalog_bytes() {
let fixture = Fixture::new(&[]);
let root = fixture.directory.0.join("installation");
let key = Ed25519KeyPair::from_seed_unchecked(&[91; 32]).unwrap();
let hex = |bytes: &[u8]| {
bytes
.iter()
.map(|byte| format!("{byte:02x}"))
.collect::<String>()
};
write(
&root,
"state/trusted-release-key",
hex(key.public_key().as_ref()),
);
let bytes = b"signed fixture contents";
let path = "runtime/npm/linux-x86_64/runtime.pack";
let target = dever::compiler::toolchain::BuildTarget::host().unwrap();
let catalog = serde_json::to_vec(&serde_json::json!({"format":"dever-release-v2","version":"0.0.1","platform":target.name(),"artifacts":[{"path":"base.txt","bytes":bytes.len(),"sha256":digest(bytes)}],"extensions":[{"kind":{"type":"runtime","ecosystem":"npm"},"target":"linux-x86_64","artifacts":[{"path":path,"bytes":bytes.len(),"sha256":digest(bytes)}]}]})).unwrap();
write(&root, "versions/0.0.1/base.txt", bytes);
write(&root, "versions/0.0.1/manifest.json", &catalog);
write(
&root,
"versions/0.0.1/manifest.sig",
hex(key.sign(&catalog).as_ref()),
);
let signed = SignedResources::load(&root, "0.0.1").unwrap();
assert_eq!(signed.read("base.txt").unwrap(), bytes);
let actual = signed.read_with(path, |version, catalog_hash, extension, artifact| {
assert_eq!(version, "0.0.1");
assert_eq!(catalog_hash, digest(&catalog));
assert_eq!(extension, &serde_json::json!({"kind":{"type":"runtime","ecosystem":"npm"},"target":"linux-x86_64"}));
assert_eq!(artifact.path, path);
Ok(bytes.to_vec())
}).unwrap();
assert_eq!(actual, bytes);
assert!(
signed
.read_with(path, |_, _, _, _| Ok(b"changed".to_vec()))
.is_err()
);
write(&root, "versions/0.0.1/base.txt", b"different signed file");
assert!(signed.read("base.txt").is_err());
write(&root, "versions/0.0.1/manifest.json", b"{}");
assert!(SignedResources::load(&root, "0.0.1").is_err());
}
#[test]
fn archive_consumption_rejects_links_and_file_directory_collisions() {
let make = |entries: &[(&str, &[u8], tar::EntryType)]| {
let gzip = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::fast());
let mut archive = tar::Builder::new(gzip);
for (path, bytes, kind) in entries {
let mut header = tar::Header::new_gnu();
header.set_entry_type(*kind);
header.set_size(bytes.len() as u64);
header.set_mode(0o755);
header.set_cksum();
archive.append_data(&mut header, path, *bytes).unwrap();
}
archive.into_inner().unwrap().finish().unwrap()
};
let bytes = make(&[(
"package/main.js",
b"export const value = 42;",
tar::EntryType::Regular,
)]);
assert_eq!(archive::files(&bytes, false).unwrap().len(), 1);
assert!(archive::entries(&bytes, false).unwrap()["package/main.js"].1);
let bytes = make(&[("package/main.js", b"", tar::EntryType::Symlink)]);
assert!(archive::files(&bytes, false).unwrap_err().contains("links"));
let bytes = make(&[
("package", b"not a directory", tar::EntryType::Regular),
("package/main.js", b"", tar::EntryType::Regular),
]);
assert!(
archive::files(&bytes, false)
.unwrap_err()
.contains("collision")
);
let mut zip = zip::ZipWriter::new(std::io::Cursor::new(Vec::new()));
zip.start_file("../escape", zip::write::SimpleFileOptions::default())
.unwrap();
zip.write_all(b"bad").unwrap();
assert!(archive::files(&zip.finish().unwrap().into_inner(), true).is_err());
}
#[test]
fn lib_zip_rejects_duplicate_central_paths() {
let mut zip = zip::ZipWriter::new(std::io::Cursor::new(Vec::new()));
for name in ["package/first", "package/other"] {
zip.start_file(
name,
zip::write::SimpleFileOptions::default().unix_permissions(0o755),
)
.unwrap();
zip.write_all(name.as_bytes()).unwrap();
}
let mut bytes = zip.finish().unwrap().into_inner();
let files = archive::entries(&bytes, true).unwrap();
assert_eq!(files.len(), 2);
assert!(files["package/first"].1);
let mut cursor = 0;
while cursor + 5 <= bytes.len() {
if &bytes[cursor..cursor + 5] == b"other" {
bytes[cursor..cursor + 5].copy_from_slice(b"first");
}
cursor += 1;
}
assert!(
archive::entries(&bytes, true)
.unwrap_err()
.contains("duplicate or inconsistent")
);
}
#[test]
fn python_wheel_identity_abi_and_dependency_edges_are_checked_before_installation() {
let bytes = python_fixture::wheel("tiny", "1.0.0", "");
let lib = serde_json::from_value(serde_json::json!({"spec":{"ecosystem":"pip","name":"tiny","version":"1.0.0"},"dependencies":[],"runtime":{"name":"python","version":"3.12.1","sha256":"0".repeat(64)},"artifacts":[],"schema":"pypi-wheel-v1"})).unwrap();
let markers = serde_json::json!({"implementation_name":"cpython","implementation_version":"3.12.1","os_name":"posix","platform_machine":"x86_64","platform_python_implementation":"CPython","platform_release":"","platform_system":"Linux","platform_version":"","python_full_version":"3.12.1","python_version":"3.12","sys_platform":"linux"});
let mut runtime = serde_json::from_value::<dever::compiler::project::dependency::library::runtime::Manifest>(serde_json::json!({"format":"dever-worker-runtime-v1","ecosystem":"pip","target":"linux-x86_64","executable":"bin/python3","arguments":["-I","-S","-B"],"python_wheel_tags":["py3-none-any"],"python_extension_suffixes":[".so"],"python_markers":markers})).unwrap();
let files =
dever::compiler::project::dependency::library::python::install(&lib, &bytes, &runtime, &[])
.unwrap();
assert_eq!(files["tiny/__init__.py"], b"VALUE = 42\n");
runtime.python_wheel_tags.clear();
assert!(
dever::compiler::project::dependency::library::python::install(&lib, &bytes, &runtime, &[])
.unwrap_err()
.contains("tags")
);
}