1 //! Tests for parsing RustSec advisories
2 
3 #![warn(rust_2018_idioms, unused_qualifications)]
4 
5 use rustsec::advisory::Category;
6 use std::path::Path;
7 
8 /// Example RustSec Advisory to use for tests
9 const EXAMPLE_V3_ADVISORY_PATH: &str = "./tests/support/example_advisory_v3.md";
10 
11 /// Load example V3 advisory from the filesystem
load_example_v3_advisory() -> rustsec::Advisory12 fn load_example_v3_advisory() -> rustsec::Advisory {
13     rustsec::Advisory::load_file(Path::new(EXAMPLE_V3_ADVISORY_PATH)).unwrap()
14 }
15 
16 /// Load example V4 advisory from the filesystem
load_example_v4_advisory() -> rustsec::Advisory17 fn load_example_v4_advisory() -> rustsec::Advisory {
18     rustsec::Advisory::load_file(Path::new("./tests/support/example_advisory_v4.md")).unwrap()
19 }
20 
21 /// Basic metadata
22 #[test]
parse_metadata()23 fn parse_metadata() {
24     for advisory in &[load_example_v3_advisory(), load_example_v4_advisory()] {
25         assert_eq!(advisory.metadata.id.as_str(), "RUSTSEC-2001-2101");
26         assert_eq!(advisory.metadata.package.as_str(), "base");
27         assert_eq!(advisory.title(), "All your base are belong to us");
28         assert_eq!(
29             advisory.description(),
30             "You have no chance to survive. Make your time."
31         );
32         assert_eq!(advisory.metadata.date.as_str(), "2001-02-03");
33         assert_eq!(
34             advisory.metadata.url.as_ref().unwrap().to_string(),
35             "https://www.youtube.com/watch?v=jQE66WA2s-A"
36         );
37 
38         for (i, category) in [Category::CodeExecution, Category::PrivilegeEscalation]
39             .iter()
40             .enumerate()
41         {
42             assert_eq!(*category, advisory.metadata.categories[i]);
43         }
44 
45         for (i, kw) in ["how", "are", "you", "gentlemen"].iter().enumerate() {
46             assert_eq!(*kw, advisory.metadata.keywords[i].as_str());
47         }
48     }
49 }
50 
51 /// Parsing of impact metadata
52 #[test]
parse_affected()53 fn parse_affected() {
54     let affected = load_example_v3_advisory().affected.unwrap();
55     assert_eq!(affected.arch[0], platforms::target::Arch::X86);
56     assert_eq!(affected.os[0], platforms::target::OS::Windows);
57 
58     let example_function = "base::belongs::All".parse().unwrap();
59     let req = &affected.functions.get(&example_function).unwrap()[0];
60     assert!(req.matches(&"1.2.2".parse().unwrap()));
61     assert!(!req.matches(&"1.2.3".parse().unwrap()));
62 }
63 
64 /// Parsing of other aliased advisory IDs
65 #[test]
parse_aliases()66 fn parse_aliases() {
67     let alias = &load_example_v3_advisory().metadata.aliases[0];
68     assert!(alias.is_cve());
69     assert_eq!(alias.year().unwrap(), 2001);
70 }
71 
72 /// Parsing of CVSS v3.1 severity vector strings
73 #[test]
parse_cvss_vector_string()74 fn parse_cvss_vector_string() {
75     let advisory = load_example_v3_advisory();
76     assert_eq!(
77         advisory.severity().unwrap(),
78         rustsec::advisory::Severity::Critical
79     );
80 
81     let cvss = advisory.metadata.cvss.unwrap();
82     assert_eq!(cvss.av.unwrap(), cvss::v3::base::av::AttackVector::Network);
83     assert_eq!(cvss.ac.unwrap(), cvss::v3::base::ac::AttackComplexity::Low);
84     assert_eq!(
85         cvss.pr.unwrap(),
86         cvss::v3::base::pr::PrivilegesRequired::None
87     );
88     assert_eq!(cvss.ui.unwrap(), cvss::v3::base::ui::UserInteraction::None);
89     assert_eq!(cvss.s.unwrap(), cvss::v3::base::s::Scope::Changed);
90     assert_eq!(cvss.c.unwrap(), cvss::v3::base::c::Confidentiality::High);
91     assert_eq!(cvss.i.unwrap(), cvss::v3::base::i::Integrity::High);
92     assert_eq!(cvss.a.unwrap(), cvss::v3::base::a::Availability::High);
93     assert_eq!(cvss.score().value(), 10.0);
94 }
95 
96 /// Parsing of patched version reqs
97 #[test]
parse_patched_version_reqs()98 fn parse_patched_version_reqs() {
99     let advisory = load_example_v3_advisory();
100     let req = &advisory.versions.patched()[0];
101     assert!(!req.matches(&"1.2.2".parse().unwrap()));
102     assert!(req.matches(&"1.2.3".parse().unwrap()));
103     assert!(req.matches(&"1.2.4".parse().unwrap()));
104 }
105