Skip to content

Commit 2e9fbb1

Browse files
TC-2150 License ID with Spaces not captured properly (trustification#2147)
Co-authored-by: Carlos Feria <carlosthe19916@gmail.com>
1 parent ee73925 commit 2e9fbb1

File tree

5 files changed

+73864
-144
lines changed

5 files changed

+73864
-144
lines changed

spog/api/src/endpoints/license.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ pub async fn download_licenses(
4242
let sbom_id = id.into_inner();
4343
let sbom = get_sbom(state, sbom_id.as_str(), &token).await?;
4444
let scanner = license_scanner::LicenseScanner::new(sbom);
45-
let sbom_licenses = scanner.scanner()?;
45+
let (sbom_licenses, extracted_licensing_info) = scanner.scanner()?;
4646

4747
let sbom_name = sbom_licenses.sbom_name.clone();
48-
let exporter = license_exporter::LicenseExporter::new(sbom_licenses);
48+
let exporter = license_exporter::LicenseExporter::new(sbom_licenses, extracted_licensing_info);
4949
let zip = exporter.generate()?;
5050

5151
Ok(HttpResponse::Ok()

spog/api/src/license/license_exporter.rs

+59-33
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::license::SbomLicense;
1+
use crate::license::{ExtractedLicensingInfos, SbomLicense};
22
use crate::utils::get_sanitize_filename;
33
use actix_web::body::BoxBody;
44
use actix_web::http::header::ContentType;
@@ -7,14 +7,14 @@ use csv::WriterBuilder;
77
use flate2::write::GzEncoder;
88
use flate2::Compression;
99
use http::StatusCode;
10-
use std::collections::HashSet;
1110
use tar::Builder;
1211
use trustification_common::error::ErrorInformation;
1312

1413
extern crate sanitize_filename;
1514

1615
pub struct LicenseExporter {
1716
sbom_license: SbomLicense,
17+
extracted_licensing_infos: Vec<ExtractedLicensingInfos>,
1818
}
1919

2020
#[derive(Debug, thiserror::Error)]
@@ -63,8 +63,11 @@ impl ResponseError for LicenseExporterError {
6363
}
6464

6565
impl LicenseExporter {
66-
pub fn new(sbom_license: SbomLicense) -> Self {
67-
LicenseExporter { sbom_license }
66+
pub fn new(sbom_license: SbomLicense, extracted_licensing_infos: Vec<ExtractedLicensingInfos>) -> Self {
67+
LicenseExporter {
68+
sbom_license,
69+
extracted_licensing_infos,
70+
}
6871
}
6972

7073
pub fn generate(&self) -> Result<Vec<u8>, LicenseExporterError> {
@@ -86,12 +89,21 @@ impl LicenseExporter {
8689
"group",
8790
"version",
8891
"package reference",
89-
"license",
92+
"license id",
9093
"license name",
94+
"license expression",
9195
"alternate package reference",
9296
])?;
9397

94-
let mut license_ref_key: HashSet<String> = HashSet::new();
98+
for extracted_licensing_info in &self.extracted_licensing_infos {
99+
wtr_license_ref.write_record([
100+
extracted_licensing_info.license_id.as_str(),
101+
extracted_licensing_info.name.as_str(),
102+
extracted_licensing_info.extracted_text.as_str(),
103+
extracted_licensing_info.comment.as_str(),
104+
])?;
105+
}
106+
95107
for pl in &self.sbom_license.packages {
96108
let alternate_package_reference = pl
97109
.other_reference
@@ -100,28 +112,24 @@ impl LicenseExporter {
100112
.collect::<Vec<_>>()
101113
.join("\n");
102114

103-
for l in &pl.licenses {
104-
wtr_sbom.write_record([
105-
&pl.name,
106-
&self.sbom_license.sbom_namespace,
107-
&self.sbom_license.component_group,
108-
&self.sbom_license.component_version,
109-
&pl.purl,
110-
l.license_id.as_str(),
111-
l.name.as_str(),
112-
alternate_package_reference.as_str(),
113-
])?;
114-
115-
if l.is_license_ref && !license_ref_key.contains(&l.license_id) {
116-
wtr_license_ref.write_record([
117-
l.license_id.as_str(),
118-
l.name.as_str(),
119-
l.license_text.as_str(),
120-
l.license_comment.as_str(),
121-
])?;
122-
license_ref_key.insert(String::from(&l.license_id));
123-
}
124-
}
115+
let spdx_licenses = pl
116+
.spdx_licenses
117+
.iter()
118+
.map(|reference| reference.as_str())
119+
.collect::<Vec<_>>()
120+
.join("\n");
121+
122+
wtr_sbom.write_record([
123+
&pl.name,
124+
&self.sbom_license.sbom_namespace,
125+
&self.sbom_license.component_group,
126+
&self.sbom_license.component_version,
127+
&pl.purl,
128+
&spdx_licenses,
129+
&pl.license_name,
130+
&pl.license_text,
131+
alternate_package_reference.as_str(),
132+
])?;
125133
}
126134

127135
let sbom_csv = wtr_sbom
@@ -199,29 +207,47 @@ mod tests {
199207

200208
let license_scanner = LicenseScanner::new(sbom);
201209

202-
let sbom_licenses = license_scanner
210+
let (sbom_licenses, extracted_licensing_info) = license_scanner
203211
.scanner()
204212
.unwrap_or_else(|_| panic!("failed to parse test data"));
205213

206-
let export = LicenseExporter::new(sbom_licenses);
214+
let export = LicenseExporter::new(sbom_licenses, extracted_licensing_info);
207215
let mut file =
208216
File::create("/tmp/application.cdx_licenses.tar.gz").unwrap_or_else(|_| panic!("create file failed"));
209217
file.write_all(&export.generate().unwrap_or_else(|_| panic!("generate failed")))
210218
.unwrap_or_else(|_| panic!("write file failed"));
211219
}
212220

221+
#[tokio::test]
222+
async fn is_works_cydx_with_cpe() {
223+
let sbom = load_sbom_file("../test-data/tc_1730_license_escape.json")
224+
.unwrap_or_else(|_| panic!("failed to parse test data"));
225+
226+
let license_scanner = LicenseScanner::new(sbom);
227+
228+
let (sbom_licenses, extracted_licensing_info) = license_scanner
229+
.scanner()
230+
.unwrap_or_else(|_| panic!("failed to parse test data"));
231+
232+
let export = LicenseExporter::new(sbom_licenses, extracted_licensing_info);
233+
let mut file =
234+
File::create("/tmp/tc_1730_license_escape.tar.gz").unwrap_or_else(|_| panic!("create file failed"));
235+
file.write_all(&export.generate().unwrap_or_else(|_| panic!("generate failed")))
236+
.unwrap_or_else(|_| panic!("write file failed"));
237+
}
238+
213239
#[tokio::test]
214240
async fn is_works_spdx() {
215241
let sbom = load_sbom_file("../test-data/mtv-2.6.json").unwrap_or_else(|_| panic!("failed to parse test data"));
216242

217243
let license_scanner = LicenseScanner::new(sbom);
218244

219-
let sbom_licenses = license_scanner
245+
let (sbom_licenses, extracted_licensing_info) = license_scanner
220246
.scanner()
221247
.unwrap_or_else(|_| panic!("failed to parse test data"));
222248

223-
let export = LicenseExporter::new(sbom_licenses);
224-
let mut file = File::create("/tmp/mtv-2.6_licenses.tar.gz").unwrap_or_else(|_| panic!("create file failed"));
249+
let export = LicenseExporter::new(sbom_licenses, extracted_licensing_info);
250+
let mut file = File::create("/tmp/mtv-2.6.tar.gz").unwrap_or_else(|_| panic!("create file failed"));
225251
file.write_all(&export.generate().unwrap_or_else(|_| panic!("generate failed")))
226252
.unwrap_or_else(|_| panic!("write file failed"));
227253
}

0 commit comments

Comments
 (0)