Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmSpdx.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmSpdx.h"
4
5
#include <stdexcept>
6
#include <string>
7
8
#include "cmSbomSerializer.h"
9
10
inline void SerializeIfPresent(cmSbomSerializer& s, std::string const& key,
11
                               cm::optional<std::string> const& v)
12
0
{
13
0
  if (v) {
14
0
    s.AddString(key, *v);
15
0
  }
16
0
}
17
18
std::string to_string(cmSpdxIntegrityMethod::HashAlgorithmId id)
19
0
{
20
0
  switch (id) {
21
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::ADLER32:
22
0
      return "ADLER32";
23
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B256:
24
0
      return "BLAKE2B256";
25
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B384:
26
0
      return "BLAKE2B384";
27
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B512:
28
0
      return "BLAKE2B512";
29
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE3:
30
0
      return "BLAKE3";
31
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::MD2:
32
0
      return "MD2";
33
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::MD4:
34
0
      return "MD4";
35
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::MD5:
36
0
      return "MD5";
37
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::MD6:
38
0
      return "MD6";
39
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA1:
40
0
      return "SHA1";
41
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA224:
42
0
      return "SHA224";
43
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA256:
44
0
      return "SHA256";
45
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA384:
46
0
      return "SHA384";
47
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA512:
48
0
      return "SHA512";
49
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_256:
50
0
      return "SHA3_256";
51
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_384:
52
0
      return "SHA3_384";
53
0
    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_512:
54
0
      return "SHA3_512";
55
0
  }
56
0
  throw std::invalid_argument("Unknown HashAlgorithmId");
57
0
}
58
59
std::string to_string(cmSpdxSoftwareArtifact::PurposeId id)
60
0
{
61
0
  switch (id) {
62
0
    case cmSpdxSoftwareArtifact::PurposeId::APPLICATION:
63
0
      return "application";
64
0
    case cmSpdxSoftwareArtifact::PurposeId::ARCHIVE:
65
0
      return "archive";
66
0
    case cmSpdxSoftwareArtifact::PurposeId::CONTAINER:
67
0
      return "container";
68
0
    case cmSpdxSoftwareArtifact::PurposeId::DATA:
69
0
      return "data";
70
0
    case cmSpdxSoftwareArtifact::PurposeId::DEVICE:
71
0
      return "device";
72
0
    case cmSpdxSoftwareArtifact::PurposeId::FIRMWARE:
73
0
      return "firmware";
74
0
    case cmSpdxSoftwareArtifact::PurposeId::FILE:
75
0
      return "file";
76
0
    case cmSpdxSoftwareArtifact::PurposeId::INSTALL:
77
0
      return "install";
78
0
    case cmSpdxSoftwareArtifact::PurposeId::LIBRARY:
79
0
      return "library";
80
0
    case cmSpdxSoftwareArtifact::PurposeId::MODULE:
81
0
      return "module";
82
0
    case cmSpdxSoftwareArtifact::PurposeId::OPERATING_SYSTEM:
83
0
      return "operatingSystem";
84
0
    case cmSpdxSoftwareArtifact::PurposeId::SOURCE:
85
0
      return "source";
86
0
  }
87
0
  throw std::invalid_argument("Unknown PurposeId");
88
0
}
89
90
std::string to_string(cmSpdxSbom::TypeId id)
91
0
{
92
0
  switch (id) {
93
0
    case cmSpdxSbom::TypeId::ANALYZED:
94
0
      return "analyzed";
95
0
    case cmSpdxSbom::TypeId::BUILD:
96
0
      return "build";
97
0
    case cmSpdxSbom::TypeId::DEPLOYED:
98
0
      return "deployed";
99
0
    case cmSpdxSbom::TypeId::DESIGN:
100
0
      return "design";
101
0
    case cmSpdxSbom::TypeId::RUNTIME:
102
0
      return "runtime";
103
0
    case cmSpdxSbom::TypeId::SOURCE:
104
0
      return "source";
105
0
    case cmSpdxSbom::TypeId::TEST:
106
0
      return "test";
107
0
  }
108
0
  throw std::invalid_argument("Unknown Sbom::TypeId");
109
0
}
110
111
std::string to_string(cmSpdxFile::FileKindId id)
112
0
{
113
0
  switch (id) {
114
0
    case cmSpdxFile::FileKindId::DIRECTORY:
115
0
      return "directory";
116
0
    case cmSpdxFile::FileKindId::FILE:
117
0
      return "file";
118
0
  }
119
0
  throw std::invalid_argument("Unknown File::FileKindId");
120
0
}
121
122
std::string to_string(cmSpdxRelationship::RelationshipTypeId id)
123
0
{
124
0
  switch (id) {
125
0
    case cmSpdxRelationship::RelationshipTypeId::DESCRIBES:
126
0
      return "describes";
127
0
    case cmSpdxRelationship::RelationshipTypeId::CONTAINS:
128
0
      return "contains";
129
0
    case cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON:
130
0
      return "dependsOn";
131
0
    case cmSpdxRelationship::RelationshipTypeId::OTHER:
132
0
      return "other";
133
0
  }
134
0
  throw std::invalid_argument("Unknown RelationshipTypeId");
135
0
}
136
137
std::string to_string(cmSpdxLifecycleScopedRelationship::ScopeId id)
138
0
{
139
0
  switch (id) {
140
0
    case cmSpdxLifecycleScopedRelationship::ScopeId::BUILD:
141
0
      return "build";
142
0
    case cmSpdxLifecycleScopedRelationship::ScopeId::DESIGN:
143
0
      return "design";
144
0
    case cmSpdxLifecycleScopedRelationship::ScopeId::RUNTIME:
145
0
      return "runtime";
146
0
    case cmSpdxLifecycleScopedRelationship::ScopeId::TEST:
147
0
      return "test";
148
0
  }
149
0
  throw std::invalid_argument("Unknown Lifecycle ScopeId");
150
0
}
151
152
std::string to_string(cmSpdxAnnotation::AnnotationTypeId id)
153
0
{
154
0
  switch (id) {
155
0
    case cmSpdxAnnotation::AnnotationTypeId::REVIEW:
156
0
      return "review";
157
0
    case cmSpdxAnnotation::AnnotationTypeId::OTHER:
158
0
      return "other";
159
0
  }
160
0
  throw std::invalid_argument("Unknown AnnotationTypeId");
161
0
}
162
163
std::string to_string(cmSpdxArtifact::SupportTypeId id)
164
0
{
165
0
  switch (id) {
166
0
    case cmSpdxArtifact::SupportTypeId::COMMUNITY:
167
0
      return "community";
168
0
    case cmSpdxArtifact::SupportTypeId::COMMERCIAL:
169
0
      return "commercial";
170
0
    case cmSpdxArtifact::SupportTypeId::NONE:
171
0
      return "none";
172
0
  }
173
0
  throw std::invalid_argument("Unknown SupportTypeId");
174
0
}
175
176
void cmSpdxExternalIdentifier::Serialize(cmSbomSerializer& serializer) const
177
0
{
178
0
  serializer.AddString("type", "ExternalIdentifier");
179
0
  SerializeIfPresent(serializer, "externalIdentifierType",
180
0
                     ExternalIdentifierType);
181
0
  SerializeIfPresent(serializer, "identifier", Identifier);
182
0
  SerializeIfPresent(serializer, "comment", Comment);
183
0
  SerializeIfPresent(serializer, "identifierLocation", IdentifierLocation);
184
0
  SerializeIfPresent(serializer, "issuingAuthority", IssuingAuthority);
185
0
}
186
187
void cmSpdxExternalRef::Serialize(cmSbomSerializer& serializer) const
188
0
{
189
0
  serializer.AddString("type", "ExternalRef");
190
0
  SerializeIfPresent(serializer, "externalRefType", ExternalRefType);
191
0
  SerializeIfPresent(serializer, "locator", Locator);
192
0
  SerializeIfPresent(serializer, "contentType", ContentType);
193
0
  SerializeIfPresent(serializer, "comment", Comment);
194
0
}
195
196
void cmSpdxChecksum::Serialize(cmSbomSerializer& serializer) const
197
0
{
198
0
  serializer.AddString("type", "Checksum");
199
0
  serializer.AddString("algorithm", to_string(Algorithm));
200
0
  serializer.AddString("checksumValue", ChecksumValue);
201
0
}
202
203
void cmSpdxCreationInfo::Serialize(cmSbomSerializer& serializer) const
204
0
{
205
0
  serializer.AddString("type", "CreationInfo");
206
0
  SerializeIfPresent(serializer, "@id", SpdxId);
207
0
  if (SpecVersion) {
208
0
    serializer.AddString("specVersion", *SpecVersion);
209
0
  }
210
0
  SerializeIfPresent(serializer, "comment", Comment);
211
0
  SerializeIfPresent(serializer, "created", Created);
212
0
  if (!CreatedBy.empty()) {
213
0
    serializer.AddVectorIfPresent("createdBy", CreatedBy);
214
0
  }
215
0
  if (!CreatedUsing.empty()) {
216
0
    serializer.AddVectorIfPresent("createdUsing", CreatedUsing);
217
0
  }
218
0
}
219
220
void cmSpdxIntegrityMethod::Serialize(cmSbomSerializer& serializer) const
221
0
{
222
0
  serializer.AddString("type", "IntegrityMethod");
223
0
  SerializeIfPresent(serializer, "comment", Comment);
224
0
}
225
226
void cmSpdxElement::Serialize(cmSbomSerializer& serializer) const
227
0
{
228
0
  serializer.AddString("type", "Element");
229
0
  SerializeIfPresent(serializer, "spdxId", SpdxId);
230
0
  SerializeIfPresent(serializer, "name", Name);
231
0
  SerializeIfPresent(serializer, "summary", Summary);
232
0
  SerializeIfPresent(serializer, "description", Description);
233
0
  SerializeIfPresent(serializer, "comment", Comment);
234
0
  if (CreationInfo) {
235
0
    serializer.AddVisitable("creationInfo", *CreationInfo);
236
0
  }
237
0
  if (VerifiedUsing) {
238
0
    serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
239
0
  }
240
0
  if (!ExternalRef.empty()) {
241
0
    serializer.AddVectorIfPresent("externalRef", ExternalRef);
242
0
  }
243
0
  if (!ExternalIdentifier.empty()) {
244
0
    serializer.AddVectorIfPresent("externalIdentifier", ExternalIdentifier);
245
0
  }
246
0
  if (Extension) {
247
0
    serializer.AddVisitable("extension", *Extension);
248
0
  }
249
0
}
250
251
void cmSpdxTool::Serialize(cmSbomSerializer& serializer) const
252
0
{
253
0
  cmSpdxElement::Serialize(serializer);
254
0
  serializer.AddString("type", "Tool");
255
0
}
256
257
void cmSpdxAgent::Serialize(cmSbomSerializer& serializer) const
258
0
{
259
0
  cmSpdxElement::Serialize(serializer);
260
0
  serializer.AddString("type", "Agent");
261
0
}
262
263
void cmSpdxOrganization::Serialize(cmSbomSerializer& serializer) const
264
0
{
265
0
  cmSpdxAgent::Serialize(serializer);
266
0
  serializer.AddString("type", "Organization");
267
0
}
268
269
void cmSpdxPerson::Serialize(cmSbomSerializer& serializer) const
270
0
{
271
0
  cmSpdxAgent::Serialize(serializer);
272
0
  serializer.AddString("type", "Person");
273
0
}
274
275
void cmSpdxSoftwareAgent::Serialize(cmSbomSerializer& serializer) const
276
0
{
277
0
  cmSpdxAgent::Serialize(serializer);
278
0
  serializer.AddString("type", "SoftwareAgent");
279
0
}
280
281
void cmSpdxPositiveIntegerRange::Serialize(cmSbomSerializer& serializer) const
282
0
{
283
0
  serializer.AddString("type", "PositiveIntegerRange");
284
0
  SerializeIfPresent(serializer, "beginIntegerRange", BeginIntegerRange);
285
0
  SerializeIfPresent(serializer, "endIntegerRange", EndIntegerRange);
286
0
}
287
288
void cmSpdxRelationship::Serialize(cmSbomSerializer& serializer) const
289
0
{
290
0
  cmSpdxElement::Serialize(serializer);
291
0
  serializer.AddString("type", "Relationship");
292
0
  if (From) {
293
0
    serializer.AddVisitable("from", *From);
294
0
  }
295
0
  if (!To.empty()) {
296
0
    serializer.AddVectorIfPresent("to", To);
297
0
  }
298
0
  if (RelationshipType) {
299
0
    serializer.AddString("relationshipType", to_string(*RelationshipType));
300
0
  }
301
0
  SerializeIfPresent(serializer, "startTime", StartTime);
302
0
  SerializeIfPresent(serializer, "endTime", EndTime);
303
0
}
304
305
void cmSpdxLifecycleScopedRelationship::Serialize(
306
  cmSbomSerializer& serializer) const
307
0
{
308
0
  cmSpdxRelationship::Serialize(serializer);
309
0
  serializer.AddString("type", "LifecycleScopedRelationship");
310
0
  if (Scope) {
311
0
    serializer.AddString("scope", to_string(*Scope));
312
0
  }
313
0
}
314
315
void cmSpdxArtifact::Serialize(cmSbomSerializer& serializer) const
316
0
{
317
0
  cmSpdxElement::Serialize(serializer);
318
0
  serializer.AddString("type", "Artifact");
319
0
  if (!OriginatedBy.empty()) {
320
0
    serializer.AddVectorIfPresent("originatedBy", OriginatedBy);
321
0
  }
322
0
  if (SuppliedBy) {
323
0
    serializer.AddVisitable("suppliedBy", *SuppliedBy);
324
0
  }
325
0
  SerializeIfPresent(serializer, "builtTime", BuiltTime);
326
0
  SerializeIfPresent(serializer, "releaseTime", ReleaseTime);
327
0
  SerializeIfPresent(serializer, "validUntilTime", ValidUntilTime);
328
0
  SerializeIfPresent(serializer, "standardName", StandardName);
329
0
  if (Support) {
330
0
    serializer.AddString("support", to_string(*Support));
331
0
  }
332
0
}
333
334
void cmSpdxIndividualElement::Serialize(cmSbomSerializer& serializer) const
335
0
{
336
0
  cmSpdxElement::Serialize(serializer);
337
0
  serializer.AddString("type", "IndividualElement");
338
0
}
339
340
void cmSpdxAnnotation::Serialize(cmSbomSerializer& serializer) const
341
0
{
342
0
  cmSpdxElement::Serialize(serializer);
343
0
  serializer.AddString("type", "Annotation");
344
0
  if (AnnotationType) {
345
0
    serializer.AddString("annotationType", to_string(*AnnotationType));
346
0
  }
347
0
  SerializeIfPresent(serializer, "contentType", ContentType);
348
0
  SerializeIfPresent(serializer, "statement", Statement);
349
0
  if (Element) {
350
0
    serializer.AddVisitable("element", *Element);
351
0
  }
352
0
}
353
354
void cmSpdxExternalMap::Serialize(cmSbomSerializer& serializer) const
355
0
{
356
0
  serializer.AddString("type", "ExternalMap");
357
0
  SerializeIfPresent(serializer, "externalSpdxId", ExternalSpdxId);
358
0
  if (VerifiedUsing) {
359
0
    serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
360
0
  }
361
0
  SerializeIfPresent(serializer, "locationHistory", LocationHistory);
362
0
  if (DefiningArtifact) {
363
0
    serializer.AddVisitable("definingArtifact", *DefiningArtifact);
364
0
  }
365
0
}
366
367
void cmSpdxNamespaceMap::Serialize(cmSbomSerializer& serializer) const
368
0
{
369
0
  serializer.AddString("type", "NamespaceMap");
370
0
  SerializeIfPresent(serializer, "prefix", Prefix);
371
0
  SerializeIfPresent(serializer, "namespace", Namespace);
372
0
}
373
374
void cmSpdxElementCollection::Serialize(cmSbomSerializer& serializer) const
375
0
{
376
0
  cmSpdxElement::Serialize(serializer);
377
0
  serializer.AddString("type", "ElementCollection");
378
0
  if (!Elements.empty()) {
379
0
    serializer.AddVectorIfPresent("element", Elements);
380
0
  }
381
0
  if (!RootElements.empty()) {
382
0
    serializer.AddVectorIfPresent("rootElement", RootElements);
383
0
  }
384
0
  if (!ProfileConformance.empty()) {
385
0
    serializer.AddVectorIfPresent("profileConformance", ProfileConformance);
386
0
  }
387
0
}
388
389
void cmSpdxPackageVerificationCode::Serialize(
390
  cmSbomSerializer& serializer) const
391
0
{
392
0
  serializer.AddString("type", "PackageVerificationCode");
393
0
  if (Algorithm) {
394
0
    serializer.AddString("algorithm", to_string(*Algorithm));
395
0
  }
396
0
  SerializeIfPresent(serializer, "hashValue", HashValue);
397
0
  SerializeIfPresent(serializer, "packageVerificationCodeExcludedFile",
398
0
                     PackageVerificationCodeExcludedFile);
399
0
}
400
401
void cmSpdxHash::Serialize(cmSbomSerializer& serializer) const
402
0
{
403
0
  serializer.AddString("type", "Hash");
404
0
  serializer.AddString("hashAlgorithm", to_string(HashAlgorithm));
405
0
  serializer.AddString("hashValue", HashValue);
406
0
}
407
408
void cmSpdxBundle::Serialize(cmSbomSerializer& serializer) const
409
0
{
410
0
  cmSpdxElementCollection::Serialize(serializer);
411
0
  serializer.AddString("type", "Bundle");
412
0
  SerializeIfPresent(serializer, "context", Context);
413
0
}
414
415
void cmSpdxBom::Serialize(cmSbomSerializer& serializer) const
416
0
{
417
0
  cmSpdxBundle::Serialize(serializer);
418
0
  serializer.AddString("type", "Bom");
419
0
}
420
421
void cmSpdxSbom::Serialize(cmSbomSerializer& serializer) const
422
0
{
423
0
  cmSpdxBom::Serialize(serializer);
424
0
  serializer.AddString("type", "software_Sbom");
425
0
  if (Types) {
426
0
    for (auto const& t : *Types) {
427
0
      serializer.AddString("sbomType", to_string(t));
428
0
    }
429
0
  }
430
0
  if (LifecycleScope) {
431
0
    serializer.AddString("lifecycleScope", to_string(*LifecycleScope));
432
0
  }
433
0
}
434
435
void cmSpdxSoftwareArtifact::Serialize(cmSbomSerializer& serializer) const
436
0
{
437
0
  cmSpdxArtifact::Serialize(serializer);
438
0
  serializer.AddString("type", "software_SoftwareArtifact");
439
0
  if (PrimaryPurpose) {
440
0
    serializer.AddString("software_primaryPurpose",
441
0
                         to_string(*PrimaryPurpose));
442
0
  }
443
0
  if (AdditionalPurpose) {
444
0
    for (auto const& p : *AdditionalPurpose) {
445
0
      serializer.AddString("software_AdditionalPurpose", to_string(p));
446
0
    }
447
0
  }
448
0
  SerializeIfPresent(serializer, "software_copyrightText", CopyrightText);
449
0
  SerializeIfPresent(serializer, "software_attributionText", AttributionText);
450
0
  if (ContentIdentifier) {
451
0
    serializer.AddVisitable("software_contentIdentifier", *ContentIdentifier);
452
0
  }
453
0
  SerializeIfPresent(serializer, "software_artifactSize", ArtifactSize);
454
0
}
455
456
void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
457
0
{
458
0
  cmSpdxSoftwareArtifact::Serialize(serializer);
459
0
  serializer.AddString("type", "software_Package");
460
0
  SerializeIfPresent(serializer, "software_downloadLocation",
461
0
                     DownloadLocation);
462
0
  SerializeIfPresent(serializer, "software_homePage", Homepage);
463
0
  SerializeIfPresent(serializer, "software_packageVersion", PackageVersion);
464
0
  SerializeIfPresent(serializer, "software_packageUrl", PackageUrl);
465
0
  SerializeIfPresent(serializer, "software_sourceInfo", SourceInfo);
466
0
}
467
468
void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
469
0
{
470
0
  cmSpdxArtifact::Serialize(serializer);
471
0
  serializer.AddString("type", "software_File");
472
0
  if (ContentType) {
473
0
    serializer.AddString("software_contentType", *ContentType);
474
0
  }
475
0
  if (FileType) {
476
0
    serializer.AddString("software_fileType", to_string(*FileType));
477
0
  }
478
0
}
479
480
void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
481
0
{
482
0
  cmSpdxIntegrityMethod::Serialize(serializer);
483
0
  serializer.AddString("type", "software_contentIdentifier");
484
0
  SerializeIfPresent(serializer, "software_contentIdentifierType",
485
0
                     ContentIdentifierType);
486
0
  SerializeIfPresent(serializer, "software_contentValue", ContentValue);
487
0
}
488
489
void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
490
0
{
491
0
  cmSpdxSoftwareArtifact::Serialize(serializer);
492
0
  serializer.AddString("type", "software_snippet");
493
0
  SerializeIfPresent(serializer, "software_byteRange", ByteRange);
494
0
  SerializeIfPresent(serializer, "software_lineRange", LineRange);
495
0
  if (SnippetFromFile) {
496
0
    serializer.AddVisitable("software_snippetFromFile", *SnippetFromFile);
497
0
  }
498
0
}
499
500
void cmSpdxDocument::Serialize(cmSbomSerializer& serializer) const
501
0
{
502
0
  cmSpdxElementCollection::Serialize(serializer);
503
504
0
  serializer.AddString("type", "SpdxDocument");
505
0
  if (ExternalMap) {
506
0
    serializer.AddVisitable("externalMap", *ExternalMap);
507
0
  }
508
0
  if (NamespaceMap) {
509
0
    serializer.AddVisitable("namespaceMap", *NamespaceMap);
510
0
  }
511
0
  SerializeIfPresent(serializer, "dataLicense", DataLicense);
512
0
}
513
514
void cmSbomDocument::Serialize(cmSbomSerializer& serializer) const
515
0
{
516
0
  serializer.AddString(
517
0
    "@context",
518
0
    Context.value_or("https://spdx.org/rdf/3.0.1/spdx-context.jsonld"));
519
0
  if (!Graph.empty()) {
520
0
    serializer.AddVectorIfPresent("@graph", Graph);
521
0
  }
522
0
}