From 973e22c89e9b95f4e839e6193ae51aa0c9f8e58f Mon Sep 17 00:00:00 2001 From: Jia Chao Date: Fri, 7 Jun 2024 16:12:36 +0800 Subject: [PATCH] =?UTF-8?q?CVRF:=20=E5=A4=84=E7=90=86=20producttree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jia Chao --- src/lib.rs | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/test.rs | 29 ++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 83955bd..495d2b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -162,6 +162,7 @@ impl CVRF { "DocumentTracking" => self.documenttracking.load_from_xmlreader(xmlreader), "DocumentNotes" => self.handle_notes(xmlreader), "DocumentReferences" => self.handle_references(xmlreader), + "ProductTree" => self.producttree.load_from_xmlreader(xmlreader), _ => {} }, Err(e) => { @@ -583,6 +584,77 @@ impl ProductTree { packages: HashMap::new(), } } + + #[instrument(skip(self, xmlreader))] + fn load_from_xmlreader(&mut self, xmlreader: &mut XmlReader) { + let mut _type = String::new(); + let mut _name = String::new(); + + loop { + match xmlreader.next() { + Ok(XmlEvent::StartElement { attributes, .. }) => { + for attr in attributes { + match attr.name.local_name.as_str() { + "Type" => { + _type = attr.value.clone(); + } + "Name" => { + _name = attr.value.clone(); + } + _ => {} + } + } + } + Ok(XmlEvent::EndElement { .. }) => { + if xmlreader.depth < 2 { + trace!("ProductTree read end."); + break; + } + } + Err(e) => { + error!("XmlReader Error: {e}"); + break; + } + _ => {} + } + + if _type.as_str() == "Product Name" { + self._load_products_branch(xmlreader); + } + if _type.as_str() == "Package Arch" { + self.packages.insert(_name.clone(), vec![]); + self._load_packages_branch(&_name, xmlreader); + } + _type.clear(); + _name.clear(); + } + + } + + #[instrument(skip(self, xmlreader))] + fn _load_products_branch(&mut self, xmlreader: &mut XmlReader) { + loop { + let mut product = Product::new(); + product.load_from_xmlreader(xmlreader); + if xmlreader.depth < 3 { + break; + } + self.products.push(product); + } + } + + #[instrument(skip(self, key, xmlreader))] + fn _load_packages_branch(&mut self, key: &str, xmlreader: &mut XmlReader) { + let packages = self.packages.get_mut(key).unwrap(); + loop { + let mut package = Product::new(); + package.load_from_xmlreader(xmlreader); + if xmlreader.depth < 3 { + break; + } + packages.push(package); + } + } } // depth = 4 @@ -609,6 +681,33 @@ impl Product { content: String::new(), } } + + #[instrument(skip(self, xmlreader))] + fn load_from_xmlreader(&mut self, xmlreader: &mut XmlReader) { + loop { + match xmlreader.next() { + Ok(XmlEvent::StartElement { attributes, .. }) => { + for attr in attributes { + match attr.name.local_name.as_str() { + "ProductID" => self.productid = attr.value.clone(), + "CPE" => self.cpe = attr.value.clone(), + _ => {} + } + } + self.content = xmlreader.next_characters(); + } + Ok(XmlEvent::EndElement { .. }) => { + trace!("Product read end."); + break; + } + Err(e) => { + error!("XmlReader Error: {e}"); + break; + } + _ => {} + } + } + } } // depth = 2 diff --git a/src/test.rs b/src/test.rs index f959fa7..a9baac3 100644 --- a/src/test.rs +++ b/src/test.rs @@ -55,4 +55,33 @@ fn cvrf_works() { assert_eq!(cvrf.documentreferences.len(), 3); assert_eq!(cvrf.documentreferences[1].r#type, reference_type); assert_eq!(cvrf.documentreferences[1].r#url, reference_url); + + // producttree + let producttree_productid = "openEuler-22.03-LTS"; + let producttree_cep = "cpe:/a:openEuler:openEuler:22.03-LTS"; + let producttree_content = "openEuler-22.03-LTS"; + assert_eq!(cvrf.producttree.products.len(), 6); + assert_eq!( + cvrf.producttree.products[2].productid, + producttree_productid + ); + assert_eq!(cvrf.producttree.products[2].cpe, producttree_cep); + assert_eq!(cvrf.producttree.products[2].content, producttree_content); + let producttree_src = "src"; + let producttree_src_productid = "golang-1.17.3-32"; + let producttree_src_cep = "cpe:/a:openEuler:openEuler:22.03-LTS"; + let producttree_src_content = "golang-1.17.3-32.oe2203.src.rpm"; + assert_eq!(cvrf.producttree.packages.len(), 4); + assert_eq!( + cvrf.producttree.packages.get(producttree_src).unwrap()[2].productid, + producttree_src_productid + ); + assert_eq!( + cvrf.producttree.packages.get(producttree_src).unwrap()[2].cpe, + producttree_src_cep + ); + assert_eq!( + cvrf.producttree.packages.get(producttree_src).unwrap()[2].content, + producttree_src_content + ); }