Merge topic 'sbom_model'

0653620033 cmSbom: Add SPDX object model and serializers
985b0f5bcf CMake C++11 Compatibility: Add more type_traits from C++14 and C++17

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !11231
This commit is contained in:
Brad King
2025-10-25 09:13:43 -04:00
committed by Kitware Robot
15 changed files with 1504 additions and 3101 deletions
+3 -2
View File
@@ -111,7 +111,8 @@ Available features are:
``cm::shared_lock``
* ``<cm/type_traits>``:
``cm::enable_if_t``
``cm::conditional_t``, ``cm::decay_t``, ``cm::enable_if_t``,
``cm::remove_cv_t``, ``cm::remove_reference_t``
* ``<cm/unordered_map>``:
``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
@@ -169,7 +170,7 @@ Available features are:
* ``<cm/type_traits>``:
``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
``cm::void_t``
``cm::is_same_v``, ``cm::void_t``
* ``<cm/unordered_map>``:
``cm::size``, ``cm::empty``, ``cm::data``
+6 -3
View File
@@ -701,6 +701,8 @@ add_library(
cmRemoveDefinitionsCommand.h
cmReturnCommand.cxx
cmReturnCommand.h
cmSbomObject.h
cmSbomSerializer.h
cmSearchPath.cxx
cmSearchPath.h
cmSeparateArgumentsCommand.cxx
@@ -721,9 +723,10 @@ add_library(
cmSiteNameCommand.h
cmSourceGroupCommand.cxx
cmSourceGroupCommand.h
cmSPDXSerializer.cxx
cmSPDXSerializer.h
cmSPDXTypes.def
cmSpdx.cxx
cmSpdx.h
cmSpdxSerializer.cxx
cmSpdxSerializer.h
cmString.cxx
cmString.hxx
cmStringReplaceHelper.cxx
-1375
View File
@@ -1,1375 +0,0 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmSPDXSerializer.h"
#include <new>
#include <string>
#include <cm/optional>
#include <cm3p/json/value.h>
// Serialization Utilities
template <typename T>
void addVectorSPDXValue(Json::Value& obj, std::string const& key,
std::vector<T> const& vec)
{
auto& list = obj[key];
list = Json::Value(Json::arrayValue);
for (auto const& val : vec) {
list.append(val.toJsonLD());
}
}
template <>
void addVectorSPDXValue(Json::Value& obj, std::string const& key,
std::vector<std::string> const& vec)
{
auto& list = obj[key];
list = Json::Value(Json::arrayValue);
for (auto const& val : vec) {
list.append(val);
}
}
template <typename T>
void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
cm::optional<std::vector<T>> const& opt)
{
if (opt) {
addVectorSPDXValue(obj, key, *opt);
}
}
template <typename T>
void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
cm::optional<T> const& opt)
{
if (opt) {
obj[key] = opt->toJsonLD();
}
}
template <>
void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
cm::optional<std::string> const& opt)
{
if (opt) {
obj[key] = *opt;
}
}
// Base Class
cmSPDXSerializationBase::SPDXTypeId cmSPDXSerializationBase::getTypeId() const
{
return TypeId;
}
cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id)
: TypeId(id)
{
}
cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id,
std::string nodeId)
: NodeId(std::move(nodeId))
, TypeId(id)
{
}
// Convenience Classes
cmSPDXIdentifierReference::cmSPDXIdentifierReference()
: cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE)
{
}
cmSPDXIdentifierReference::cmSPDXIdentifierReference(
cmSPDXSerializationBase const& ref)
: cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref.NodeId)
{
}
cmSPDXIdentifierReference::cmSPDXIdentifierReference(std::string const& ref)
: cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref)
{
}
Json::Value cmSPDXIdentifierReference::toJsonLD() const
{
return NodeId;
}
cmSPDXNonElementBase::cmSPDXNonElementBase(SPDXTypeId id)
: cmSPDXSerializationBase(id)
{
}
Json::Value cmSPDXNonElementBase::toJsonLD() const
{
Json::Value obj(Json::objectValue);
obj["@id"] = NodeId;
return obj;
}
// SPDX Core Enums
cmSPDXAnnotationType::cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXAnnotationType::toJsonLD() const
{
switch (TypeId) {
case OTHER:
return "other";
case REVIEW:
return "review";
default:
return "INVALID_ANNOTATION_TYPE_ID";
}
}
cmSPDXExternalIdentifierType::cmSPDXExternalIdentifierType(
cmSPDXExternalIdentifierTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXExternalIdentifierType::toJsonLD() const
{
switch (TypeId) {
case CPE22:
return "cpe22";
case CPE23:
return "cpe23";
case CVE:
return "cve";
case EMAIL:
return "email";
case GITOID:
return "gitoid";
case OTHER:
return "other";
case PACKAGE_URL:
return "packageUrl";
case SECURITY_OTHER:
return "securityOther";
case SWHID:
return "swhid";
case SWID:
return "swid";
case URL_SCHEME:
return "urlScheme";
default:
return "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID";
}
}
cmSPDXExternalRefType::cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXExternalRefType::toJsonLD() const
{
switch (TypeId) {
case ALT_DOWNLOAD_LOCATION:
return "altDownloadLocation:";
case ALT_WEB_PAGE:
return "altWebPage";
case BINARY_ARTIFACT:
return "binaryArtifact";
case BOWER:
return "bower";
case BUILD_META:
return "buildMeta";
case BUILD_SYSTEM:
return "buildSystem";
case CERTIFICATION_REPORT:
return "certificationReport";
case CHAT:
return "chat";
case COMPONENT_ANALYSIS_REPORT:
return "componentAnalysisReport";
case CWE:
return "cwe";
case DOCUMENTATION:
return "documentation";
case DYNAMIC_ANALYSIS_REPORT:
return "dynamicAnalysisReport";
case EOL_NOTICE:
return "eolNotice";
case EXPORT_CONTROL_ASSESSMENT:
return "exportControlAssessment";
case FUNDING:
return "funding";
case ISSUE_TRACKER:
return "issueTracker";
case LICENSE:
return "license";
case MAILING_LIST:
return "mailingList";
case MAVEN_CENTRAL:
return "mavenCentral";
case METRICS:
return "metrics";
case NPM:
return "npm";
case NUGET:
return "nuget";
case OTHER:
return "other";
case PRIVACY_ASSESSMENT:
return "privacyAssessment";
case PRODUCT_METADATA:
return "productMetadata";
case PURCHASE_ORDER:
return "purchaseOrder";
case QUALITY_ASSESSMENT_REPORT:
return "qualityAssessmentReport";
case RELEASE_HISTORY:
return "releaseHistory";
case RELEASE_NOTES:
return "releaseNotes";
case RISK_ASSESSMENT:
return "riskAssessment";
case RUNTIME_ANALYSIS_REPORT:
return "runtimeAnalysisReport";
case SECURE_SOFTWARE_ATTESTATION:
return "secureSoftwareAttestation";
case SECURITY_ADVERSARY_MODEL:
return "securityAdversaryModel";
case SECURITY_ADVISORY:
return "securityAdvisory";
case SECURITY_FIX:
return "securityFix";
case SECURITY_OTHER:
return "securityOther";
case SECURITY_PEN_TEST_REPORT:
return "securityPenTestReport";
case SECURITY_POLICY:
return "securityPolicy";
case SECURITY_THREAT_MODEL:
return "securityThreatModel";
case SOCIAL_MEDIA:
return "socialMedia";
case SOURCE_ARTIFACT:
return "sourceArtifact";
case STATIC_ANALYSIS_REPORT:
return "staticAnalysisReport";
case SUPPORT:
return "support";
case VCS:
return "vcs";
case VULNERABILITY_DISCLOSURE_REPORT:
return "vulnerabilityDisclosureReport";
case VULNERABILITY_EXPLOITABILITY_ASSESSMENT:
return "vulnerabilityExploitabilityAssessment";
default:
return "INVALID_EXTERNAL_REF_TYPE_ID";
}
}
cmSPDXHashAlgorithm::cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXHashAlgorithm::toJsonLD() const
{
switch (TypeId) {
case ADLER32:
return "adler32";
case BLAKE2B256:
return "blake2b256";
case BLAKE2B384:
return "blake2b384";
case BLAKE2B512:
return "blake2b512";
case BLAKE3:
return "blake3";
case CRYSTALS_DILITHIUM:
return "crystalsDilithium";
case CRYSTALS_KYBER:
return "crystalsLyber";
case FALCON:
return "falcon";
case MD2:
return "md2";
case MD4:
return "md4";
case MD5:
return "md5";
case MD6:
return "md6";
case OTHER:
return "other";
case SHA1:
return "sha1";
case SHA224:
return "sha224";
case SHA256:
return "sha256";
case SHA384:
return "sha384";
case SHA3_224:
return "sha3_224";
case SHA3_256:
return "sha3_256";
case SHA3_384:
return "sha3_384";
case SHA3_512:
return "sha3_512";
case SHA512:
return "sha512";
default:
return "INVALID_HASH_TYPE_ID";
}
}
cmSPDXLifecycleScopeType::cmSPDXLifecycleScopeType(
cmSPDXLifecycleScopeTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXLifecycleScopeType::toJsonLD() const
{
switch (TypeId) {
case BUILD:
return "build";
case DESIGN:
return "design";
case DEVELOPMENT:
return "development";
case OTHER:
return "other";
case RUNTIME:
return "runtime";
case TEST:
return "test";
default:
return "INVALID_LIFECYCLE_SCOPE_TYPE_ID";
}
}
cmSPDXProfileIdentifierType::cmSPDXProfileIdentifierType(
cmSPDXProfileIdentifierTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXProfileIdentifierType::toJsonLD() const
{
switch (TypeId) {
case AI:
return "ai";
case BUILD:
return "build";
case CORE:
return "code";
case DATASET:
return "dataset";
case EXPANDED_LICENSING:
return "expandedLicensing";
case EXTENSION:
return "extension";
case LITE:
return "lite";
case SECURITY:
return "security";
case SIMPLE_LICENSING:
return "simpleLicensing";
case SOFTWARE:
return "software";
default:
return "INVALID_PROFILE_IDENTIFIER_TYPE_ID";
}
}
cmSPDXRelationshipCompletenessType::cmSPDXRelationshipCompletenessType(
cmSPDXRelationshipCompletenessTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXRelationshipCompletenessType::toJsonLD() const
{
switch (TypeId) {
case COMPLETE:
return "complete";
case INCOMPLETE:
return "incomplete";
case NO_ASSERTION:
return "noAssertion";
default:
return "INVALID_RELATIONSHIP_COMPLETENESS_TYPE_ID";
}
}
cmSPDXRelationshipType::cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXRelationshipType::toJsonLD() const
{
switch (TypeId) {
case AFFECTS:
return "affects";
case AMENDED_BY:
return "amendedBy";
case ANCESTOR_OF:
return "ancestorOf";
case AVAILABLE_FROM:
return "availableFrom";
case CONFIGURES:
return "configures";
case CONTAINS:
return "contains";
case COORDINATED_BY:
return "coordinatedBy";
case COPIED_TO:
return "copiedTo";
case DELEGATED_TO:
return "delegatedTo";
case DEPENDS_ON:
return "dependsOn";
case DESCENDANT_OF:
return "descendantOf";
case DESCRIBES:
return "describes";
case DOES_NOT_AFFECT:
return "doesNotAffect";
case EXPANDS_TO:
return "expandsTo";
case EXPLOIT_CREATED_BY:
return "exploitCreatedBy";
case FIXED_BY:
return "fixedBy";
case FIXED_IN:
return "fixedIn";
case FOUND_BY:
return "foundBy";
case GENERATES:
return "generates";
case HAS_ADDED_FILE:
return "hasAddedFile";
case HAS_ASSESSMENT_FOR:
return "hasAssessmentFor";
case HAS_ASSOCIATED_VULNERABILITY:
return "hasAssociatedVulnerability";
case HAS_CONCLUDED_LICENSE:
return "hasConcludedLicense";
case HAS_DATA_FILE:
return "hasDataFile";
case HAS_DECLARED_LICENSE:
return "hasDeclaredLicense";
case HAS_DELETED_FILE:
return "hasDeletedFile";
case HAS_DEPENDENCY_MANIFEST:
return "hasDependencyManifest";
case HAS_DISTRIBUTION_ARTIFACT:
return "hasDistributionArtifact";
case HAS_DOCUMENTATION:
return "hasDocumentation";
case HAS_DYNAMIC_LINK:
return "hasDynamicLink";
case HAS_EVIDENCE:
return "hasEvidence";
case HAS_EXAMPLE:
return "hasExample";
case HAS_HOST:
return "hasHost";
case HAS_INPUT:
return "hasInput";
case HAS_METADATA:
return "hasMetadata";
case HAS_OPTIONAL_COMPONENT:
return "hasOptionalComponent";
case HAS_OPTIONAL_DEPENDENCY:
return "hasOptionalDependency";
case HAS_OUTPUT:
return "hasOutput";
case HAS_PREREQUISITE:
return "hasPrerequisite";
case HAS_PROVIDED_DEPENDENCY:
return "hasProvidedDependency";
case HAS_REQUIREMENT:
return "hasRequirement";
case HAS_SPECIFICATION:
return "hasSpecification";
case HAS_STATIC_LINK:
return "hasStaticLink";
case HAS_TEST:
return "hasTest";
case HAS_TEST_CASE:
return "hasTestCase";
case HAS_VARIANT:
return "hasVariant";
case INVOKED_BY:
return "invokedBy";
case MODIFIED_BY:
return "modifiedBy";
case OTHER:
return "other";
case PACKAGED_BY:
return "packagedBy";
case PATCHED_BY:
return "patchedBy";
case PUBLISHED_BY:
return "publishedBy";
case REPORTED_BY:
return "reportedBy";
case REPUBLISHED_BY:
return "republishedBy";
case SERIALIZED_IN_ARTIFACT:
return "serializedInArtifact";
case TESTED_ON:
return "testedOn";
case TRAINED_ON:
return "trainedOn";
case UNDER_INVESTIGATION_FOR:
return "underInvestigationFor";
case USES_TOOL:
return "usesTool";
default:
return "INVALID_RELATIONSHIP_TYPE_ID";
}
}
cmSPDXSupportType::cmSPDXSupportType(cmSPDXSupportTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXSupportType::toJsonLD() const
{
switch (TypeId) {
case DEPLOYED:
return "deployed";
case DEVELOPMENT:
return "development";
case END_OF_SUPPORT:
return "endOfSupport";
case LIMITED_SUPPORT:
return "limitedSupport";
case NO_ASSERTION:
return "noAssertion";
case NO_SUPPORT:
return "noSupport";
case SUPPORT:
return "support";
default:
return "INVALID_SUPPORT_TYPE_ID";
}
}
// SPDX Core NonElement Classes, Abstract
cmSPDXIntegrityMethod::cmSPDXIntegrityMethod(SPDXTypeId id)
: cmSPDXNonElementBase(id)
{
}
Json::Value cmSPDXIntegrityMethod::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
addOptionalSPDXValue(obj, "comment", Comment);
return obj;
}
// SPDX Core NonElement Classes, Concrete
cmSPDXCreationInfo::cmSPDXCreationInfo()
: cmSPDXNonElementBase(CORE_CREATION_INFO)
{
}
Json::Value cmSPDXCreationInfo::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "CreationInfo";
addOptionalSPDXValue(obj, "Comment", Comment);
obj["created"] = Created;
addVectorSPDXValue(obj, "createdBy", CreatedBy);
addOptionalSPDXValue(obj, "createdUsing", CreatedUsing);
return obj;
}
cmSPDXDictionaryEntry::cmSPDXDictionaryEntry()
: cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
{
}
cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key)
: cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
, Key(std::move(key))
{
}
cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key, std::string val)
: cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
, Key(std::move(key))
, Value(std::move(val))
{
}
Json::Value cmSPDXDictionaryEntry::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "DictionaryEntry";
obj["key"] = Key;
addOptionalSPDXValue(obj, "value", Value);
return obj;
}
cmSPDXExternalIdentifier::cmSPDXExternalIdentifier()
: cmSPDXNonElementBase(CORE_EXTERNAL_IDENTIFIER)
{
}
Json::Value cmSPDXExternalIdentifier::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "ExternalIdentifier";
addOptionalSPDXValue(obj, "comment", Comment);
obj["externalIdentifierType"] = ExternalIdentifierType.toJsonLD();
obj["identifier"] = Identifier;
addOptionalSPDXValue(obj, "identifierLocator", IdentifierLocator);
addOptionalSPDXValue(obj, "issuingAuthority", IssuingAuthority);
return obj;
}
cmSPDXExternalMap::cmSPDXExternalMap()
: cmSPDXNonElementBase(CORE_EXTERNAL_MAP)
{
}
Json::Value cmSPDXExternalMap::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "ExternalMap";
addOptionalSPDXValue(obj, "definingArtifact", DefiningArtifact);
obj["externalSpdxId"] = ExternalSpdxId;
addOptionalSPDXValue(obj, "locationHint", LocationHint);
addOptionalSPDXValue(obj, "integrityMethod", IntegrityMethod);
return obj;
}
cmSPDXExternalRef::cmSPDXExternalRef()
: cmSPDXNonElementBase(CORE_EXTERNAL_REF)
{
}
Json::Value cmSPDXExternalRef::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "ExternalRef";
addOptionalSPDXValue(obj, "comment", Comment);
addOptionalSPDXValue(obj, "contentType", ContentType);
addOptionalSPDXValue(obj, "externalRefType", ExternalRefType);
addOptionalSPDXValue(obj, "locator", Locator);
return obj;
}
cmSPDXHash::cmSPDXHash()
: cmSPDXIntegrityMethod(CORE_HASH)
{
}
Json::Value cmSPDXHash::toJsonLD() const
{
auto obj = cmSPDXIntegrityMethod::toJsonLD();
obj["type"] = "Hash";
obj["algorithm"] = Algorithm.toJsonLD();
obj["hashValue"] = HashValue;
return obj;
}
cmSPDXNamespaceMap::cmSPDXNamespaceMap()
: cmSPDXNonElementBase(CORE_NAMESPACE_MAP)
{
}
Json::Value cmSPDXNamespaceMap::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "NamespaceMap";
obj["namespace"] = Namespace;
obj["prefix"] = Namespace;
return obj;
}
cmSPDXPackageVerificationCode::cmSPDXPackageVerificationCode()
: cmSPDXIntegrityMethod(CORE_PACKAGE_VERIFICATION_CODE)
{
}
Json::Value cmSPDXPackageVerificationCode::toJsonLD() const
{
auto obj = cmSPDXIntegrityMethod::toJsonLD();
obj["type"] = "PackageVerificationCode";
obj["algorithm"] = Algorithm.toJsonLD();
obj["hashValue"] = HashValue;
return obj;
}
cmSPDXPositiveIntegerRange::cmSPDXPositiveIntegerRange(
unsigned int beingIntegerRange, unsigned int endIntegerRange)
: cmSPDXNonElementBase(CORE_POSITIVE_INTEGER_RANGE)
, BeginIntegerRange(beingIntegerRange)
, EndIntegerRange(endIntegerRange)
{
}
Json::Value cmSPDXPositiveIntegerRange::toJsonLD() const
{
auto obj = cmSPDXNonElementBase::toJsonLD();
obj["type"] = "PositiveIntegerRange";
obj["beginIntegerRange"] = BeginIntegerRange;
obj["endIntegerRange"] = EndIntegerRange;
return obj;
}
// SPDX Core Element Classes, Abstract
cmSPDXElement::cmSPDXElement(SPDXTypeId id,
cmSPDXCreationInfo const& creationInfo)
: cmSPDXSerializationBase(id)
, CreationInfo(creationInfo)
{
}
Json::Value cmSPDXElement::toJsonLD() const
{
Json::Value obj(Json::objectValue);
addOptionalSPDXValue(obj, "comment", Comment);
obj["creationInfo"] = CreationInfo.toJsonLD();
addOptionalSPDXValue(obj, "description", Description);
addOptionalSPDXValue(obj, "extension", Extension);
addOptionalSPDXValue(obj, "externalIdentifier", ExternalIdentifier);
addOptionalSPDXValue(obj, "externalRef", ExternalRef);
addOptionalSPDXValue(obj, "name", Name);
obj["spdxId"] = NodeId;
addOptionalSPDXValue(obj, "summary", Summary);
addOptionalSPDXValue(obj, "verifiedUsing", VerifiedUsing);
return obj;
}
cmSPDXArtifact::cmSPDXArtifact(SPDXTypeId id,
cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(id, creationInfo)
{
}
Json::Value cmSPDXArtifact::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
addOptionalSPDXValue(obj, "builtTime", BuiltTime);
addOptionalSPDXValue(obj, "originateBy", OriginatedBy);
addOptionalSPDXValue(obj, "releaseTime", ReleaseTime);
addOptionalSPDXValue(obj, "standardName", StandardName);
addOptionalSPDXValue(obj, "suppliedBy", SuppliedBy);
addOptionalSPDXValue(obj, "supportType", SupportType);
addOptionalSPDXValue(obj, "validUntilTime", ValidUntilTime);
return obj;
}
cmSPDXElementCollection::cmSPDXElementCollection(
SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(id, creationInfo)
{
}
Json::Value cmSPDXElementCollection::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
addOptionalSPDXValue(obj, "element", Element);
addOptionalSPDXValue(obj, "profileConformance", ProfileConformance);
addOptionalSPDXValue(obj, "rootElement", RootElement);
return obj;
}
// SPDX Implicit Core Element Classes, Abstract
// Nominally an inheritable class, but adds nothing to Element
using cmSPDXAgentAbstract = cmSPDXElement;
cmSPDXBundleAbstract::cmSPDXBundleAbstract(
SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
: cmSPDXElementCollection(id, creationInfo)
{
}
Json::Value cmSPDXBundleAbstract::toJsonLD() const
{
auto obj = cmSPDXElementCollection::toJsonLD();
obj["context"] = Context;
return obj;
}
// Nominally an inheritable class, but adds nothing to Bundle
using cmSPDXBomAbstract = cmSPDXBundleAbstract;
cmSPDXRelationshipAbstract::cmSPDXRelationshipAbstract(
SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(id, creationInfo)
{
}
Json::Value cmSPDXRelationshipAbstract::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
addOptionalSPDXValue(obj, "completeness", Completeness);
addOptionalSPDXValue(obj, "endTime", EndTime);
obj["from"] = From.toJsonLD();
obj["relationshipType"] = RelationshipType.toJsonLD();
addOptionalSPDXValue(obj, "startTime", StartTime);
addVectorSPDXValue(obj, "to", To);
return obj;
}
// SPDX Core Element Classes, Concrete
cmSPDXAgent::cmSPDXAgent(cmSPDXCreationInfo const& creationInfo)
: cmSPDXAgentAbstract(CORE_AGENT, creationInfo)
{
}
Json::Value cmSPDXAgent::toJsonLD() const
{
auto obj = cmSPDXAgentAbstract::toJsonLD();
obj["type"] = "Agent";
return obj;
}
cmSPDXAnnotation::cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
cmSPDXIdentifierReference subject)
: cmSPDXElement(CORE_ANNOTATION, creationInfo)
, Subject(std::move(subject))
{
}
Json::Value cmSPDXAnnotation::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
obj["type"] = "Annotation";
obj["annotationType"] = AnnotationType.toJsonLD();
addOptionalSPDXValue(obj, "contentType", ContentType);
addOptionalSPDXValue(obj, "statement", Statement);
obj["subject"] = Subject.toJsonLD();
return obj;
}
cmSPDXBom::cmSPDXBom(cmSPDXCreationInfo const& creationInfo)
: cmSPDXBomAbstract(CORE_BOM, creationInfo)
{
}
Json::Value cmSPDXBom::toJsonLD() const
{
auto obj = cmSPDXBomAbstract::toJsonLD();
obj["type"] = "Bom";
return obj;
}
cmSPDXBundle::cmSPDXBundle(cmSPDXCreationInfo const& creationInfo)
: cmSPDXBundleAbstract(CORE_BUNDLE, creationInfo)
{
}
Json::Value cmSPDXBundle::toJsonLD() const
{
auto obj = cmSPDXBundleAbstract::toJsonLD();
obj["type"] = "Bundle";
return obj;
}
cmSPDXIndividualElement::cmSPDXIndividualElement(
cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(CORE_INDIVIDUAL_ELEMENT, creationInfo)
{
}
Json::Value cmSPDXIndividualElement::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
obj["type"] = "IndividualElement";
return obj;
}
cmSPDXLifecycleScopedRelationship::cmSPDXLifecycleScopedRelationship(
cmSPDXCreationInfo const& creationInfo)
: cmSPDXRelationshipAbstract(CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
creationInfo)
{
}
Json::Value cmSPDXLifecycleScopedRelationship::toJsonLD() const
{
auto obj = cmSPDXRelationshipAbstract::toJsonLD();
obj["type"] = "LifecycleScopedRelationship";
addOptionalSPDXValue(obj, "scope", Scope);
return obj;
}
cmSPDXOrganization::cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo)
: cmSPDXAgentAbstract(CORE_ORGANIZATION, creationInfo)
{
}
Json::Value cmSPDXOrganization::toJsonLD() const
{
auto obj = cmSPDXAgentAbstract::toJsonLD();
obj["type"] = "Organization";
return obj;
}
cmSPDXPerson::cmSPDXPerson(cmSPDXCreationInfo const& creationInfo)
: cmSPDXAgentAbstract(CORE_PERSON, creationInfo)
{
}
Json::Value cmSPDXPerson::toJsonLD() const
{
auto obj = cmSPDXAgentAbstract::toJsonLD();
obj["type"] = "Person";
return obj;
}
cmSPDXRelationship::cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo)
: cmSPDXRelationshipAbstract(CORE_RELATIONSHIP, creationInfo)
{
}
Json::Value cmSPDXRelationship::toJsonLD() const
{
auto obj = cmSPDXRelationshipAbstract::toJsonLD();
obj["type"] = "Relationship";
return obj;
}
cmSPDXSoftwareAgent::cmSPDXSoftwareAgent(
cmSPDXCreationInfo const& creationInfo)
: cmSPDXAgentAbstract(CORE_SOFTWARE_AGENT, creationInfo)
{
}
Json::Value cmSPDXSoftwareAgent::toJsonLD() const
{
auto obj = cmSPDXAgentAbstract::toJsonLD();
obj["type"] = "SoftwareAgent";
return obj;
}
cmSPDXSpdxDocument::cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo)
: cmSPDXElementCollection(CORE_SPDX_DOCUMENT, creationInfo)
{
}
Json::Value cmSPDXSpdxDocument::toJsonLD() const
{
auto obj = cmSPDXElementCollection::toJsonLD();
obj["type"] = "SpdxDocument";
addOptionalSPDXValue(obj, "dataLicense", DataLicense);
addOptionalSPDXValue(obj, "externalMap", ExternalMap);
addOptionalSPDXValue(obj, "namespaceMap", NamespaceMap);
return obj;
}
cmSPDXTool::cmSPDXTool(cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(CORE_TOOL, creationInfo)
{
}
Json::Value cmSPDXTool::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
obj["type"] = "Tool";
return obj;
}
// SPDX Software Enums
cmSPDXContentIdentifierType::cmSPDXContentIdentifierType(
cmSPDXContentIdentifierTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXContentIdentifierType::toJsonLD() const
{
switch (TypeId) {
case GITOID:
return "gitoid";
case SWHID:
return "swhid";
default:
return "INVALID_CONTENT_IDENTIFIER_TYPE_ID";
}
}
cmSPDXFileKindType::cmSPDXFileKindType(cmSPDXFileKindTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXFileKindType::toJsonLD() const
{
switch (TypeId) {
case DIRECTORY:
return "directory";
case FILE:
return "file";
default:
return "INVALID_FILE_KIND_TYPE_ID";
}
}
cmSPDXSbomType::cmSPDXSbomType(cmSPDXSbomTypeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXSbomType::toJsonLD() const
{
switch (TypeId) {
case ANALYZED:
return "analyzed";
case BUILD:
return "build";
case DEPLOYED:
return "deployed";
case DESIGN:
return "design";
case RUNTIME:
return "runtime";
case SOURCE:
return "source";
default:
return "INVALID_SBOM_TYPE_ID";
}
}
cmSPDXSoftwarePurpose::cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId)
: TypeId(typeId)
{
}
Json::Value cmSPDXSoftwarePurpose::toJsonLD() const
{
switch (TypeId) {
case APPLICATION:
return "application";
case ARCHIVE:
return "archive";
case BOM:
return "bom";
case CONFIGURATION:
return "configuration";
case CONTAINER:
return "container";
case DATA:
return "data";
case DEVICE:
return "device";
case DEVICE_DRIVER:
return "deviceDriver";
case DISK_IMAGE:
return "diskImage";
case DOCUMENTATION:
return "documentation";
case EVIDENCE:
return "evidence";
case EXECUTABLE:
return "executable";
case FILE:
return "file";
case FILESYSTEM_IMAGE:
return "filesystemImage";
case FIRMWARE:
return "firmware";
case FRAMEWORK:
return "framework";
case INSTALL:
return "install";
case LIBRARY:
return "library";
case MANIFEST:
return "manifest";
case MODEL:
return "model";
case MODULE:
return "module";
case OPERATING_SYSTEM:
return "operatingSystem";
case OTHER:
return "other";
case PATCH:
return "patch";
case PLATFORM:
return "platform";
case REQUIREMENT:
return "requirement";
case SOURCE:
return "source";
case SPECIFICATION:
return "specification";
case TEST:
return "test";
default:
return "INVALID_SOFTWARE_PURPOSE_ID";
}
}
// SPDX Software NonElement Classes, Concrete
cmSPDXContentIdentifier::cmSPDXContentIdentifier()
: cmSPDXIntegrityMethod(SOFTWARE_CONTENT_IDENTIFIER)
{
}
Json::Value cmSPDXContentIdentifier::toJsonLD() const
{
auto obj = cmSPDXIntegrityMethod::toJsonLD();
obj["type"] = "ContentIdentifier";
obj["contentIdentifierType"] = ContentIdentifierType.toJsonLD();
obj["contentIdentifierValue"] = ContentIdentifierValue;
return obj;
}
// SPDX Software Element Classes, Abstract
cmSPDXSoftwareArtifact::cmSPDXSoftwareArtifact(
SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
: cmSPDXArtifact(id, creationInfo)
{
}
Json::Value cmSPDXSoftwareArtifact::toJsonLD() const
{
auto obj = cmSPDXArtifact::toJsonLD();
addOptionalSPDXValue(obj, "additionalPurpose", AdditionalPurpose);
addOptionalSPDXValue(obj, "attributionText", AttributionText);
addOptionalSPDXValue(obj, "contentIdentifier", ContentIdentifier);
addOptionalSPDXValue(obj, "copyrightText", CopyrightText);
addOptionalSPDXValue(obj, "primaryPurpose", PrimaryPurpose);
return obj;
}
// SPDX Software Element Classes, Concrete
cmSPDXFile::cmSPDXFile(cmSPDXCreationInfo const& creationInfo)
: cmSPDXSoftwareArtifact(SOFTWARE_FILE, creationInfo)
{
}
Json::Value cmSPDXFile::toJsonLD() const
{
auto obj = cmSPDXSoftwareArtifact::toJsonLD();
obj["type"] = "File";
addOptionalSPDXValue(obj, "contentType", ContentType);
addOptionalSPDXValue(obj, "fileKind", FileKind);
return obj;
}
cmSPDXPackage::cmSPDXPackage(cmSPDXCreationInfo const& creationInfo)
: cmSPDXSoftwareArtifact(SOFTWARE_PACKAGE, creationInfo)
{
}
Json::Value cmSPDXPackage::toJsonLD() const
{
auto obj = cmSPDXSoftwareArtifact::toJsonLD();
obj["type"] = "Package";
addOptionalSPDXValue(obj, "downloadLocation", DownloadLocation);
addOptionalSPDXValue(obj, "homePage", HomePage);
addOptionalSPDXValue(obj, "packageUrl", PackageUrl);
addOptionalSPDXValue(obj, "packageVersion", PackageVersion);
addOptionalSPDXValue(obj, "sourceInfo", SourceInfo);
return obj;
}
cmSPDXSbom::cmSPDXSbom(cmSPDXCreationInfo const& creationInfo)
: cmSPDXBomAbstract(SOFTWARE_SBOM, creationInfo)
{
}
Json::Value cmSPDXSbom::toJsonLD() const
{
auto obj = cmSPDXBomAbstract::toJsonLD();
obj["type"] = "Sbom";
addOptionalSPDXValue(obj, "sbomType", SbomType);
return obj;
}
cmSPDXSnippet::cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo)
: cmSPDXSoftwareArtifact(SOFTWARE_SNIPPET, creationInfo)
{
}
Json::Value cmSPDXSnippet::toJsonLD() const
{
auto obj = cmSPDXSoftwareArtifact::toJsonLD();
obj["type"] = "Snippet";
addOptionalSPDXValue(obj, "byteRange", ByteRange);
addOptionalSPDXValue(obj, "lineRange", LineRange);
obj["snippetFromFile"] = SnippetFromFile.toJsonLD();
return obj;
}
// SPDX SimpleLicensing Element Classes, Concrete
cmSPDXLicenseExpression::cmSPDXLicenseExpression(
cmSPDXCreationInfo const& creationInfo)
: cmSPDXAnyLicenseInfo(SIMPLE_LICENSING_LICENSE_EXPRESSION, creationInfo)
{
}
Json::Value cmSPDXLicenseExpression::toJsonLD() const
{
auto obj = cmSPDXAnyLicenseInfo::toJsonLD();
obj["type"] = "LicenseExpression";
addOptionalSPDXValue(obj, "customIdToUri", CustomIdToUri);
obj["licenseExpression"] = LicenseExpression;
addOptionalSPDXValue(obj, "licenseListVersion", LicenseListVersion);
return obj;
}
cmSPDXSimpleLicensingText::cmSPDXSimpleLicensingText(
cmSPDXCreationInfo const& creationInfo)
: cmSPDXElement(SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT, creationInfo)
{
}
Json::Value cmSPDXSimpleLicensingText::toJsonLD() const
{
auto obj = cmSPDXElement::toJsonLD();
obj["type"] = "SimpleLicensingText";
obj["licenseText"] = LicenseText;
return obj;
}
// Graph Manipulation
#define X_SPDX(classtype, enumid, member, camel) \
template <> \
cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>() \
{ \
return cmSPDXSerializationBase::enumid; \
} \
\
template <> \
std::string cmSPDXGetTypeName<classtype>() \
{ \
return #camel; \
} \
\
cmSPDXObject::cmSPDXObject(classtype val) \
: member(std::move(val)) {}; \
\
void cmSPDXObject::get(classtype** ptr) \
{ \
*ptr = SerializationBase.getTypeId() == cmSPDXSerializationBase::enumid \
? &member \
: nullptr; \
}
#include "cmSPDXTypes.def"
cmSPDXObject::cmSPDXObject()
: IdentifierReference("UNINITIALIZED_SPDX_OBJECT")
{
}
cmSPDXObject::cmSPDXObject(cmSPDXObject const& other)
{
switch (other.SerializationBase.getTypeId()) {
#define X_SPDX(classtype, enumid, member, camel) \
case cmSPDXSerializationBase::enumid: \
new (&member) classtype(other.member); \
break;
#include "cmSPDXTypes.def"
default:
new (&IdentifierReference)
cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
}
}
cmSPDXObject::cmSPDXObject(cmSPDXObject&& other) noexcept
{
switch (other.SerializationBase.getTypeId()) {
#define X_SPDX(classtype, enumid, member, camel) \
case cmSPDXSerializationBase::enumid: \
new (&member) classtype(std::move(other.member)); \
break;
#include "cmSPDXTypes.def"
default:
new (&IdentifierReference)
cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
}
}
cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject const& other)
{
this->~cmSPDXObject();
new (this) cmSPDXObject(other);
return *this;
}
cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject&& other) noexcept
{
this->~cmSPDXObject();
new (this) cmSPDXObject(std::move(other));
return *this;
}
cmSPDXObject::~cmSPDXObject()
{
switch (SerializationBase.getTypeId()) {
#define X_SPDX(classtype, enumid, member, camel) \
case cmSPDXSerializationBase::enumid: \
member.~classtype(); \
break;
#include "cmSPDXTypes.def"
default:
break;
}
}
Json::Value cmSPDXObject::toJsonLD() const
{
switch (SerializationBase.getTypeId()) {
#define X_SPDX(classtype, enumid, member, camel) \
case cmSPDXSerializationBase::enumid: \
return member.toJsonLD();
#include "cmSPDXTypes.def"
default:
return "INVALID_SPDX_OBJECT_TYPE_ID";
}
}
cmSPDXSimpleGraph::cmSPDXSimpleGraph(std::string iriBase,
cmSPDXCreationInfo creationInfo)
: IRIBase(std::move(iriBase))
, CreationInfo(&insert<cmSPDXCreationInfo>(std::move(creationInfo)))
{
}
cmSPDXCreationInfo& cmSPDXSimpleGraph::getCreationInfo()
{
return *CreationInfo;
}
Json::Value cmSPDXSimpleGraph::toJsonLD()
{
Json::Value obj(Json::objectValue);
obj["@context"] = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
auto& graph = obj["@graph"];
for (auto const& it : Graph) {
graph.append(it.second.toJsonLD());
}
return obj;
}
-1008
View File
@@ -1,1008 +0,0 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <array>
#include <cstddef>
#include <map>
#include <new>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <cm/optional>
#include <cm/type_traits>
#include <cm3p/json/value.h>
#include "cmStringAlgorithms.h"
// Base Class
struct cmSPDXSerializationBase
{
enum SPDXTypeId
{
INVALID = -1,
NULL_ID = 0,
#define X_SPDX(classtype, enumid, title, camel) enumid,
#include "cmSPDXTypes.def"
SPDX_TYPE_ID_MAX,
};
SPDXTypeId getTypeId() const;
std::string NodeId;
protected:
cmSPDXSerializationBase(SPDXTypeId id);
cmSPDXSerializationBase(SPDXTypeId id, std::string nodeId);
private:
SPDXTypeId TypeId;
};
// Convenience Classes
struct cmSPDXIdentifierReference : cmSPDXSerializationBase
{
cmSPDXIdentifierReference();
cmSPDXIdentifierReference(cmSPDXSerializationBase const& ref);
cmSPDXIdentifierReference(std::string const& ref);
Json::Value toJsonLD() const;
};
struct cmSPDXNonElementBase : cmSPDXSerializationBase
{
protected:
cmSPDXNonElementBase(SPDXTypeId id);
Json::Value toJsonLD() const;
};
// SPDX Core Data Types
// Nominally these are supposed to be validated strings
using cmSPDXDateTime = std::string;
using cmSPDXMediaType = std::string;
using cmSPDXSemVer = std::string;
// SPDX Core Enums
struct cmSPDXAnnotationType
{
enum cmSPDXAnnotationTypeId
{
INVALID = -1,
NULL_ID = 0,
OTHER,
REVIEW,
};
cmSPDXAnnotationTypeId TypeId;
cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXExternalIdentifierType
{
enum cmSPDXExternalIdentifierTypeId
{
INVALID = -1,
NULL_ID = 0,
CPE22,
CPE23,
CVE,
EMAIL,
GITOID,
OTHER,
PACKAGE_URL,
SECURITY_OTHER,
SWHID,
SWID,
URL_SCHEME,
};
cmSPDXExternalIdentifierTypeId TypeId;
cmSPDXExternalIdentifierType(
cmSPDXExternalIdentifierTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXExternalRefType
{
enum cmSPDXExternalRefTypeId
{
INVALID = -1,
NULL_ID = 0,
ALT_DOWNLOAD_LOCATION,
ALT_WEB_PAGE,
BINARY_ARTIFACT,
BOWER,
BUILD_META,
BUILD_SYSTEM,
CERTIFICATION_REPORT,
CHAT,
COMPONENT_ANALYSIS_REPORT,
CWE,
DOCUMENTATION,
DYNAMIC_ANALYSIS_REPORT,
EOL_NOTICE,
EXPORT_CONTROL_ASSESSMENT,
FUNDING,
ISSUE_TRACKER,
LICENSE,
MAILING_LIST,
MAVEN_CENTRAL,
METRICS,
NPM,
NUGET,
OTHER,
PRIVACY_ASSESSMENT,
PRODUCT_METADATA,
PURCHASE_ORDER,
QUALITY_ASSESSMENT_REPORT,
RELEASE_HISTORY,
RELEASE_NOTES,
RISK_ASSESSMENT,
RUNTIME_ANALYSIS_REPORT,
SECURE_SOFTWARE_ATTESTATION,
SECURITY_ADVERSARY_MODEL,
SECURITY_ADVISORY,
SECURITY_FIX,
SECURITY_OTHER,
SECURITY_PEN_TEST_REPORT,
SECURITY_POLICY,
SECURITY_THREAT_MODEL,
SOCIAL_MEDIA,
SOURCE_ARTIFACT,
STATIC_ANALYSIS_REPORT,
SUPPORT,
VCS,
VULNERABILITY_DISCLOSURE_REPORT,
VULNERABILITY_EXPLOITABILITY_ASSESSMENT,
};
cmSPDXExternalRefTypeId TypeId;
cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXHashAlgorithm
{
enum cmSPDXHashAlgorithmId
{
INVALID = -1,
NULL_ID = 0,
ADLER32,
BLAKE2B256,
BLAKE2B384,
BLAKE2B512,
BLAKE3,
CRYSTALS_DILITHIUM,
CRYSTALS_KYBER,
FALCON,
MD2,
MD4,
MD5,
MD6,
OTHER,
SHA1,
SHA224,
SHA256,
SHA384,
SHA3_224,
SHA3_256,
SHA3_384,
SHA3_512,
SHA512,
};
cmSPDXHashAlgorithmId TypeId;
cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXLifecycleScopeType
{
enum cmSPDXLifecycleScopeTypeId
{
INVALID = -1,
NULL_ID = 0,
BUILD,
DESIGN,
DEVELOPMENT,
OTHER,
RUNTIME,
TEST,
};
cmSPDXLifecycleScopeTypeId TypeId;
cmSPDXLifecycleScopeType(cmSPDXLifecycleScopeTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXProfileIdentifierType
{
enum cmSPDXProfileIdentifierTypeId
{
INVALID = -1,
NULL_ID = 0,
AI,
BUILD,
CORE,
DATASET,
EXPANDED_LICENSING,
EXTENSION,
LITE,
SECURITY,
SIMPLE_LICENSING,
SOFTWARE,
};
cmSPDXProfileIdentifierTypeId TypeId;
cmSPDXProfileIdentifierType(cmSPDXProfileIdentifierTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXRelationshipCompletenessType
{
enum cmSPDXRelationshipCompletenessTypeId
{
INVALID = -1,
NULL_ID = 0,
COMPLETE,
INCOMPLETE,
NO_ASSERTION,
};
cmSPDXRelationshipCompletenessTypeId TypeId;
cmSPDXRelationshipCompletenessType(
cmSPDXRelationshipCompletenessTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXRelationshipType
{
enum cmSPDXRelationshipTypeId
{
INVALID = -1,
NULL_ID = 0,
AFFECTS,
AMENDED_BY,
ANCESTOR_OF,
AVAILABLE_FROM,
CONFIGURES,
CONTAINS,
COORDINATED_BY,
COPIED_TO,
DELEGATED_TO,
DEPENDS_ON,
DESCENDANT_OF,
DESCRIBES,
DOES_NOT_AFFECT,
EXPANDS_TO,
EXPLOIT_CREATED_BY,
FIXED_BY,
FIXED_IN,
FOUND_BY,
GENERATES,
HAS_ADDED_FILE,
HAS_ASSESSMENT_FOR,
HAS_ASSOCIATED_VULNERABILITY,
HAS_CONCLUDED_LICENSE,
HAS_DATA_FILE,
HAS_DECLARED_LICENSE,
HAS_DELETED_FILE,
HAS_DEPENDENCY_MANIFEST,
HAS_DISTRIBUTION_ARTIFACT,
HAS_DOCUMENTATION,
HAS_DYNAMIC_LINK,
HAS_EVIDENCE,
HAS_EXAMPLE,
HAS_HOST,
HAS_INPUT,
HAS_METADATA,
HAS_OPTIONAL_COMPONENT,
HAS_OPTIONAL_DEPENDENCY,
HAS_OUTPUT,
HAS_PREREQUISITE,
HAS_PROVIDED_DEPENDENCY,
HAS_REQUIREMENT,
HAS_SPECIFICATION,
HAS_STATIC_LINK,
HAS_TEST,
HAS_TEST_CASE,
HAS_VARIANT,
INVOKED_BY,
MODIFIED_BY,
OTHER,
PACKAGED_BY,
PATCHED_BY,
PUBLISHED_BY,
REPORTED_BY,
REPUBLISHED_BY,
SERIALIZED_IN_ARTIFACT,
TESTED_ON,
TRAINED_ON,
UNDER_INVESTIGATION_FOR,
USES_TOOL,
};
cmSPDXRelationshipTypeId TypeId;
cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXSupportType
{
enum cmSPDXSupportTypeId
{
INVALID = -1,
NULL_ID = 0,
DEPLOYED,
DEVELOPMENT,
END_OF_SUPPORT,
LIMITED_SUPPORT,
NO_ASSERTION,
NO_SUPPORT,
SUPPORT,
};
cmSPDXSupportTypeId TypeId;
cmSPDXSupportType(cmSPDXSupportTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
// SPDX Core NonElement Classes, Abstract
struct cmSPDXIntegrityMethod : cmSPDXNonElementBase
{
cm::optional<std::string> Comment;
protected:
cmSPDXIntegrityMethod(SPDXTypeId id);
Json::Value toJsonLD() const;
};
// SPDX Core NonElement Classes, Concrete
struct cmSPDXCreationInfo : cmSPDXNonElementBase
{
cm::optional<std::string> Comment;
cmSPDXDateTime Created;
std::vector<cmSPDXIdentifierReference> CreatedBy;
cm::optional<std::vector<cmSPDXIdentifierReference>> CreatedUsing;
cmSPDXCreationInfo();
Json::Value toJsonLD() const;
};
struct cmSPDXDictionaryEntry : cmSPDXNonElementBase
{
std::string Key;
cm::optional<std::string> Value;
cmSPDXDictionaryEntry();
cmSPDXDictionaryEntry(std::string key);
cmSPDXDictionaryEntry(std::string key, std::string val);
Json::Value toJsonLD() const;
};
struct cmSPDXExternalIdentifier : cmSPDXNonElementBase
{
cm::optional<std::string> Comment;
cmSPDXExternalIdentifierType ExternalIdentifierType;
std::string Identifier;
cm::optional<std::vector<std::string>> IdentifierLocator;
cm::optional<std::string> IssuingAuthority;
cmSPDXExternalIdentifier();
Json::Value toJsonLD() const;
};
struct cmSPDXExternalMap : cmSPDXNonElementBase
{
cm::optional<cmSPDXIdentifierReference> DefiningArtifact;
std::string ExternalSpdxId;
cm::optional<std::string> LocationHint;
cm::optional<std::vector<cmSPDXIdentifierReference>> IntegrityMethod;
cmSPDXExternalMap();
Json::Value toJsonLD() const;
};
struct cmSPDXExternalRef : cmSPDXNonElementBase
{
cm::optional<std::string> Comment;
cm::optional<cmSPDXMediaType> ContentType;
cm::optional<cmSPDXExternalRefType> ExternalRefType;
cm::optional<std::vector<std::string>> Locator;
cmSPDXExternalRef();
Json::Value toJsonLD() const;
};
struct cmSPDXHash : cmSPDXIntegrityMethod
{
cmSPDXHashAlgorithm Algorithm;
std::string HashValue;
cmSPDXHash();
Json::Value toJsonLD() const;
};
struct cmSPDXNamespaceMap : cmSPDXNonElementBase
{
std::string Namespace;
std::string Prefix;
cmSPDXNamespaceMap();
Json::Value toJsonLD() const;
};
struct cmSPDXPackageVerificationCode : cmSPDXIntegrityMethod
{
cmSPDXHashAlgorithm Algorithm;
std::string HashValue;
cm::optional<std::vector<std::string>> PackageVerificationCodeExcludedFile;
cmSPDXPackageVerificationCode();
Json::Value toJsonLD() const;
};
struct cmSPDXPositiveIntegerRange : cmSPDXNonElementBase
{
unsigned int BeginIntegerRange;
unsigned int EndIntegerRange;
cmSPDXPositiveIntegerRange(unsigned int beingIntegerRange = 0,
unsigned int endIntegerRange = 0);
Json::Value toJsonLD() const;
};
// SPDX Core Element Classes, Abstract
struct cmSPDXElement : cmSPDXSerializationBase
{
cm::optional<std::string> Comment;
cmSPDXIdentifierReference CreationInfo;
cm::optional<std::string> Description;
cm::optional<std::vector<cmSPDXIdentifierReference>> Extension;
cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalIdentifier;
cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalRef;
cm::optional<std::string> Name;
// SpdxId is the NodeId
cm::optional<std::string> Summary;
cm::optional<std::vector<cmSPDXIdentifierReference>> VerifiedUsing;
protected:
cmSPDXElement(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXArtifact : cmSPDXElement
{
cm::optional<cmSPDXDateTime> BuiltTime;
cm::optional<std::vector<cmSPDXIdentifierReference>> OriginatedBy;
cm::optional<cmSPDXDateTime> ReleaseTime;
cm::optional<std::vector<std::string>> StandardName;
cm::optional<cmSPDXIdentifierReference> SuppliedBy;
cm::optional<std::vector<cmSPDXSupportType>> SupportType;
cm::optional<cmSPDXDateTime> ValidUntilTime;
protected:
cmSPDXArtifact(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXElementCollection : cmSPDXElement
{
cm::optional<std::vector<cmSPDXIdentifierReference>> Element;
cm::optional<std::vector<cmSPDXProfileIdentifierType>> ProfileConformance;
cm::optional<std::vector<cmSPDXIdentifierReference>> RootElement;
protected:
cmSPDXElementCollection(SPDXTypeId id,
cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// SPDX Implicit Core Element Classes, Abstract
// Nominally an inheritable class, but adds nothing to Element
using cmSPDXAgentAbstract = cmSPDXElement;
struct cmSPDXBundleAbstract : cmSPDXElementCollection
{
std::string Context;
protected:
cmSPDXBundleAbstract(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// Nominally an inheritable class, but adds nothing to Bundle
using cmSPDXBomAbstract = cmSPDXBundleAbstract;
struct cmSPDXRelationshipAbstract : cmSPDXElement
{
cm::optional<cmSPDXRelationshipCompletenessType> Completeness;
cm::optional<cmSPDXDateTime> EndTime;
cmSPDXIdentifierReference From;
cmSPDXRelationshipType RelationshipType;
cm::optional<cmSPDXDateTime> StartTime;
std::vector<cmSPDXIdentifierReference> To;
protected:
cmSPDXRelationshipAbstract(SPDXTypeId id,
cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// SPDX Core Element Classes, Concrete
struct cmSPDXAgent : cmSPDXAgentAbstract
{
cmSPDXAgent(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXAnnotation : cmSPDXElement
{
cmSPDXAnnotationType AnnotationType;
cm::optional<cmSPDXMediaType> ContentType;
cm::optional<std::string> Statement;
cmSPDXIdentifierReference Subject;
cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
cmSPDXIdentifierReference subject = {});
Json::Value toJsonLD() const;
};
struct cmSPDXBom : cmSPDXBomAbstract
{
cmSPDXBom(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXBundle : cmSPDXBundleAbstract
{
cmSPDXBundle(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXIndividualElement : cmSPDXElement
{
cmSPDXIndividualElement(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXLifecycleScopedRelationship : cmSPDXRelationshipAbstract
{
cm::optional<cmSPDXLifecycleScopeType> Scope;
cmSPDXLifecycleScopedRelationship(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXOrganization : cmSPDXAgentAbstract
{
cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXPerson : cmSPDXAgentAbstract
{
cmSPDXPerson(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXRelationship : cmSPDXRelationshipAbstract
{
cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXSoftwareAgent : cmSPDXAgentAbstract
{
cmSPDXSoftwareAgent(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXSpdxDocument : cmSPDXElementCollection
{
cm::optional<cmSPDXIdentifierReference> DataLicense;
cm::optional<cmSPDXIdentifierReference> ExternalMap;
cm::optional<cmSPDXIdentifierReference> NamespaceMap;
cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXTool : cmSPDXElement
{
cmSPDXTool(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// SPDX Software Enums
struct cmSPDXContentIdentifierType
{
enum cmSPDXContentIdentifierTypeId
{
INVALID = -1,
NULL_ID = 0,
GITOID,
SWHID,
};
cmSPDXContentIdentifierTypeId TypeId;
cmSPDXContentIdentifierType(cmSPDXContentIdentifierTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXFileKindType
{
enum cmSPDXFileKindTypeId
{
INVALID = -1,
NULL_ID = 0,
DIRECTORY,
FILE,
};
cmSPDXFileKindTypeId TypeId;
cmSPDXFileKindType(cmSPDXFileKindTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXSbomType
{
enum cmSPDXSbomTypeId
{
INVALID = -1,
NULL_ID = 0,
ANALYZED,
BUILD,
DEPLOYED,
DESIGN,
RUNTIME,
SOURCE,
};
cmSPDXSbomTypeId TypeId;
cmSPDXSbomType(cmSPDXSbomTypeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
struct cmSPDXSoftwarePurpose
{
enum cmSPDXSoftwarePurposeId
{
INVALID = -1,
NULL_ID = 0,
APPLICATION,
ARCHIVE,
BOM,
CONFIGURATION,
CONTAINER,
DATA,
DEVICE,
DEVICE_DRIVER,
DISK_IMAGE,
DOCUMENTATION,
EVIDENCE,
EXECUTABLE,
FILE,
FILESYSTEM_IMAGE,
FIRMWARE,
FRAMEWORK,
INSTALL,
LIBRARY,
MANIFEST,
MODEL,
MODULE,
OPERATING_SYSTEM,
OTHER,
PATCH,
PLATFORM,
REQUIREMENT,
SOURCE,
SPECIFICATION,
TEST,
};
cmSPDXSoftwarePurposeId TypeId;
cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId = NULL_ID);
Json::Value toJsonLD() const;
};
// SPDX Software NonElement Classes, Concrete
struct cmSPDXContentIdentifier : cmSPDXIntegrityMethod
{
cmSPDXContentIdentifierType ContentIdentifierType;
std::string ContentIdentifierValue;
cmSPDXContentIdentifier();
Json::Value toJsonLD() const;
};
// SPDX Software Element Classes, Abstract
struct cmSPDXSoftwareArtifact : cmSPDXArtifact
{
cm::optional<std::vector<cmSPDXSoftwarePurpose>> AdditionalPurpose;
cm::optional<std::string> AttributionText;
cm::optional<cmSPDXIdentifierReference> ContentIdentifier;
cm::optional<std::string> CopyrightText;
cm::optional<cmSPDXSoftwarePurpose> PrimaryPurpose;
protected:
cmSPDXSoftwareArtifact(SPDXTypeId id,
cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// SPDX Software Element Classes, Concrete
struct cmSPDXFile : cmSPDXSoftwareArtifact
{
cm::optional<cmSPDXMediaType> ContentType;
cm::optional<cmSPDXFileKindType> FileKind;
cmSPDXFile(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXPackage : cmSPDXSoftwareArtifact
{
cm::optional<std::string> DownloadLocation;
cm::optional<std::string> HomePage;
cm::optional<std::string> PackageUrl;
cm::optional<std::string> PackageVersion;
cm::optional<std::string> SourceInfo;
cmSPDXPackage(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXSbom : cmSPDXBomAbstract
{
cm::optional<std::vector<cmSPDXSbomType>> SbomType;
cmSPDXSbom(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXSnippet : cmSPDXSoftwareArtifact
{
cm::optional<cmSPDXIdentifierReference> ByteRange;
cm::optional<cmSPDXIdentifierReference> LineRange;
cmSPDXIdentifierReference SnippetFromFile;
cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo);
Json::Value toJsonLD() const;
};
// SPDX SimpleLicensing Element Classes, Abstract
// Nominally an inheritable class, but adds nothing to Element
using cmSPDXAnyLicenseInfo = cmSPDXElement;
// SPDX SimpleLicensing Element Classes, Concrete
struct cmSPDXLicenseExpression : cmSPDXAnyLicenseInfo
{
cm::optional<std::vector<cmSPDXIdentifierReference>> CustomIdToUri;
std::string LicenseExpression;
cm::optional<cmSPDXSemVer> LicenseListVersion;
cmSPDXLicenseExpression(cmSPDXCreationInfo const& CreationInfo);
Json::Value toJsonLD() const;
};
struct cmSPDXSimpleLicensingText : cmSPDXElement
{
std::string LicenseText;
cmSPDXSimpleLicensingText(cmSPDXCreationInfo const& CreationInfo);
Json::Value toJsonLD() const;
};
// Graph Manipulation
template <typename T>
cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId();
template <typename T>
std::string cmSPDXGetTypeName();
#define X_SPDX(classtype, enumid, member, camel) \
template <> \
cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>(); \
\
template <> \
std::string cmSPDXGetTypeName<classtype>();
#include "cmSPDXTypes.def"
template <class T>
struct cmSPDXTag
{
using type = T;
};
union cmSPDXObject
{
cmSPDXSerializationBase SerializationBase;
cmSPDXObject();
cmSPDXObject(cmSPDXObject const& other);
cmSPDXObject(cmSPDXObject&& other) noexcept;
#define X_SPDX(classtype, enumid, member, camel) \
classtype member; \
cmSPDXObject(classtype val); \
\
template <typename... Args> \
cmSPDXObject(cmSPDXTag<classtype>, Args&&... args) \
{ \
new (&member) classtype(std::forward<Args>(args)...); \
}
#include "cmSPDXTypes.def"
cmSPDXObject& operator=(cmSPDXObject const& other);
cmSPDXObject& operator=(cmSPDXObject&& other) noexcept;
~cmSPDXObject();
template <typename T>
T* get()
{
T* ptr;
get(&ptr);
return ptr;
}
Json::Value toJsonLD() const;
private:
#define X_SPDX(classtype, enumid, member, camel) void get(classtype** ptr);
#include "cmSPDXTypes.def"
};
struct cmSPDXSimpleGraph
{
cmSPDXSimpleGraph(std::string iriBase, cmSPDXCreationInfo creationInfo = {});
template <typename T, typename... Args>
cm::enable_if_t<std::is_base_of<cmSPDXElement, T>::value, T>& insert(
Args&&... args)
{
std::string nodeId = cmStrCat(IRIBase, IRICount++);
auto const& it =
Graph.emplace(std::piecewise_construct, std::forward_as_tuple(nodeId),
std::forward_as_tuple(cmSPDXTag<T>{}, *CreationInfo,
std::forward<Args>(args)...));
auto& node = *it.first->second.template get<T>();
node.NodeId = std::move(nodeId);
return node;
}
cmSPDXCreationInfo& getCreationInfo();
template <typename T, typename... Args>
cm::enable_if_t<std::is_base_of<cmSPDXNonElementBase, T>::value, T>& insert(
Args&&... args)
{
std::size_t nodeCount = BlankCounts[cmSPDXGetTypeId<T>()]++;
std::string nodeId =
cmStrCat("_:", cmSPDXGetTypeName<T>(), "_", nodeCount);
auto const& it = Graph.emplace(
std::piecewise_construct, std::forward_as_tuple(nodeId),
std::forward_as_tuple(cmSPDXTag<T>{}, std::forward<Args>(args)...));
auto& node = *it.first->second.template get<T>();
node.NodeId = std::move(nodeId);
return node;
}
template <typename T>
T* get(std::string const& key)
{
auto it = Graph.find(key);
if (it == Graph.end()) {
return nullptr;
}
return it->second.get<T>();
}
template <typename T>
T* get(cmSPDXIdentifierReference const& key)
{
auto it = Graph.find(key.NodeId);
if (it == Graph.end()) {
return nullptr;
}
return it->second.get<T>();
}
Json::Value toJsonLD();
private:
std::string IRIBase;
std::size_t IRICount{ 0 };
std::array<std::size_t, cmSPDXSerializationBase::SPDX_TYPE_ID_MAX>
BlankCounts{};
std::map<std::string, cmSPDXObject> Graph;
cmSPDXCreationInfo* CreationInfo;
};
-54
View File
@@ -1,54 +0,0 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#ifndef X_SPDX
# define X_SPDX(classtype, enumid, member, camel)
#endif
// Convenience
X_SPDX(cmSPDXIdentifierReference, CM_IDENTIFIER_REFERENCE, IdentifierReference,
identifierReference)
// Core
X_SPDX(cmSPDXAgent, CORE_AGENT, Agent, agent)
X_SPDX(cmSPDXAnnotation, CORE_ANNOTATION, Annotation, annotation)
X_SPDX(cmSPDXBom, CORE_BOM, Bom, bom)
X_SPDX(cmSPDXBundle, CORE_BUNDLE, Bundle, bundle)
X_SPDX(cmSPDXCreationInfo, CORE_CREATION_INFO, CreationInfo, creationInfo)
X_SPDX(cmSPDXDictionaryEntry, CORE_DICTIONARY_ENTRY, DictionaryEntry,
dictionaryEntry)
X_SPDX(cmSPDXExternalIdentifier, CORE_EXTERNAL_IDENTIFIER, ExternalIdentifier,
externalIdentifier)
X_SPDX(cmSPDXExternalMap, CORE_EXTERNAL_MAP, ExternalMap, externalMap)
X_SPDX(cmSPDXExternalRef, CORE_EXTERNAL_REF, ExternalRef, externalRef)
X_SPDX(cmSPDXHash, CORE_HASH, Hash, hash)
X_SPDX(cmSPDXIndividualElement, CORE_INDIVIDUAL_ELEMENT, IndividualElement,
individualElement)
X_SPDX(cmSPDXLifecycleScopedRelationship, CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
LifecycleScopedRelationship, lifecycleScopedRelationship)
X_SPDX(cmSPDXNamespaceMap, CORE_NAMESPACE_MAP, NamespaceMap, namespaceMap)
X_SPDX(cmSPDXOrganization, CORE_ORGANIZATION, Organization, organization)
X_SPDX(cmSPDXPackageVerificationCode, CORE_PACKAGE_VERIFICATION_CODE,
PackageVerificationCode, packageVerificationCode)
X_SPDX(cmSPDXPerson, CORE_PERSON, Person, person)
X_SPDX(cmSPDXPositiveIntegerRange, CORE_POSITIVE_INTEGER_RANGE,
PositiveIntegerRange, positiveIntegerRange)
X_SPDX(cmSPDXRelationship, CORE_RELATIONSHIP, Relationship, relationship)
X_SPDX(cmSPDXSoftwareAgent, CORE_SOFTWARE_AGENT, SoftwareAgent, softwareAgent)
X_SPDX(cmSPDXSpdxDocument, CORE_SPDX_DOCUMENT, SpdxDocument, spdxDocument)
X_SPDX(cmSPDXTool, CORE_TOOL, Tool, tool)
// Software
X_SPDX(cmSPDXContentIdentifier, SOFTWARE_CONTENT_IDENTIFIER, ContentIdentifier,
contentIdentifier)
X_SPDX(cmSPDXFile, SOFTWARE_FILE, File, file)
X_SPDX(cmSPDXPackage, SOFTWARE_PACKAGE, Package, package)
X_SPDX(cmSPDXSbom, SOFTWARE_SBOM, Sbom, sbom)
X_SPDX(cmSPDXSnippet, SOFTWARE_SNIPPET, Snippet, snippet)
// SimpleLicensing
X_SPDX(cmSPDXLicenseExpression, SIMPLE_LICENSING_LICENSE_EXPRESSION,
LicenseExpression, licenseExpression)
X_SPDX(cmSPDXSimpleLicensingText, SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT,
SimpleLicensingText, simpleLicensingText)
#undef X_SPDX
+270
View File
@@ -0,0 +1,270 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include <cm/type_traits>
#include "cmSbomSerializer.h"
class cmSbomObject;
template <typename T>
inline void SerializeDispatch(T const& t, cmSbomSerializer& serializer)
{
serializer.BeginObject();
t.Serialize(serializer);
serializer.EndObject();
}
template <typename T>
inline void SerializeDispatch(T* p, cmSbomSerializer& serializer)
{
if (p->SpdxId) {
serializer.AddReference(*p->SpdxId);
}
}
inline void SerializeDispatch(std::nullptr_t, cmSbomSerializer&)
{
}
struct ObjectInterface
{
virtual ObjectInterface* Copy(void* storage) const = 0;
virtual ObjectInterface* Move(void* storage) = 0;
virtual void* Addr() noexcept = 0;
virtual void const* Addr() const noexcept = 0;
virtual void SerializeImpl(cmSbomSerializer& os) const = 0;
virtual ~ObjectInterface() = default;
ObjectInterface() = default;
ObjectInterface(ObjectInterface const&) = default;
ObjectInterface& operator=(ObjectInterface const&) = default;
ObjectInterface(ObjectInterface&&) noexcept = default;
ObjectInterface& operator=(ObjectInterface&&) noexcept = default;
};
namespace impl {
#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20150623
using max_align_t = ::max_align_t;
#else
using max_align_t = std::max_align_t;
#endif
enum class StorageKind
{
Stack,
Heap
};
template <typename, StorageKind>
struct Storage
{
};
template <typename T>
struct Storage<T, StorageKind::Stack> : ObjectInterface
{
using ValueType = cm::decay_t<T>;
explicit Storage(T x)
: Value(std::move(x))
{
}
Storage(Storage&&) noexcept(
std::is_nothrow_move_constructible<ValueType>::value) = default;
~Storage() override = default;
void* Addr() noexcept override { return std::addressof(Value); }
void const* Addr() const noexcept override { return std::addressof(Value); }
ValueType& get() { return Value; }
ValueType const& get() const { return Value; }
private:
ValueType Value;
};
template <typename T>
struct Storage<T, StorageKind::Heap> : ObjectInterface
{
using ValueType = cm::decay_t<T>;
explicit Storage(T x)
: Ptr(new T(std::move(x)))
{
}
Storage(Storage&&) noexcept = default;
~Storage() override = default;
void* Addr() noexcept override { return Ptr.get(); }
void const* Addr() const noexcept override { return Ptr.get(); }
ValueType& get() { return *Ptr; }
ValueType const& get() const { return *Ptr; }
private:
std::unique_ptr<ValueType> Ptr;
};
template <>
struct Storage<std::nullptr_t, StorageKind::Stack> : ObjectInterface
{
explicit Storage(std::nullptr_t) {}
Storage(Storage&&) noexcept = default;
~Storage() override = default;
void* Addr() noexcept override { return nullptr; }
void const* Addr() const noexcept override { return nullptr; }
void SerializeImpl(cmSbomSerializer&) const override {}
std::nullptr_t get() { return nullptr; }
std::nullptr_t get() const { return nullptr; }
};
}
struct ObjectStorage
{
template <typename T>
using Stack = impl::Storage<T, impl::StorageKind::Stack>;
template <typename T>
using Heap = impl::Storage<T, impl::StorageKind::Heap>;
static constexpr std::size_t BufferSize = 128u;
static constexpr std::size_t Size = sizeof(Heap<std::nullptr_t>) > BufferSize
? sizeof(Heap<std::nullptr_t>)
: BufferSize;
static constexpr std::size_t Align = alignof(impl::max_align_t);
struct Buffer
{
alignas(Align) unsigned char Data[Size];
};
template <typename Concrete>
using Model = cm::conditional_t<sizeof(Stack<Concrete>) <= Size &&
alignof(Stack<Concrete>) <= Align,
Stack<Concrete>, Heap<Concrete>>;
};
class cmSbomObject
{
public:
template <typename T>
struct Instance : ObjectStorage::Model<T>
{
using Base = ObjectStorage::Model<T>;
using Base::Base;
Instance(Instance&&) noexcept = default;
ObjectInterface* Copy(void* storage) const override
{
return ::new (storage) Instance(this->get());
}
ObjectInterface* Move(void* storage) override
{
return ::new (storage) Instance(std::move(*this));
}
void SerializeImpl(cmSbomSerializer& os) const override
{
SerializeDispatch(this->get(), os);
}
};
cmSbomObject() { ::new (Storage()) Instance<std::nullptr_t>(nullptr); }
cmSbomObject(std::nullptr_t)
: cmSbomObject()
{
}
template <
typename T, typename Decayed = cm::remove_cv_t<cm::remove_reference_t<T>>,
typename = cm::enable_if_t<!std::is_same<Decayed, cmSbomObject>::value>>
cmSbomObject(T&& x)
{
::new (Storage()) Instance<Decayed>(std::forward<T>(x));
}
cmSbomObject(cmSbomObject const& other)
{
other.Interface().Copy(Storage());
}
cmSbomObject(cmSbomObject&& other) noexcept
{
other.Interface().Move(Storage());
}
~cmSbomObject() noexcept { Interface().~ObjectInterface(); }
cmSbomObject& operator=(cmSbomObject rhs)
{
Interface().~ObjectInterface();
rhs.Interface().Move(Storage());
return *this;
}
bool IsNull() const noexcept { return Interface().Addr() == nullptr; }
explicit operator bool() const noexcept { return !IsNull(); }
void Serialize(cmSbomSerializer& os) const { Interface().SerializeImpl(os); }
template <typename T>
T& CastUnchecked()
{
return *static_cast<T*>(Interface().Addr());
}
template <typename T>
T const& CastUnchecked() const
{
return *static_cast<T const*>(Interface().Addr());
}
ObjectInterface& Interface()
{
return *static_cast<ObjectInterface*>(Storage());
}
ObjectInterface const& Interface() const
{
return *static_cast<ObjectInterface const*>(Storage());
}
void* Storage() { return &Data.Data; }
void const* Storage() const { return &Data.Data; }
template <typename U>
U* ptr() noexcept
{
return std::addressof(this->template CastUnchecked<U>());
}
template <typename U>
U const* ptr() const noexcept
{
return std::addressof(this->template CastUnchecked<U>());
}
private:
ObjectStorage::Buffer Data{};
};
template <typename T, typename U = cm::decay_t<T>>
U* insert_back(std::vector<cmSbomObject>& vec, T&& obj) noexcept
{
vec.emplace_back(std::forward<U>(obj));
return std::addressof(vec.back().CastUnchecked<U>());
}
+38
View File
@@ -0,0 +1,38 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <string>
#include <vector>
#include <cm/optional>
class cmSbomObject;
class cmSbomSerializer
{
public:
cmSbomSerializer() = default;
cmSbomSerializer(cmSbomSerializer const&) = default;
cmSbomSerializer(cmSbomSerializer&&) = default;
cmSbomSerializer& operator=(cmSbomSerializer const&) = default;
cmSbomSerializer& operator=(cmSbomSerializer&&) = default;
virtual void BeginObject() {}
virtual void EndObject() {}
virtual void BeginArray() {}
virtual void EndArray() {}
virtual void AddReference(std::string const& id) = 0;
virtual void AddString(std::string const& key, std::string const& value) = 0;
virtual void AddVisitable(std::string const& key,
cmSbomObject const& visitable) = 0;
virtual void AddVectorIfPresent(std::string const& key,
std::vector<cmSbomObject> const& vec) = 0;
virtual void AddVectorIfPresent(std::string const& key,
std::vector<std::string> const& vec) = 0;
virtual bool WriteSbom(std::ostream& os, cmSbomObject const& document) = 0;
virtual ~cmSbomSerializer() = default;
};
+520
View File
@@ -0,0 +1,520 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmSpdx.h"
#include <stdexcept>
#include <string>
#include "cmSbomSerializer.h"
inline void SerializeIfPresent(cmSbomSerializer& s, std::string const& key,
cm::optional<std::string> const& v)
{
if (v) {
s.AddString(key, *v);
}
}
std::string to_string(cmSpdxIntegrityMethod::HashAlgorithmId id)
{
switch (id) {
case cmSpdxIntegrityMethod::HashAlgorithmId::ADLER32:
return "ADLER32";
case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B256:
return "BLAKE2B256";
case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B384:
return "BLAKE2B384";
case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B512:
return "BLAKE2B512";
case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE3:
return "BLAKE3";
case cmSpdxIntegrityMethod::HashAlgorithmId::MD2:
return "MD2";
case cmSpdxIntegrityMethod::HashAlgorithmId::MD4:
return "MD4";
case cmSpdxIntegrityMethod::HashAlgorithmId::MD5:
return "MD5";
case cmSpdxIntegrityMethod::HashAlgorithmId::MD6:
return "MD6";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA1:
return "SHA1";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA224:
return "SHA224";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA256:
return "SHA256";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA384:
return "SHA384";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA512:
return "SHA512";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_256:
return "SHA3_256";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_384:
return "SHA3_384";
case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_512:
return "SHA3_512";
}
throw std::invalid_argument("Unknown HashAlgorithmId");
}
std::string to_string(cmSpdxSoftwareArtifact::PurposeId id)
{
switch (id) {
case cmSpdxSoftwareArtifact::PurposeId::APPLICATION:
return "APPLICATION";
case cmSpdxSoftwareArtifact::PurposeId::ARCHIVE:
return "ARCHIVE";
case cmSpdxSoftwareArtifact::PurposeId::CONTAINER:
return "CONTAINER";
case cmSpdxSoftwareArtifact::PurposeId::DATA:
return "DATA";
case cmSpdxSoftwareArtifact::PurposeId::DEVICE:
return "DEVICE";
case cmSpdxSoftwareArtifact::PurposeId::FIRMWARE:
return "FIRMWARE";
case cmSpdxSoftwareArtifact::PurposeId::FILE:
return "FILE";
case cmSpdxSoftwareArtifact::PurposeId::INSTALL:
return "INSTALL";
case cmSpdxSoftwareArtifact::PurposeId::LIBRARY:
return "LIBRARY";
case cmSpdxSoftwareArtifact::PurposeId::MODULE:
return "MODULE";
case cmSpdxSoftwareArtifact::PurposeId::OPERATING_SYSTEM:
return "OPERATING_SYSTEM";
case cmSpdxSoftwareArtifact::PurposeId::SOURCE:
return "SOURCE";
}
throw std::invalid_argument("Unknown PurposeId");
}
std::string to_string(cmSpdxSbom::TypeId id)
{
switch (id) {
case cmSpdxSbom::TypeId::ANALYZED:
return "ANALYZED";
case cmSpdxSbom::TypeId::BUILD:
return "BUILD";
case cmSpdxSbom::TypeId::DEPLOYED:
return "DEPLOYED";
case cmSpdxSbom::TypeId::DESIGN:
return "DESIGN";
case cmSpdxSbom::TypeId::RUNTIME:
return "RUNTIME";
case cmSpdxSbom::TypeId::SOURCE:
return "SOURCE";
case cmSpdxSbom::TypeId::TEST:
return "TEST";
}
throw std::invalid_argument("Unknown Sbom::TypeId");
}
std::string to_string(cmSpdxFile::FileKindId id)
{
switch (id) {
case cmSpdxFile::FileKindId::DIRECTORY:
return "DIRECTORY";
case cmSpdxFile::FileKindId::FILE:
return "FILE";
}
throw std::invalid_argument("Unknown File::FileKindId");
}
std::string to_string(cmSpdxRelationship::RelationshipTypeId id)
{
switch (id) {
case cmSpdxRelationship::RelationshipTypeId::DESCRIBES:
return "DESCRIBES";
case cmSpdxRelationship::RelationshipTypeId::CONTAINS:
return "CONTAINS";
case cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON:
return "DEPENDS_ON";
case cmSpdxRelationship::RelationshipTypeId::OTHER:
return "OTHER";
}
throw std::invalid_argument("Unknown RelationshipTypeId");
}
std::string to_string(cmSpdxLifecycleScopedRelationship::ScopeId id)
{
switch (id) {
case cmSpdxLifecycleScopedRelationship::ScopeId::BUILD:
return "BUILD";
case cmSpdxLifecycleScopedRelationship::ScopeId::DESIGN:
return "DESIGN";
case cmSpdxLifecycleScopedRelationship::ScopeId::RUNTIME:
return "RUNTIME";
case cmSpdxLifecycleScopedRelationship::ScopeId::TEST:
return "TEST";
}
throw std::invalid_argument("Unknown Lifecycle ScopeId");
}
std::string to_string(cmSpdxAnnotation::AnnotationTypeId id)
{
switch (id) {
case cmSpdxAnnotation::AnnotationTypeId::REVIEW:
return "REVIEW";
case cmSpdxAnnotation::AnnotationTypeId::OTHER:
return "OTHER";
}
throw std::invalid_argument("Unknown AnnotationTypeId");
}
std::string to_string(cmSpdxArtifact::SupportTypeId id)
{
switch (id) {
case cmSpdxArtifact::SupportTypeId::COMMUNITY:
return "COMMUNITY";
case cmSpdxArtifact::SupportTypeId::COMMERCIAL:
return "COMMERCIAL";
case cmSpdxArtifact::SupportTypeId::NONE:
return "NONE";
}
throw std::invalid_argument("Unknown SupportTypeId");
}
void cmSpdxExternalIdentifier::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "ExternalIdentifier");
SerializeIfPresent(serializer, "externalIdentifierType",
ExternalIdentifierType);
SerializeIfPresent(serializer, "identifier", Identifier);
SerializeIfPresent(serializer, "comment", Comment);
SerializeIfPresent(serializer, "identifierLocation", IdentifierLocation);
SerializeIfPresent(serializer, "issuingAuthority", IssuingAuthority);
}
void cmSpdxExternalRef::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "ExternalRef");
SerializeIfPresent(serializer, "externalRefType", ExternalRefType);
SerializeIfPresent(serializer, "locator", Locator);
SerializeIfPresent(serializer, "contentType", ContentType);
SerializeIfPresent(serializer, "comment", Comment);
}
void cmSpdxChecksum::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "Checksum");
serializer.AddString("algorithm", to_string(Algorithm));
serializer.AddString("checksumValue", ChecksumValue);
}
void cmSpdxCreationInfo::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "CreationInfo");
SerializeIfPresent(serializer, "@id", SpdxId);
if (SpecVersion) {
serializer.AddString("specVersion", *SpecVersion);
}
SerializeIfPresent(serializer, "comment", Comment);
SerializeIfPresent(serializer, "created", Created);
if (!CreatedBy.empty()) {
serializer.AddVectorIfPresent("createdBy", CreatedBy);
}
if (!CreatedUsing.empty()) {
serializer.AddVectorIfPresent("createdUsing", CreatedUsing);
}
}
void cmSpdxIntegrityMethod::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "IntegrityMethod");
SerializeIfPresent(serializer, "comment", Comment);
}
void cmSpdxElement::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "Element");
SerializeIfPresent(serializer, "@id", SpdxId);
SerializeIfPresent(serializer, "name", Name);
SerializeIfPresent(serializer, "summary", Summary);
SerializeIfPresent(serializer, "description", Description);
SerializeIfPresent(serializer, "comment", Comment);
if (CreationInfo) {
serializer.AddVisitable("creationInfo", *CreationInfo);
}
if (VerifiedUsing) {
serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
}
if (!ExternalRef.empty()) {
serializer.AddVectorIfPresent("externalRef", ExternalRef);
}
if (!ExternalIdentifier.empty()) {
serializer.AddVectorIfPresent("externalIdentifier", ExternalIdentifier);
}
if (Extension) {
serializer.AddVisitable("extension", *Extension);
}
}
void cmSpdxTool::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "Tool");
}
void cmSpdxAgent::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "Agent");
}
void cmSpdxOrganization::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxAgent::Serialize(serializer);
serializer.AddString("type", "Organization");
}
void cmSpdxPerson::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxAgent::Serialize(serializer);
serializer.AddString("type", "Person");
}
void cmSpdxSoftwareAgent::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxAgent::Serialize(serializer);
serializer.AddString("type", "SoftwareAgent");
}
void cmSpdxPositiveIntegerRange::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "PositiveIntegerRange");
SerializeIfPresent(serializer, "beginIntegerRange", BeginIntegerRange);
SerializeIfPresent(serializer, "endIntegerRange", EndIntegerRange);
}
void cmSpdxRelationship::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "Relationship");
if (From) {
serializer.AddVisitable("from", *From);
}
if (!To.empty()) {
serializer.AddVectorIfPresent("to", To);
}
if (RelationshipType) {
serializer.AddString("relationshipType", to_string(*RelationshipType));
}
SerializeIfPresent(serializer, "startTime", StartTime);
SerializeIfPresent(serializer, "endTime", EndTime);
}
void cmSpdxLifecycleScopedRelationship::Serialize(
cmSbomSerializer& serializer) const
{
cmSpdxRelationship::Serialize(serializer);
serializer.AddString("type", "LifecycleScopedRelationship");
if (Scope) {
serializer.AddString("scope", to_string(*Scope));
}
}
void cmSpdxArtifact::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "Artifact");
if (!OriginatedBy.empty()) {
serializer.AddVectorIfPresent("originatedBy", OriginatedBy);
}
if (SuppliedBy) {
serializer.AddVisitable("suppliedBy", *SuppliedBy);
}
SerializeIfPresent(serializer, "builtTime", BuiltTime);
SerializeIfPresent(serializer, "releaseTime", ReleaseTime);
SerializeIfPresent(serializer, "validUntilTime", ValidUntilTime);
SerializeIfPresent(serializer, "standardName", StandardName);
if (Support) {
serializer.AddString("support", to_string(*Support));
}
}
void cmSpdxIndividualElement::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "IndividualElement");
}
void cmSpdxAnnotation::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "Annotation");
if (AnnotationType) {
serializer.AddString("annotationType", to_string(*AnnotationType));
}
SerializeIfPresent(serializer, "contentType", ContentType);
SerializeIfPresent(serializer, "statement", Statement);
if (Element) {
serializer.AddVisitable("element", *Element);
}
}
void cmSpdxExternalMap::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "ExternalMap");
SerializeIfPresent(serializer, "externalSpdxId", ExternalSpdxId);
if (VerifiedUsing) {
serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
}
SerializeIfPresent(serializer, "locationHistory", LocationHistory);
if (DefiningArtifact) {
serializer.AddVisitable("definingArtifact", *DefiningArtifact);
}
}
void cmSpdxNamespaceMap::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "NamespaceMap");
SerializeIfPresent(serializer, "prefix", Prefix);
SerializeIfPresent(serializer, "namespace", Namespace);
}
void cmSpdxElementCollection::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElement::Serialize(serializer);
serializer.AddString("type", "ElementCollection");
if (!Elements.empty()) {
serializer.AddVectorIfPresent("element", Elements);
}
if (!RootElements.empty()) {
serializer.AddVectorIfPresent("rootElement", RootElements);
}
if (!ProfileConformance.empty()) {
serializer.AddVectorIfPresent("profileConformance", ProfileConformance);
}
}
void cmSpdxPackageVerificationCode::Serialize(
cmSbomSerializer& serializer) const
{
serializer.AddString("type", "PackageVerificationCode");
if (Algorithm) {
serializer.AddString("algorithm", to_string(*Algorithm));
}
SerializeIfPresent(serializer, "hashValue", HashValue);
SerializeIfPresent(serializer, "packageVerificationCodeExcludedFile",
PackageVerificationCodeExcludedFile);
}
void cmSpdxHash::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString("type", "Hash");
serializer.AddString("hashAlgorithm", to_string(HashAlgorithm));
serializer.AddString("hashValue", HashValue);
}
void cmSpdxBundle::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElementCollection::Serialize(serializer);
serializer.AddString("type", "Bundle");
SerializeIfPresent(serializer, "context", Context);
}
void cmSpdxBom::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxBundle::Serialize(serializer);
serializer.AddString("type", "Bom");
}
void cmSpdxSbom::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxBom::Serialize(serializer);
serializer.AddString("type", "software_Sbom");
if (Types) {
for (auto const& t : *Types) {
serializer.AddString("sbomType", to_string(t));
}
}
if (LifecycleScope) {
serializer.AddString("lifecycleScope", to_string(*LifecycleScope));
}
}
void cmSpdxSoftwareArtifact::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxArtifact::Serialize(serializer);
serializer.AddString("type", "software_SoftwareArtifact");
if (PrimaryPurpose) {
serializer.AddString("primaryPurpose", to_string(*PrimaryPurpose));
}
if (AdditionalPurpose) {
for (auto const& p : *AdditionalPurpose) {
serializer.AddString("additionalPurpose", to_string(p));
}
}
SerializeIfPresent(serializer, "copyrightText", CopyrightText);
SerializeIfPresent(serializer, "attributionText", AttributionText);
if (ContentIdentifier) {
serializer.AddVisitable("contentIdentifier", *ContentIdentifier);
}
SerializeIfPresent(serializer, "artifactSize", ArtifactSize);
}
void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxSoftwareArtifact::Serialize(serializer);
serializer.AddString("type", "software_Package");
SerializeIfPresent(serializer, "downloadLocation", DownloadLocation);
SerializeIfPresent(serializer, "homePage", Homepage);
SerializeIfPresent(serializer, "packageVersion", PackageVersion);
SerializeIfPresent(serializer, "packageUrl", PackageUrl);
SerializeIfPresent(serializer, "sourceInfo", SourceInfo);
}
void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxArtifact::Serialize(serializer);
serializer.AddString("type", "software_File");
if (ContentType) {
serializer.AddString("contentType", *ContentType);
}
if (FileType) {
serializer.AddString("fileType", to_string(*FileType));
}
}
void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxIntegrityMethod::Serialize(serializer);
serializer.AddString("type", "software_ContentIdentifier");
SerializeIfPresent(serializer, "contentIdentifierType",
ContentIdentifierType);
SerializeIfPresent(serializer, "contentValue", ContentValue);
}
void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxSoftwareArtifact::Serialize(serializer);
serializer.AddString("type", "software_Snippet");
SerializeIfPresent(serializer, "byteRange", ByteRange);
SerializeIfPresent(serializer, "lineRange", LineRange);
if (SnippetFromFile) {
serializer.AddVisitable("snippetFromFile", *SnippetFromFile);
}
}
void cmSpdxDocument::Serialize(cmSbomSerializer& serializer) const
{
cmSpdxElementCollection::Serialize(serializer);
serializer.AddString("type", "SpdxDocument");
if (ExternalMap) {
serializer.AddVisitable("externalMap", *ExternalMap);
}
if (NamespaceMap) {
serializer.AddVisitable("namespaceMap", *NamespaceMap);
}
SerializeIfPresent(serializer, "dataLicense", DataLicense);
}
void cmSbomDocument::Serialize(cmSbomSerializer& serializer) const
{
serializer.AddString(
"@context",
Context.value_or("https://spdx.org/rdf/3.0.1/spdx-context.jsonld"));
if (!Graph.empty()) {
serializer.AddVectorIfPresent("@graph", Graph);
}
}
+390
View File
@@ -0,0 +1,390 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <string>
#include <vector>
#include <cm/optional>
#include "cmSbomObject.h"
class cmSbomSerializer;
using Datetime = std::string;
using MediaType = std::string;
using SemVer = std::string;
struct cmSpdxExternalIdentifier
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> ExternalIdentifierType;
cm::optional<std::string> Identifier;
cm::optional<std::string> Comment;
cm::optional<std::string> IdentifierLocation;
cm::optional<std::string> IssuingAuthority;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxExternalRef
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> ExternalRefType;
cm::optional<std::string> Locator;
cm::optional<std::string> ContentType;
cm::optional<std::string> Comment;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxCreationInfo
{
cm::optional<std::string> SpdxId;
cm::optional<SemVer> SpecVersion;
cm::optional<std::string> Comment;
cm::optional<Datetime> Created;
std::vector<cmSbomObject> CreatedBy;
std::vector<cmSbomObject> CreatedUsing;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxIntegrityMethod
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> Comment;
enum HashAlgorithmId
{
ADLER32,
BLAKE2B256,
BLAKE2B384,
BLAKE2B512,
BLAKE3,
MD2,
MD4,
MD5,
MD6,
SHA1,
SHA224,
SHA256,
SHA384,
SHA512,
SHA3_256,
SHA3_384,
SHA3_512,
};
cmSpdxIntegrityMethod() = default;
cmSpdxIntegrityMethod(cmSpdxIntegrityMethod const&) = default;
cmSpdxIntegrityMethod(cmSpdxIntegrityMethod&&) = default;
cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod const&) = default;
cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod&&) = default;
virtual void Serialize(cmSbomSerializer&) const;
virtual ~cmSpdxIntegrityMethod() = default;
};
struct cmSpdxChecksum
{
cm::optional<std::string> SpdxId;
cmSpdxIntegrityMethod::HashAlgorithmId Algorithm;
std::string ChecksumValue;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxElement
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> Name;
cm::optional<std::string> Summary;
cm::optional<std::string> Description;
cm::optional<std::string> Comment;
cm::optional<cmSbomObject> CreationInfo;
cm::optional<cmSbomObject> VerifiedUsing;
std::vector<cmSbomObject> ExternalRef;
std::vector<cmSbomObject> ExternalIdentifier;
cm::optional<cmSbomObject> Extension;
cmSpdxElement() = default;
cmSpdxElement(cmSpdxElement const&) = default;
cmSpdxElement(cmSpdxElement&&) = default;
cmSpdxElement& operator=(cmSpdxElement const&) = default;
cmSpdxElement& operator=(cmSpdxElement&&) = default;
virtual ~cmSpdxElement() = default;
virtual void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxTool final : cmSpdxElement
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxAgent : cmSpdxElement
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxOrganization final : cmSpdxAgent
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxPerson final : cmSpdxAgent
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxSoftwareAgent final : cmSpdxAgent
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxPositiveIntegerRange
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> BeginIntegerRange;
cm::optional<std::string> EndIntegerRange;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxRelationship : cmSpdxElement
{
enum RelationshipTypeId
{
DESCRIBES,
CONTAINS,
DEPENDS_ON,
OTHER
};
cm::optional<cmSbomObject> From;
std::vector<cmSbomObject> To;
cm::optional<RelationshipTypeId> RelationshipType;
cm::optional<Datetime> StartTime;
cm::optional<Datetime> EndTime;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxLifecycleScopedRelationship final : cmSpdxRelationship
{
enum ScopeId
{
BUILD,
DESIGN,
RUNTIME,
TEST
};
cm::optional<ScopeId> Scope;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxArtifact : cmSpdxElement
{
enum SupportTypeId
{
COMMUNITY,
COMMERCIAL,
NONE
};
std::vector<cmSbomObject> OriginatedBy;
cm::optional<cmSbomObject> SuppliedBy;
cm::optional<Datetime> BuiltTime;
cm::optional<Datetime> ReleaseTime;
cm::optional<Datetime> ValidUntilTime;
cm::optional<std::string> StandardName;
cm::optional<SupportTypeId> Support;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxIndividualElement final : cmSpdxElement
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxAnnotation final : cmSpdxElement
{
enum AnnotationTypeId
{
REVIEW,
OTHER
};
cm::optional<AnnotationTypeId> AnnotationType;
cm::optional<MediaType> ContentType;
cm::optional<std::string> Statement;
cm::optional<cmSbomObject> Element;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxExternalMap
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> ExternalSpdxId;
cm::optional<cmSbomObject> VerifiedUsing;
cm::optional<std::string> LocationHistory;
cm::optional<cmSbomObject> DefiningArtifact;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxNamespaceMap
{
cm::optional<std::string> SpdxId;
cm::optional<std::string> Prefix;
cm::optional<std::string> Namespace;
void Serialize(cmSbomSerializer&) const;
};
struct cmSpdxElementCollection : cmSpdxElement
{
std::vector<cmSbomObject> Elements;
std::vector<cmSbomObject> RootElements;
std::vector<std::string> ProfileConformance;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxPackageVerificationCode final : cmSpdxIntegrityMethod
{
cm::optional<HashAlgorithmId> Algorithm;
cm::optional<std::string> HashValue;
cm::optional<std::string> PackageVerificationCodeExcludedFile;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxHash final : cmSpdxIntegrityMethod
{
HashAlgorithmId HashAlgorithm;
std::string HashValue;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxBundle : cmSpdxElementCollection
{
cm::optional<std::string> Context;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxBom : cmSpdxBundle
{
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxSbom final : cmSpdxBom
{
enum TypeId
{
ANALYZED,
BUILD,
DEPLOYED,
DESIGN,
RUNTIME,
SOURCE,
TEST
};
cm::optional<std::vector<TypeId>> Types;
cm::optional<TypeId> LifecycleScope;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxSoftwareArtifact : cmSpdxArtifact
{
enum PurposeId
{
APPLICATION,
ARCHIVE,
CONTAINER,
DATA,
DEVICE,
FIRMWARE,
FILE,
INSTALL,
LIBRARY,
MODULE,
OPERATING_SYSTEM,
SOURCE
};
cm::optional<PurposeId> PrimaryPurpose;
cm::optional<std::vector<PurposeId>> AdditionalPurpose;
cm::optional<std::string> CopyrightText;
cm::optional<std::string> AttributionText;
cm::optional<cmSbomObject> ContentIdentifier;
cm::optional<std::string> ArtifactSize;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxPackage final : cmSpdxSoftwareArtifact
{
cm::optional<std::string> DownloadLocation;
cm::optional<std::string> Homepage;
cm::optional<std::string> PackageVersion;
cm::optional<std::string> PackageUrl;
cm::optional<std::string> SourceInfo;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxDocument final : cmSpdxElementCollection
{
cm::optional<cmSbomObject> ExternalMap;
cm::optional<cmSbomObject> NamespaceMap;
std::string DataLicense;
void Serialize(cmSbomSerializer& serializer) const override;
};
struct cmSpdxContentIdentifier final : cmSpdxIntegrityMethod
{
cm::optional<std::string> ContentIdentifierType;
cm::optional<std::string> ContentValue;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxFile final : cmSpdxArtifact
{
enum FileKindId
{
DIRECTORY,
FILE
};
cm::optional<MediaType> ContentType;
cm::optional<FileKindId> FileType;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSpdxSnippet final : cmSpdxSoftwareArtifact
{
cm::optional<std::string> ByteRange;
cm::optional<std::string> LineRange;
cm::optional<cmSbomObject> SnippetFromFile;
void Serialize(cmSbomSerializer&) const override;
};
struct cmSbomDocument
{
cm::optional<std::string> Context;
std::vector<cmSbomObject> Graph;
void Serialize(cmSbomSerializer&) const;
};
+119
View File
@@ -0,0 +1,119 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmSpdxSerializer.h"
#include <utility>
#include <cm3p/json/writer.h>
#include "cmSbomObject.h"
cmSpdxSerializer::cmSpdxSerializer()
{
Json::StreamWriterBuilder builder = Json::StreamWriterBuilder();
builder["indentation"] = " ";
Writer.reset(builder.newStreamWriter());
}
void cmSpdxSerializer::BeginObject()
{
CurrentValue = Json::objectValue;
}
void cmSpdxSerializer::BeginArray()
{
CurrentValue = Json::arrayValue;
}
void cmSpdxSerializer::EndObject()
{
}
void cmSpdxSerializer::EndArray()
{
}
void cmSpdxSerializer::AddReference(std::string const& id)
{
CurrentValue = id;
}
void cmSpdxSerializer::AddString(std::string const& key,
std::string const& value)
{
if (!value.empty()) {
CurrentValue[key] = value;
}
}
void cmSpdxSerializer::AddVisitable(std::string const& key,
cmSbomObject const& visitable)
{
if (visitable.IsNull()) {
return;
}
Json::Value parentValue = std::move(CurrentValue);
visitable.Serialize(*this);
Json::Value childValue = std::move(CurrentValue);
CurrentValue = std::move(parentValue);
CurrentValue[key] = std::move(childValue);
}
void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
std::vector<cmSbomObject> const& vec)
{
if (vec.empty()) {
return;
}
Json::Value parentValue = std::move(CurrentValue);
Json::Value childValue(Json::arrayValue);
for (auto const& item : vec) {
if (item.IsNull()) {
continue;
}
item.Serialize(*this);
if (!CurrentValue.isNull()) {
childValue.append(std::move(CurrentValue));
}
}
CurrentValue = std::move(parentValue);
CurrentValue[key] = std::move(childValue);
}
void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
std::vector<std::string> const& vec)
{
if (vec.empty()) {
return;
}
Json::Value parentValue = std::move(CurrentValue);
Json::Value childValue(Json::arrayValue);
for (auto const& item : vec) {
if (item.empty()) {
continue;
}
childValue.append(item);
}
CurrentValue = std::move(parentValue);
CurrentValue[key] = std::move(childValue);
}
bool cmSpdxSerializer::WriteSbom(std::ostream& os,
cmSbomObject const& document)
{
if (document.IsNull()) {
return false;
}
document.Serialize(*this);
Writer->write(CurrentValue, &os);
return os.good();
}
+52
View File
@@ -0,0 +1,52 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
#include "cmSbomSerializer.h"
class cmSbomObject;
struct cmSpdxSerializer final : cmSbomSerializer
{
cmSpdxSerializer();
~cmSpdxSerializer() override = default;
void BeginObject() override;
void BeginArray() override;
void EndObject() override;
void EndArray() override;
void AddReference(std::string const& id) override;
void AddString(std::string const& key, std::string const& value) override;
void AddVisitable(std::string const& key,
cmSbomObject const& visitable) override;
void AddVectorIfPresent(std::string const& key,
std::vector<cmSbomObject> const& vec) override;
void AddVectorIfPresent(std::string const& key,
std::vector<std::string> const& vec) override;
bool WriteSbom(std::ostream& os, cmSbomObject const& document) override;
Json::Value GetJson() { return CurrentValue; }
private:
Json::Value CurrentValue;
std::string CurrentKey;
std::unique_ptr<Json::StreamWriter> Writer;
};
+1 -1
View File
@@ -25,7 +25,7 @@ set(CMakeLib_TESTS
testRange.cxx
testOptional.cxx
testPathResolver.cxx
testSPDXSerializer.cxx
testSpdxSerializer.cxx
testStdIo.cxx
testString.cxx
testStringAlgorithms.cxx
-649
View File
@@ -1,649 +0,0 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include <iostream>
#include <string>
#include <vector>
#include <cm/optional>
#include <cm/type_traits>
#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
#include "cmSPDXSerializer.h"
namespace {
std::string const nonOptional(R"================({
"@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
"@graph": [
{
"@id": "_:contentIdentifier_0",
"contentIdentifierType": "INVALID_CONTENT_IDENTIFIER_TYPE_ID",
"contentIdentifierValue": "",
"type": "ContentIdentifier"
},
{
"@id": "_:creationInfo_0",
"created": "",
"createdBy": [],
"type": "CreationInfo"
},
{
"@id": "_:creationInfo_1",
"created": "",
"createdBy": [],
"type": "CreationInfo"
},
{
"@id": "_:dictionaryEntry_0",
"key": "",
"type": "DictionaryEntry"
},
{
"@id": "_:externalIdentifier_0",
"externalIdentifierType": "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID",
"identifier": "",
"type": "ExternalIdentifier"
},
{
"@id": "_:externalMap_0",
"externalSpdxId": "",
"type": "ExternalMap"
},
{
"@id": "_:externalRef_0",
"type": "ExternalRef"
},
{
"@id": "_:hash_0",
"algorithm": "INVALID_HASH_TYPE_ID",
"hashValue": "",
"type": "Hash"
},
{
"@id": "_:namespaceMap_0",
"namespace": "",
"prefix": "",
"type": "NamespaceMap"
},
{
"@id": "_:packageVerificationCode_0",
"algorithm": "INVALID_HASH_TYPE_ID",
"hashValue": "",
"type": "PackageVerificationCode"
},
{
"@id": "_:positiveIntegerRange_0",
"beginIntegerRange": 0,
"endIntegerRange": 0,
"type": "PositiveIntegerRange"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
"type": "Agent"
},
{
"annotationType": "INVALID_ANNOTATION_TYPE_ID",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
"subject": "",
"type": "Annotation"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
"type": "SpdxDocument"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
"type": "Tool"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
"type": "File"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
"type": "Package"
},
{
"context": "",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
"type": "Sbom"
},
{
"creationInfo": "_:creationInfo_0",
"snippetFromFile": "",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
"type": "Snippet"
},
{
"creationInfo": "_:creationInfo_0",
"licenseExpression": "",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
"type": "LicenseExpression"
},
{
"creationInfo": "_:creationInfo_0",
"licenseText": "",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
"type": "SimpleLicensingText"
},
{
"context": "",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
"type": "Bom"
},
{
"context": "",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
"type": "Bundle"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
"type": "IndividualElement"
},
{
"creationInfo": "_:creationInfo_0",
"from": "",
"relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
"to": [],
"type": "LifecycleScopedRelationship"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
"type": "Organization"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
"type": "Person"
},
{
"creationInfo": "_:creationInfo_0",
"from": "",
"relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
"to": [],
"type": "Relationship"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
"type": "SoftwareAgent"
}
]
})================");
std::string const Optional(R"================({
"@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
"@graph": [
{
"@id": "_:contentIdentifier_0",
"contentIdentifierType": "gitoid",
"contentIdentifierValue": "ContentIdentifierValue",
"type": "ContentIdentifier"
},
{
"@id": "_:creationInfo_0",
"created": "",
"createdBy": [],
"type": "CreationInfo"
},
{
"@id": "_:creationInfo_1",
"Comment": "Comment",
"created": "Created",
"createdBy": [
"testRef"
],
"createdUsing": [
"testRef"
],
"type": "CreationInfo"
},
{
"@id": "_:dictionaryEntry_0",
"key": "Key",
"type": "DictionaryEntry",
"value": "Value"
},
{
"@id": "_:externalIdentifier_0",
"comment": "Comment",
"externalIdentifierType": "other",
"identifier": "Identifier",
"identifierLocator": [
"IdentifierLocator"
],
"issuingAuthority": "IssuingAuthority",
"type": "ExternalIdentifier"
},
{
"@id": "_:externalMap_0",
"definingArtifact": "testRef",
"externalSpdxId": "ExternalSpdxId",
"integrityMethod": [
"testRef"
],
"locationHint": "LocationHint",
"type": "ExternalMap"
},
{
"@id": "_:externalRef_0",
"comment": "Comment",
"contentType": "ContentType",
"externalRefType": "other",
"locator": [
"Locator"
],
"type": "ExternalRef"
},
{
"@id": "_:hash_0",
"algorithm": "other",
"hashValue": "HashValue",
"type": "Hash"
},
{
"@id": "_:namespaceMap_0",
"namespace": "Namespace",
"prefix": "Namespace",
"type": "NamespaceMap"
},
{
"@id": "_:packageVerificationCode_0",
"algorithm": "other",
"hashValue": "HashValue",
"type": "PackageVerificationCode"
},
{
"@id": "_:positiveIntegerRange_0",
"beginIntegerRange": 1,
"endIntegerRange": 2,
"type": "PositiveIntegerRange"
},
{
"comment": "Comment",
"creationInfo": "_:creationInfo_0",
"description": "Description",
"extension": [
"testRef"
],
"externalIdentifier": [
"testRef"
],
"externalRef": [
"testRef"
],
"name": "Name",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
"summary": "Summary",
"type": "Agent",
"verifiedUsing": [
"testRef"
]
},
{
"annotationType": "other",
"contentType": "ContentType",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
"statement": "Statement",
"subject": "testRef",
"type": "Annotation"
},
{
"creationInfo": "_:creationInfo_0",
"dataLicense": "testRef",
"externalMap": "testRef",
"namespaceMap": "testRef",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
"type": "SpdxDocument"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
"type": "Tool"
},
{
"additionalPurpose": [
"other"
],
"attributionText": "AttributionText",
"contentIdentifier": "testRef",
"contentType": "ContentType",
"copyrightText": "CopyrightText",
"creationInfo": "_:creationInfo_0",
"fileKind": "file",
"primaryPurpose": "file",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
"type": "File"
},
{
"creationInfo": "_:creationInfo_0",
"downloadLocation": "DownloadLocation",
"homePage": "HomePage",
"packageUrl": "PackageUrl",
"packageVersion": "PackageVersion",
"sourceInfo": "SourceInfo",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
"type": "Package"
},
{
"context": "",
"creationInfo": "_:creationInfo_0",
"sbomType": [
"build"
],
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
"type": "Sbom"
},
{
"byteRange": "testRef",
"creationInfo": "_:creationInfo_0",
"lineRange": "testRef",
"snippetFromFile": "testRef",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
"type": "Snippet"
},
{
"creationInfo": "_:creationInfo_0",
"customIdToUri": [
"testRef"
],
"licenseExpression": "LicenseExpression",
"licenseListVersion": "LicenseListVersion",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
"type": "LicenseExpression"
},
{
"creationInfo": "_:creationInfo_0",
"licenseText": "LicenseText",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
"type": "SimpleLicensingText"
},
{
"context": "Context",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
"type": "Bom"
},
{
"context": "",
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
"type": "Bundle"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
"type": "IndividualElement"
},
{
"completeness": "noAssertion",
"creationInfo": "_:creationInfo_0",
"endTime": "EndTime",
"from": "testRef",
"relationshipType": "other",
"scope": "other",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
"startTime": "StartTime",
"to": [
"testRef"
],
"type": "LifecycleScopedRelationship"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
"type": "Organization"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
"type": "Person"
},
{
"creationInfo": "_:creationInfo_0",
"from": "",
"relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
"to": [],
"type": "Relationship"
},
{
"creationInfo": "_:creationInfo_0",
"spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
"type": "SoftwareAgent"
}
]
})================");
}
int testNonOptional()
{
cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
// Core
graph.insert<cmSPDXAgent>();
graph.insert<cmSPDXAnnotation>();
graph.insert<cmSPDXBom>();
graph.insert<cmSPDXBundle>();
graph.insert<cmSPDXCreationInfo>();
graph.insert<cmSPDXDictionaryEntry>();
graph.insert<cmSPDXExternalIdentifier>();
graph.insert<cmSPDXExternalMap>();
graph.insert<cmSPDXExternalRef>();
graph.insert<cmSPDXHash>();
graph.insert<cmSPDXIndividualElement>();
graph.insert<cmSPDXLifecycleScopedRelationship>();
graph.insert<cmSPDXNamespaceMap>();
graph.insert<cmSPDXOrganization>();
graph.insert<cmSPDXPackageVerificationCode>();
graph.insert<cmSPDXPerson>();
graph.insert<cmSPDXPositiveIntegerRange>();
graph.insert<cmSPDXRelationship>();
graph.insert<cmSPDXSoftwareAgent>();
graph.insert<cmSPDXSpdxDocument>();
graph.insert<cmSPDXTool>();
// Software
graph.insert<cmSPDXContentIdentifier>();
graph.insert<cmSPDXFile>();
graph.insert<cmSPDXPackage>();
graph.insert<cmSPDXSbom>();
graph.insert<cmSPDXSnippet>();
// SimpleLicensing
graph.insert<cmSPDXLicenseExpression>();
graph.insert<cmSPDXSimpleLicensingText>();
Json::Value root;
Json::Reader().parse(nonOptional.c_str(), root);
std::cout << "NonOptional SPDX:";
std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
// Convert to string to disregard differences in number signedness
return root.toStyledString() == graph.toJsonLD().toStyledString();
};
int testOptional()
{
cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
cmSPDXIdentifierReference ident("testRef");
// Core
auto& agent = graph.insert<cmSPDXAgent>();
agent.Comment = "Comment";
agent.Description = "Description";
agent.Extension.emplace().push_back(ident);
agent.ExternalIdentifier.emplace().push_back(ident);
agent.ExternalRef.emplace().push_back(ident);
agent.Name = "Name";
agent.Summary = "Summary";
agent.VerifiedUsing.emplace().push_back(ident);
auto& annotation = graph.insert<cmSPDXAnnotation>();
annotation.AnnotationType = cmSPDXAnnotationType::OTHER;
annotation.ContentType = "ContentType";
annotation.Statement = "Statement";
annotation.Subject = ident;
auto& bom = graph.insert<cmSPDXBom>();
bom.Context = "Context";
graph.insert<cmSPDXBundle>();
auto& creationInfo = graph.insert<cmSPDXCreationInfo>();
creationInfo.Comment = "Comment";
creationInfo.Created = "Created";
creationInfo.CreatedBy.push_back(ident);
creationInfo.CreatedUsing.emplace().push_back(ident);
auto& dictionaryEntry = graph.insert<cmSPDXDictionaryEntry>();
dictionaryEntry.Key = "Key";
dictionaryEntry.Value = "Value";
auto& externalIdentifier = graph.insert<cmSPDXExternalIdentifier>();
externalIdentifier.Comment = "Comment";
externalIdentifier.ExternalIdentifierType =
cmSPDXExternalIdentifierType::OTHER;
externalIdentifier.Identifier = "Identifier";
externalIdentifier.IdentifierLocator.emplace().push_back(
"IdentifierLocator");
externalIdentifier.IssuingAuthority = "IssuingAuthority";
auto& externalMap = graph.insert<cmSPDXExternalMap>();
externalMap.DefiningArtifact = ident;
externalMap.ExternalSpdxId = "ExternalSpdxId";
externalMap.LocationHint = "LocationHint";
externalMap.IntegrityMethod.emplace().push_back(ident);
auto& externalRef = graph.insert<cmSPDXExternalRef>();
externalRef.Comment = "Comment";
externalRef.ContentType = "ContentType";
externalRef.ExternalRefType = cmSPDXExternalRefType::OTHER;
externalRef.Locator.emplace().push_back("Locator");
auto& hash = graph.insert<cmSPDXHash>();
hash.Algorithm = cmSPDXHashAlgorithm::OTHER;
hash.HashValue = "HashValue";
graph.insert<cmSPDXIndividualElement>();
auto& lifecycleScopedRelationship =
graph.insert<cmSPDXLifecycleScopedRelationship>();
lifecycleScopedRelationship.Completeness =
cmSPDXRelationshipCompletenessType::NO_ASSERTION;
lifecycleScopedRelationship.EndTime = "EndTime";
lifecycleScopedRelationship.From = ident;
lifecycleScopedRelationship.RelationshipType = cmSPDXRelationshipType::OTHER;
lifecycleScopedRelationship.StartTime = "StartTime";
lifecycleScopedRelationship.To.push_back(ident);
lifecycleScopedRelationship.Scope = cmSPDXLifecycleScopeType::OTHER;
auto& namespaceMap = graph.insert<cmSPDXNamespaceMap>();
namespaceMap.Namespace = "Namespace";
namespaceMap.Prefix = "Prefix";
graph.insert<cmSPDXOrganization>();
auto& packageVerificationCode =
graph.insert<cmSPDXPackageVerificationCode>();
packageVerificationCode.Algorithm = cmSPDXHashAlgorithm::OTHER;
packageVerificationCode.HashValue = "HashValue";
packageVerificationCode.PackageVerificationCodeExcludedFile.emplace()
.push_back("PacakgeVerificationCodeExcludeFile");
graph.insert<cmSPDXPerson>();
auto& positiveIntegerRange = graph.insert<cmSPDXPositiveIntegerRange>();
positiveIntegerRange.BeginIntegerRange = 1;
positiveIntegerRange.EndIntegerRange = 2;
graph.insert<cmSPDXRelationship>();
graph.insert<cmSPDXSoftwareAgent>();
auto& spdxDocument = graph.insert<cmSPDXSpdxDocument>();
spdxDocument.DataLicense = ident;
spdxDocument.ExternalMap = ident;
spdxDocument.NamespaceMap = ident;
graph.insert<cmSPDXTool>();
// Software
auto& contentIdentifier = graph.insert<cmSPDXContentIdentifier>();
contentIdentifier.ContentIdentifierType =
cmSPDXContentIdentifierType::GITOID;
contentIdentifier.ContentIdentifierValue = "ContentIdentifierValue";
auto& file = graph.insert<cmSPDXFile>();
file.AdditionalPurpose.emplace().push_back(cmSPDXSoftwarePurpose::OTHER);
file.AttributionText = "AttributionText";
file.ContentIdentifier = ident;
file.CopyrightText = "CopyrightText";
file.PrimaryPurpose = cmSPDXSoftwarePurpose::FILE;
file.ContentType = "ContentType";
file.FileKind = cmSPDXFileKindType::FILE;
auto& package = graph.insert<cmSPDXPackage>();
package.DownloadLocation = "DownloadLocation";
package.HomePage = "HomePage";
package.PackageUrl = "PackageUrl";
package.PackageVersion = "PackageVersion";
package.SourceInfo = "SourceInfo";
auto& sbom = graph.insert<cmSPDXSbom>();
sbom.SbomType.emplace().push_back(cmSPDXSbomType::BUILD);
auto& snippet = graph.insert<cmSPDXSnippet>();
snippet.ByteRange = ident;
snippet.LineRange = ident;
snippet.SnippetFromFile = ident;
// SimpleLicensing
auto& licenseExpression = graph.insert<cmSPDXLicenseExpression>();
licenseExpression.CustomIdToUri.emplace().push_back(ident);
licenseExpression.LicenseExpression = "LicenseExpression";
licenseExpression.LicenseListVersion = "LicenseListVersion";
auto& simpleLicensingText = graph.insert<cmSPDXSimpleLicensingText>();
simpleLicensingText.LicenseText = "LicenseText";
Json::Value root;
Json::Reader().parse(Optional.c_str(), root);
std::cout << "Optional SPDX:";
std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
// Convert to string to disregard differences in number signedness
return root.toStyledString() == graph.toJsonLD().toStyledString();
};
int testSPDXSerializer(int /* argc */, char* /* argv */[])
{
if (!testNonOptional())
return -1;
if (!testOptional())
return -1;
return 0;
}
+84
View File
@@ -0,0 +1,84 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include <string>
#include <utility>
#include <vector>
#include <cm/optional>
#include <cm3p/json/value.h>
#include "cmSbomObject.h"
#include "cmSpdx.h"
#include "cmSpdxSerializer.h"
#include "testCommon.h"
namespace {
bool testSerializeSpdxJson()
{
auto constexpr contextUrl = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
cmSbomDocument doc;
doc.Context = contextUrl;
cmSpdxDocument spdxValue;
spdxValue.SpdxId = "_:SPDXRef-Document";
spdxValue.DataLicense = "CC0-1.0";
auto spdx = insert_back(doc.Graph, std::move(spdxValue));
{
cmSpdxCreationInfo ci;
ci.SpdxId = "_:SPDXRef-CreationInfo";
ci.SpecVersion = "3.0.1";
spdx->CreationInfo = std::move(ci);
}
{
cmSpdxPackage pkg;
pkg.Name = "sample-package";
pkg.SpdxId = "_:SPDXRef-Package";
spdx->RootElements.emplace_back(std::move(pkg));
}
{
cmSpdxSerializer serializer;
doc.Serialize(serializer);
auto value = serializer.GetJson();
ASSERT_TRUE(value.isObject());
Json::Value const& context = value["@context"];
ASSERT_EQUAL(context.asString(), contextUrl);
Json::Value const& graph = value["@graph"];
ASSERT_TRUE(graph.isArray());
Json::Value const& docValue = graph[0];
ASSERT_TRUE(docValue.isObject());
ASSERT_EQUAL(docValue["type"].asString(), "SpdxDocument");
ASSERT_EQUAL(docValue["@id"].asString(), "_:SPDXRef-Document");
auto const& creationInfo = docValue["creationInfo"];
ASSERT_EQUAL(creationInfo["@id"].asString(), "_:SPDXRef-CreationInfo");
ASSERT_EQUAL(creationInfo["type"].asString(), "CreationInfo");
auto const& package = docValue["rootElement"][0];
ASSERT_EQUAL(package["type"].asString(), "software_Package");
ASSERT_EQUAL(package["@id"].asString(), "_:SPDXRef-Package");
}
return true;
}
} // namespace
int testSpdxSerializer(int /*unused*/, char* /*unused*/[])
{
return runTests({ testSerializeSpdxJson });
}
+21 -9
View File
@@ -11,27 +11,39 @@ namespace cm {
#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
// Miscellaneous transformations
template <bool B, typename T = void>
using enable_if_t = std::enable_if_t<B, T>;
using std::conditional_t;
using std::decay_t;
using std::remove_cv_t;
using std::remove_reference_t;
#else
// Miscellaneous transformations
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
#endif
template <bool B, typename T, typename F>
using conditional_t = typename std::conditional<B, T, F>::type;
template <typename T>
using decay_t = typename std::decay<T>::type;
template <typename T>
using remove_cv_t = typename std::remove_cv<T>::type;
template <typename T>
using remove_reference_t = typename std::remove_reference<T>::type;
#endif // C++14 (_t aliases)
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
// Helper classes
using std::bool_constant;
// Miscellaneous transformations
using std::invoke_result;
using std::invoke_result_t;
using std::void_t;
#else
@@ -44,7 +56,7 @@ using bool_constant = std::integral_constant<bool, B>;
template <typename F, typename... ArgTypes>
using invoke_result = std::result_of<F(ArgTypes...)>;
template <class F, typename... ArgTypes>
template <typename F, typename... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
template <typename... ArgTypes>
@@ -77,13 +89,13 @@ struct is_scoped_enum_helper<T, true>
!std::is_convertible<T, typename std::underlying_type<T>::type>::value>
{
};
}
} // namespace internals
template <typename T>
struct is_scoped_enum : public internals::is_scoped_enum_helper<T>
{
};
#endif
#endif // is_scoped_enum
} // namespace cm