Coverage Report

Created: 2026-02-09 06:05

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 "OPERATING_SYSTEM";
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 "DEPENDS_ON";
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, "@id", 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("primaryPurpose", to_string(*PrimaryPurpose));
441
0
  }
442
0
  if (AdditionalPurpose) {
443
0
    for (auto const& p : *AdditionalPurpose) {
444
0
      serializer.AddString("additionalPurpose", to_string(p));
445
0
    }
446
0
  }
447
0
  SerializeIfPresent(serializer, "copyrightText", CopyrightText);
448
0
  SerializeIfPresent(serializer, "attributionText", AttributionText);
449
0
  if (ContentIdentifier) {
450
0
    serializer.AddVisitable("contentIdentifier", *ContentIdentifier);
451
0
  }
452
0
  SerializeIfPresent(serializer, "artifactSize", ArtifactSize);
453
0
}
454
455
void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
456
0
{
457
0
  cmSpdxSoftwareArtifact::Serialize(serializer);
458
0
  serializer.AddString("type", "software_Package");
459
0
  SerializeIfPresent(serializer, "downloadLocation", DownloadLocation);
460
0
  SerializeIfPresent(serializer, "homePage", Homepage);
461
0
  SerializeIfPresent(serializer, "packageVersion", PackageVersion);
462
0
  SerializeIfPresent(serializer, "packageUrl", PackageUrl);
463
0
  SerializeIfPresent(serializer, "sourceInfo", SourceInfo);
464
0
}
465
466
void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
467
0
{
468
0
  cmSpdxArtifact::Serialize(serializer);
469
0
  serializer.AddString("type", "software_File");
470
0
  if (ContentType) {
471
0
    serializer.AddString("contentType", *ContentType);
472
0
  }
473
0
  if (FileType) {
474
0
    serializer.AddString("fileType", to_string(*FileType));
475
0
  }
476
0
}
477
478
void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
479
0
{
480
0
  cmSpdxIntegrityMethod::Serialize(serializer);
481
0
  serializer.AddString("type", "software_ContentIdentifier");
482
0
  SerializeIfPresent(serializer, "contentIdentifierType",
483
0
                     ContentIdentifierType);
484
0
  SerializeIfPresent(serializer, "contentValue", ContentValue);
485
0
}
486
487
void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
488
0
{
489
0
  cmSpdxSoftwareArtifact::Serialize(serializer);
490
0
  serializer.AddString("type", "software_Snippet");
491
0
  SerializeIfPresent(serializer, "byteRange", ByteRange);
492
0
  SerializeIfPresent(serializer, "lineRange", LineRange);
493
0
  if (SnippetFromFile) {
494
0
    serializer.AddVisitable("snippetFromFile", *SnippetFromFile);
495
0
  }
496
0
}
497
498
void cmSpdxDocument::Serialize(cmSbomSerializer& serializer) const
499
0
{
500
0
  cmSpdxElementCollection::Serialize(serializer);
501
502
0
  serializer.AddString("type", "SpdxDocument");
503
0
  if (ExternalMap) {
504
0
    serializer.AddVisitable("externalMap", *ExternalMap);
505
0
  }
506
0
  if (NamespaceMap) {
507
0
    serializer.AddVisitable("namespaceMap", *NamespaceMap);
508
0
  }
509
0
  SerializeIfPresent(serializer, "dataLicense", DataLicense);
510
0
}
511
512
void cmSbomDocument::Serialize(cmSbomSerializer& serializer) const
513
0
{
514
0
  serializer.AddString(
515
0
    "@context",
516
0
    Context.value_or("https://spdx.org/rdf/3.0.1/spdx-context.jsonld"));
517
0
  if (!Graph.empty()) {
518
0
    serializer.AddVectorIfPresent("@graph", Graph);
519
0
  }
520
0
}