From 05db3b79d8422acf2ad42799eed4800ce829e4d2 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 15:54:03 +0100 Subject: [PATCH 01/18] feat: `metadata.tools` support compoennts and services Signed-off-by: Jan Kowalleck --- src/_helpers/iterable.ts | 26 ++++++++++++++ src/models/metadata.ts | 6 ++-- src/models/tool.ts | 35 ++++++++++++++++++ src/models/vulnerability/vulnerability.ts | 6 ++-- src/serialize/json/normalize.ts | 28 +++++++++++++-- src/serialize/json/types.ts | 12 +++++-- src/serialize/xml/normalize.ts | 43 +++++++++++++++++++---- 7 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 src/_helpers/iterable.ts diff --git a/src/_helpers/iterable.ts b/src/_helpers/iterable.ts new file mode 100644 index 000000000..91bc1f384 --- /dev/null +++ b/src/_helpers/iterable.ts @@ -0,0 +1,26 @@ +/*! +This file is part of CycloneDX JavaScript Library. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +SPDX-License-Identifier: Apache-2.0 +Copyright (c) OWASP Foundation. All Rights Reserved. +*/ + +export function * chainI (...iterables: Array>): Generator { + for (const iterable of iterables) { + for (const item of iterable) { + yield item + } + } +} diff --git a/src/models/metadata.ts b/src/models/metadata.ts index df51729fe..ea2fa821b 100644 --- a/src/models/metadata.ts +++ b/src/models/metadata.ts @@ -23,7 +23,7 @@ import { LifecycleRepository } from './lifecycle' import { OrganizationalContactRepository } from './organizationalContact' import type { OrganizationalEntity } from './organizationalEntity' import { PropertyRepository } from './property' -import { ToolRepository } from './tool' +import { Tools } from './tool' export interface OptionalMetadataProperties { timestamp?: Metadata['timestamp'] @@ -40,7 +40,7 @@ export interface OptionalMetadataProperties { export class Metadata { timestamp?: Date lifecycles: LifecycleRepository - tools: ToolRepository + tools: Tools authors: OrganizationalContactRepository component?: Component manufacture?: OrganizationalEntity @@ -51,7 +51,7 @@ export class Metadata { constructor (op: OptionalMetadataProperties = {}) { this.timestamp = op.timestamp this.lifecycles = op.lifecycles ?? new LifecycleRepository() - this.tools = op.tools ?? new ToolRepository() + this.tools = op.tools ?? new Tools() this.authors = op.authors ?? new OrganizationalContactRepository() this.component = op.component this.manufacture = op.manufacture diff --git a/src/models/tool.ts b/src/models/tool.ts index f7397881e..1a4a95cdd 100644 --- a/src/models/tool.ts +++ b/src/models/tool.ts @@ -21,6 +21,7 @@ import type { Comparable } from '../_helpers/sortable' import { SortableComparables } from '../_helpers/sortable' import { ExternalReferenceRepository } from './externalReference' import { HashDictionary } from './hash' +import {type Component, ComponentRepository} from "./component"; export interface OptionalToolProperties { vendor?: Tool['vendor'] @@ -53,7 +54,41 @@ export class Tool implements Comparable { (this.version ?? '').localeCompare(other.version ?? '') /* eslint-enable @typescript-eslint/strict-boolean-expressions */ } + + static fromComponent(component: Component): Tool { + return new Tool({ + vendor: component.group, + name: component.name, + version: component.version, + hashes: component.hashes, + externalReferences: component.externalReferences + }) + } } export class ToolRepository extends SortableComparables { } + + +export interface OptionalToolsProperties { + components?: ComponentRepository + tools?: ToolRepository +} + +export class Tools { + components: ComponentRepository + // TODO: services + tools: ToolRepository + + constructor(op: OptionalToolsProperties = {}) { + this.components = op.components ?? new ComponentRepository() + // TODO: this.services + this.tools = op.tools ?? new ToolRepository() + } + + get size(): number { + return this.components.size + // TODO: this.services + + this.tools.size + } +} diff --git a/src/models/vulnerability/vulnerability.ts b/src/models/vulnerability/vulnerability.ts index e158dcaeb..a117d02f0 100644 --- a/src/models/vulnerability/vulnerability.ts +++ b/src/models/vulnerability/vulnerability.ts @@ -22,7 +22,7 @@ import { SortableComparables } from '../../_helpers/sortable' import { CweRepository } from '../../types/cwe' import { BomRef } from '../bomRef' import { PropertyRepository } from '../property' -import { ToolRepository } from '../tool' +import { Tools } from '../tool' import { AdvisoryRepository } from './advisory' import { AffectRepository } from './affect' import type { Analysis } from './analysis' @@ -68,7 +68,7 @@ export class Vulnerability implements Comparable { published?: Date updated?: Date credits?: Credits - tools: ToolRepository + tools: Tools analysis?: Analysis affects: AffectRepository properties: PropertyRepository @@ -88,7 +88,7 @@ export class Vulnerability implements Comparable { this.published = op.published this.updated = op.updated this.credits = op.credits - this.tools = op.tools ?? new ToolRepository() + this.tools = op.tools ?? new Tools() this.analysis = op.analysis this.affects = op.affects ?? new AffectRepository() this.properties = op.properties ?? new PropertyRepository() diff --git a/src/serialize/json/normalize.ts b/src/serialize/json/normalize.ts index 5ac87a783..3f8fcc992 100644 --- a/src/serialize/json/normalize.ts +++ b/src/serialize/json/normalize.ts @@ -23,6 +23,7 @@ import type { Stringable } from '../../_helpers/stringable' import { treeIteratorSymbol } from '../../_helpers/tree' import { escapeUri } from '../../_helpers/uri' import type * as Models from '../../models' +import { ToolRepository } from '../../models/tool' import { LicenseExpression, NamedLicense, SpdxLicense } from '../../models/license' import { NamedLifecycle } from '../../models/lifecycle' import { AffectedSingleVersion, AffectedVersionRange } from '../../models/vulnerability/affect' @@ -32,6 +33,8 @@ import { Version as SpecVersion } from '../../spec/enums' import type { NormalizerOptions } from '../types' import type { Normalized } from './types' import { JsonSchema } from './types' +import { chainI} from "../../_helpers/iterable"; +import {Tool} from "../../models"; export class Factory { readonly #spec: Spec @@ -72,6 +75,10 @@ export class Factory { return new ToolNormalizer(this) } + makeForTools (): ToolsNormalizer { + return new ToolsNormalizer(this) + } + makeForOrganizationalContact (): OrganizationalContactNormalizer { return new OrganizationalContactNormalizer(this) } @@ -221,7 +228,7 @@ export class MetadataNormalizer extends BaseJsonNormalizer { ? this._factory.makeForLifecycle().normalizeIterable(data.lifecycles, options) : undefined, tools: data.tools.size > 0 - ? this._factory.makeForTool().normalizeIterable(data.tools, options) + ? this._factory.makeForTools().normalize(data.tools, options) : undefined, authors: data.authors.size > 0 ? this._factory.makeForOrganizationalContact().normalizeIterable(data.authors, options) @@ -285,6 +292,23 @@ export class ToolNormalizer extends BaseJsonNormalizer { } } +export class ToolsNormalizer extends BaseJsonNormalizer { + normalize(data: Models.Tools, options: NormalizerOptions): Normalized.ToolsType { + if (data.tools.size > 0) { + return this._factory.makeForTool().normalizeIterable( + new ToolRepository(chainI( + Array.from(data.components, Tool.fromComponent), + // TODO services + data.tools, + )), options) + } + return { + components: this._factory.makeForComponent().normalizeIterable(data.components, options) + // TODO services + } + } +} + export class HashNormalizer extends BaseJsonNormalizer { normalize ([algorithm, content]: Models.Hash, options: NormalizerOptions): Normalized.Hash | undefined { const spec = this._factory.spec @@ -723,7 +747,7 @@ export class VulnerabilityNormalizer extends BaseJsonNormalizer 0 - ? this._factory.makeForTool().normalizeIterable(data.tools, options) + ? this._factory.makeForTools().normalize(data.tools, options) : undefined, analysis: data.analysis === undefined ? undefined diff --git a/src/serialize/json/types.ts b/src/serialize/json/types.ts index de27dd472..d5331f502 100644 --- a/src/serialize/json/types.ts +++ b/src/serialize/json/types.ts @@ -90,7 +90,7 @@ export namespace Normalized { export interface Metadata { timestamp?: JsonSchema.DateTime lifecycles?: Lifecycle[] - tools?: Tool[] + tools?: ToolsType authors?: OrganizationalContact[] component?: Component manufacture?: OrganizationalEntity @@ -118,6 +118,14 @@ export namespace Normalized { externalReferences?: ExternalReference[] } + /** since CDX 1.5 */ + export interface Tools { + components: Component[] + // TODO: services + } + + export type ToolsType = Tools | Tool[] + export interface OrganizationalContact { name?: string email?: JsonSchema.IdnEmail @@ -257,7 +265,7 @@ export namespace Normalized { published?: JsonSchema.DateTime updated?: JsonSchema.DateTime credits?: Vulnerability.Credits - tools?: Tool[] + tools?: ToolsType analysis?: Vulnerability.Analysis affects?: Vulnerability.Affect[] properties?: Property[] diff --git a/src/serialize/xml/normalize.ts b/src/serialize/xml/normalize.ts index efb31e17d..87fba27ae 100644 --- a/src/serialize/xml/normalize.ts +++ b/src/serialize/xml/normalize.ts @@ -33,6 +33,8 @@ import type { NormalizerOptions } from '../types' import { normalizedString, token} from './_xsd' import type { SimpleXml } from './types' import { XmlSchema } from './types' +import {Tool, ToolRepository} from "../../models"; +import {chainI} from "../../_helpers/iterable"; export class Factory { readonly #spec: Spec @@ -75,6 +77,10 @@ export class Factory { return new ToolNormalizer(this) } + makeForTools (): ToolsNormalizer { + return new ToolsNormalizer(this) + } + makeForOrganizationalContact (): OrganizationalContactNormalizer { return new OrganizationalContactNormalizer(this) } @@ -250,11 +256,7 @@ export class MetadataNormalizer extends BaseXmlNormalizer { } : undefined const tools: SimpleXml.Element | undefined = data.tools.size > 0 - ? { - type: 'element', - name: 'tools', - children: this._factory.makeForTool().normalizeIterable(data.tools, options, 'tool') - } + ? this._factory.makeForTools().normalize(data.tools, options) : undefined const authors: SimpleXml.Element | undefined = data.authors.size > 0 ? { @@ -369,6 +371,35 @@ export class ToolNormalizer extends BaseXmlNormalizer { } } +export class ToolsNormalizer extends BaseXmlNormalizer { + normalize (data: Models.Tools, options: NormalizerOptions, elementName: string): SimpleXml.Element { + let children: SimpleXml.Element[] + if (data.tools.size > 0) { + children = this._factory.makeForTool().normalizeIterable( + new ToolRepository(chainI( + Array.from(data.components, Tool.fromComponent), + // TODO services + data.tools, + )), options, 'tool') + } else { + children = [] + if (data.components.size > 0) { + children.push({ + type: 'element', + name: 'components', + children: this._factory.makeForComponent().normalizeIterable(data.components, options, 'component') + }) + } + // TODO data.services + } + return { + type: 'element', + name: elementName, + children + } + } +} + export class HashNormalizer extends BaseXmlNormalizer { normalize ([algorithm, content]: Models.Hash, options: NormalizerOptions, elementName: string): SimpleXml.Element | undefined { const spec = this._factory.spec @@ -938,7 +969,7 @@ export class VulnerabilityNormalizer extends BaseXmlNormalizer 0 From b3a71b7eecbde33d8a8783998d0d39ddbb6c016e Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 16:43:03 +0100 Subject: [PATCH 02/18] wip Signed-off-by: Jan Kowalleck --- src/serialize/json/normalize.ts | 2 +- src/serialize/xml/normalize.ts | 10 +++------- src/spec/_protocol.ts | 9 +++++++++ src/spec/consts.ts | 11 ++++++++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/serialize/json/normalize.ts b/src/serialize/json/normalize.ts index 3f8fcc992..94d381257 100644 --- a/src/serialize/json/normalize.ts +++ b/src/serialize/json/normalize.ts @@ -294,7 +294,7 @@ export class ToolNormalizer extends BaseJsonNormalizer { export class ToolsNormalizer extends BaseJsonNormalizer { normalize(data: Models.Tools, options: NormalizerOptions): Normalized.ToolsType { - if (data.tools.size > 0) { + if (data.tools.size > 0 || !this._factory.spec.supportsToolsComponentsServices) { return this._factory.makeForTool().normalizeIterable( new ToolRepository(chainI( Array.from(data.components, Tool.fromComponent), diff --git a/src/serialize/xml/normalize.ts b/src/serialize/xml/normalize.ts index 87fba27ae..f94620539 100644 --- a/src/serialize/xml/normalize.ts +++ b/src/serialize/xml/normalize.ts @@ -256,7 +256,7 @@ export class MetadataNormalizer extends BaseXmlNormalizer { } : undefined const tools: SimpleXml.Element | undefined = data.tools.size > 0 - ? this._factory.makeForTools().normalize(data.tools, options) + ? this._factory.makeForTools().normalize(data.tools, options, 'tools') : undefined const authors: SimpleXml.Element | undefined = data.authors.size > 0 ? { @@ -374,7 +374,7 @@ export class ToolNormalizer extends BaseXmlNormalizer { export class ToolsNormalizer extends BaseXmlNormalizer { normalize (data: Models.Tools, options: NormalizerOptions, elementName: string): SimpleXml.Element { let children: SimpleXml.Element[] - if (data.tools.size > 0) { + if (data.tools.size > 0 || !this._factory.spec.supportsToolsComponentsServices) { children = this._factory.makeForTool().normalizeIterable( new ToolRepository(chainI( Array.from(data.components, Tool.fromComponent), @@ -966,11 +966,7 @@ export class VulnerabilityNormalizer extends BaseXmlNormalizer 0 - ? { - type: 'element', - name: 'tools', - children: this._factory.makeForTools().normalize(data.tools, options) - } + ? this._factory.makeForTools().normalize(data.tools, options, 'tools') : undefined const affects: SimpleXml.Element | undefined = data.affects.size > 0 ? { diff --git a/src/spec/_protocol.ts b/src/spec/_protocol.ts index ce2930838..0c6ff80ff 100644 --- a/src/spec/_protocol.ts +++ b/src/spec/_protocol.ts @@ -48,6 +48,7 @@ export interface _SpecProtocol { supportsExternalReferenceHashes: boolean supportsLicenseAcknowledgement: boolean supportsServices:boolean + supportsToolsComponentsServices:boolean } /** @@ -77,6 +78,7 @@ export class _Spec implements _SpecProtocol { readonly #supportsExternalReferenceHashes: boolean readonly #supportsLicenseAcknowledgement: boolean readonly #supportsServices: boolean + readonly #supportsToolsComponentsServices:boolean /* eslint-disable-next-line @typescript-eslint/max-params -- architectural decision */ constructor ( @@ -99,6 +101,8 @@ export class _Spec implements _SpecProtocol { supportsExternalReferenceHashes: boolean, supportsLicenseAcknowledgement: boolean, supportsServices:boolean + supportsLicenseAcknowledgement: boolean, + supportsToolsComponentsServices:boolean ) { this.#version = version this.#formats = new Set(formats) @@ -119,6 +123,7 @@ export class _Spec implements _SpecProtocol { this.#supportsExternalReferenceHashes = supportsExternalReferenceHashes this.#supportsLicenseAcknowledgement = supportsLicenseAcknowledgement this.#supportsServices = supportsServices + this.#supportsToolsComponentsServices=supportsToolsComponentsServices } get version (): Version { @@ -203,4 +208,8 @@ export class _Spec implements _SpecProtocol { get supportsServices (): boolean { return this.#supportsServices } + + get supportsToolsComponentsServices(): boolean { + return this.#supportsToolsComponentsServices + } } diff --git a/src/spec/consts.ts b/src/spec/consts.ts index f848f26de..5372584fb 100644 --- a/src/spec/consts.ts +++ b/src/spec/consts.ts @@ -86,7 +86,8 @@ export const Spec1dot2: Readonly<_SpecProtocol> = Object.freeze(new _Spec( false, false, false, - true + true, + false )) /** Specification v1.3 */ @@ -150,7 +151,8 @@ export const Spec1dot3: Readonly<_SpecProtocol> = Object.freeze(new _Spec( true, true, false, - true + true, + false )) /** Specification v1.4 */ @@ -221,7 +223,8 @@ export const Spec1dot4: Readonly<_SpecProtocol> = Object.freeze(new _Spec( true, true, false, - true + true, + false )) /** Specification v1.5 */ @@ -321,6 +324,7 @@ export const Spec1dot5: Readonly<_SpecProtocol> = Object.freeze(new _Spec( true, true, false, + true, true )) @@ -426,6 +430,7 @@ export const Spec1dot6: Readonly<_SpecProtocol> = Object.freeze(new _Spec( true, true, true, + true, true )) From 951b608ea1b03ebd5bcb7059e2fc5d01ac26b13a Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 16:59:51 +0100 Subject: [PATCH 03/18] wip Signed-off-by: Jan Kowalleck --- src/_helpers/iterable.ts | 2 +- src/models/tool.ts | 2 +- src/serialize/json/normalize.ts | 5 ++--- src/serialize/xml/normalize.ts | 6 +++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/_helpers/iterable.ts b/src/_helpers/iterable.ts index 91bc1f384..7e9d63b38 100644 --- a/src/_helpers/iterable.ts +++ b/src/_helpers/iterable.ts @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -export function * chainI (...iterables: Array>): Generator { +export function * chainI (...iterables: Array>): Generator { for (const iterable of iterables) { for (const item of iterable) { yield item diff --git a/src/models/tool.ts b/src/models/tool.ts index 1a4a95cdd..5cfd53409 100644 --- a/src/models/tool.ts +++ b/src/models/tool.ts @@ -19,9 +19,9 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import type { Comparable } from '../_helpers/sortable' import { SortableComparables } from '../_helpers/sortable' +import {type Component, ComponentRepository} from "./component"; import { ExternalReferenceRepository } from './externalReference' import { HashDictionary } from './hash' -import {type Component, ComponentRepository} from "./component"; export interface OptionalToolProperties { vendor?: Tool['vendor'] diff --git a/src/serialize/json/normalize.ts b/src/serialize/json/normalize.ts index 94d381257..de08535d8 100644 --- a/src/serialize/json/normalize.ts +++ b/src/serialize/json/normalize.ts @@ -17,15 +17,16 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ +import { chainI } from "../../_helpers/iterable"; import { isNotUndefined } from '../../_helpers/notUndefined' import type { SortableIterable } from '../../_helpers/sortable' import type { Stringable } from '../../_helpers/stringable' import { treeIteratorSymbol } from '../../_helpers/tree' import { escapeUri } from '../../_helpers/uri' import type * as Models from '../../models' -import { ToolRepository } from '../../models/tool' import { LicenseExpression, NamedLicense, SpdxLicense } from '../../models/license' import { NamedLifecycle } from '../../models/lifecycle' +import { Tool, ToolRepository } from '../../models/tool' import { AffectedSingleVersion, AffectedVersionRange } from '../../models/vulnerability/affect' import { isSupportedSpdxId } from '../../spdx' import type { _SpecProtocol as Spec } from '../../spec/_protocol' @@ -33,8 +34,6 @@ import { Version as SpecVersion } from '../../spec/enums' import type { NormalizerOptions } from '../types' import type { Normalized } from './types' import { JsonSchema } from './types' -import { chainI} from "../../_helpers/iterable"; -import {Tool} from "../../models"; export class Factory { readonly #spec: Spec diff --git a/src/serialize/xml/normalize.ts b/src/serialize/xml/normalize.ts index f94620539..a02147b0d 100644 --- a/src/serialize/xml/normalize.ts +++ b/src/serialize/xml/normalize.ts @@ -17,12 +17,14 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ +import { chainI } from "../../_helpers/iterable"; import { isNotUndefined } from '../../_helpers/notUndefined' import type { SortableIterable } from '../../_helpers/sortable' import type { Stringable } from '../../_helpers/stringable' import { treeIteratorSymbol } from '../../_helpers/tree' import { escapeUri } from '../../_helpers/uri' import type * as Models from '../../models' +import { Tool, ToolRepository } from "../../models"; import { LicenseExpression, NamedLicense, SpdxLicense } from '../../models/license' import { NamedLifecycle } from '../../models/lifecycle' import { AffectedSingleVersion, AffectedVersionRange } from '../../models/vulnerability/affect' @@ -33,8 +35,6 @@ import type { NormalizerOptions } from '../types' import { normalizedString, token} from './_xsd' import type { SimpleXml } from './types' import { XmlSchema } from './types' -import {Tool, ToolRepository} from "../../models"; -import {chainI} from "../../_helpers/iterable"; export class Factory { readonly #spec: Spec @@ -376,7 +376,7 @@ export class ToolsNormalizer extends BaseXmlNormalizer { let children: SimpleXml.Element[] if (data.tools.size > 0 || !this._factory.spec.supportsToolsComponentsServices) { children = this._factory.makeForTool().normalizeIterable( - new ToolRepository(chainI( + new ToolRepository(chainI( Array.from(data.components, Tool.fromComponent), // TODO services data.tools, From 015e1db0054a7e3fa930c4d89acc44b0ed38c185 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 17:41:21 +0100 Subject: [PATCH 04/18] wip Signed-off-by: Jan Kowalleck --- tests/_data/models.js | 85 ++++++----- .../json_sortedLists_spec1.2.json | 6 +- .../json_sortedLists_spec1.3.json | 6 +- .../json_sortedLists_spec1.4.json | 10 +- .../json_sortedLists_spec1.5.json | 64 ++++---- .../json_sortedLists_spec1.6.json | 64 ++++---- .../xml_sortedLists_spec1.2.json | 6 +- .../xml_sortedLists_spec1.3.json | 6 +- .../xml_sortedLists_spec1.4.json | 22 ++- .../xml_sortedLists_spec1.5.json | 138 +++++++++++------- .../xml_sortedLists_spec1.6.json | 138 +++++++++++------- ...Models.Vulnerability.Vulnerability.spec.js | 6 +- 12 files changed, 329 insertions(+), 222 deletions(-) diff --git a/tests/_data/models.js b/tests/_data/models.js index 0a0659847..a01852059 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -35,29 +35,33 @@ module.exports.createComplexStructure = function () { Enums.LifecyclePhase.Design, new Models.NamedLifecycle('testing', { description: 'my testing stage' }) ]), - tools: new Models.ToolRepository([ - new Models.Tool({ - vendor: 'tool vendor', - name: 'tool name', - version: '0.8.15', - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm.MD5, 'f32a26e2a3a8aa338cd77b6e1263c535'], - [Enums.HashAlgorithm['SHA-1'], '829c3804401b0727f70f73d4415e162400cbe57b'] - ]) - }), - new Models.Tool({ - vendor: 'tool vendor', - name: 'other tool', - version: '', // empty string, not undefined - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference( - 'https://cyclonedx.org/tool-center/', - Enums.ExternalReferenceType.Website, - { comment: 'the tools that made this' } - ) - ]) - }) - ]), + tools: new Models.Tools({ + components: new Models.ComponentRepository([ + new Models.Component( + Enums.ComponentType.Application, + 'tool name', { + group: 'tool group', + version: '0.8.15', + hashes: new Models.HashDictionary([ + [Enums.HashAlgorithm.MD5, 'f32a26e2a3a8aa338cd77b6e1263c535'], + [Enums.HashAlgorithm['SHA-1'], '829c3804401b0727f70f73d4415e162400cbe57b'] + ]) + }), + new Models.Component( + Enums.ComponentType.Library, + 'tool name', { + group: 'tool group', + version: '', // empty string, not undefined + externalReferences: new Models.ExternalReferenceRepository([ + new Models.ExternalReference( + 'https://cyclonedx.org/tool-center/', + Enums.ExternalReferenceType.Website, + { comment: 'the tools that made this' } + ) + ]) + }) + ]) + }), authors: new Models.OrganizationalContactRepository([ new Models.OrganizationalContact({ name: 'John "the-co-author" Doe' }), new Models.OrganizationalContact({ @@ -452,12 +456,14 @@ module.exports.createComplexStructure = function () { new Models.OrganizationalContact({ name: 'John "pentester" Doe' }) ]) }), - tools: new Models.ToolRepository([ - new Models.Tool({ - vendor: 'v the vendor', - name: 'tool name' - }) - ]), + tools: new Models.Tools({ + tools: new Models.ToolRepository([ + new Models.Tool({ + vendor: 'v the vendor', + name: 'tool name' + }) + ]) + }), analysis: new Models.Vulnerability.Analysis({ state: Enums.Vulnerability.AnalysisState.FalsePositive, justification: Enums.Vulnerability.AnalysisJustification.ProtectedAtRuntime, @@ -536,12 +542,21 @@ module.exports.createComplexStructure = function () { new Models.OrganizationalContact({ name: 'John "pentester" Doe' }) ]) }), - tools: new Models.ToolRepository([ - new Models.Tool({ - vendor: 'v the vendor', - name: 'tool name' - }) - ]), + tools: new Models.Tools({ + tools: new Models.ToolRepository([ + new Models.Tool({ + vendor: 'v the vendor', + name: 'tool name' + }) + ]), + components: new Models.ComponentRepository([ + new Models.Component( + Enums.ComponentType.Application, + 'tool name', { + group: 'g the group' + }) + ]) + }), analysis: new Models.Vulnerability.Analysis({ state: Enums.Vulnerability.AnalysisState.FalsePositive, justification: Enums.Vulnerability.AnalysisJustification.ProtectedAtRuntime, diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json index aa42973c9..1f35435da 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json @@ -8,11 +8,11 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", - "name": "other tool" + "vendor": "tool group", + "name": "tool name" }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json index 9cde9ce6c..afb94206c 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json @@ -8,11 +8,11 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", - "name": "other tool" + "vendor": "tool group", + "name": "tool name" }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json index df67caea3..c5f1cff41 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json @@ -8,8 +8,8 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", - "name": "other tool", + "vendor": "tool group", + "name": "tool name", "externalReferences": [ { "url": "https://cyclonedx.org/tool-center/", @@ -19,7 +19,7 @@ ] }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ @@ -663,6 +663,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json index 72908cbd0..c2eb1619d 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json @@ -15,34 +15,38 @@ "phase": "design" } ], - "tools": [ - { - "vendor": "tool vendor", - "name": "other tool", - "externalReferences": [ - { - "url": "https://cyclonedx.org/tool-center/", - "type": "website", - "comment": "the tools that made this" - } - ] - }, - { - "vendor": "tool vendor", - "name": "tool name", - "version": "0.8.15", - "hashes": [ - { - "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" - }, - { - "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" - } - ] - } - ], + "tools": { + "components": [ + { + "type": "library", + "name": "tool name", + "group": "tool group", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "type": "application", + "name": "tool name", + "group": "tool group", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, "authors": [ { "name": "Jane \"the-author\" Doe", @@ -672,6 +676,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json index c7fd297a4..23a2b2f20 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json @@ -15,34 +15,38 @@ "phase": "design" } ], - "tools": [ - { - "vendor": "tool vendor", - "name": "other tool", - "externalReferences": [ - { - "url": "https://cyclonedx.org/tool-center/", - "type": "website", - "comment": "the tools that made this" - } - ] - }, - { - "vendor": "tool vendor", - "name": "tool name", - "version": "0.8.15", - "hashes": [ - { - "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" - }, - { - "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" - } - ] - } - ], + "tools": { + "components": [ + { + "type": "library", + "name": "tool name", + "group": "tool group", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "type": "application", + "name": "tool name", + "group": "tool group", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, "authors": [ { "name": "Jane \"the-author\" Doe", @@ -673,6 +677,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json index f13035ad6..97177bb08 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json @@ -27,12 +27,12 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", "name": "name", - "children": "other tool" + "children": "tool name" } ] }, @@ -43,7 +43,7 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json index 1c02a3be9..fd5e41adf 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json @@ -27,12 +27,12 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", "name": "name", - "children": "other tool" + "children": "tool name" } ] }, @@ -43,7 +43,7 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json index 46e9cf0d3..3c1a078ac 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json @@ -27,12 +27,12 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", "name": "name", - "children": "other tool" + "children": "tool name" }, { "type": "element", @@ -68,7 +68,7 @@ { "type": "element", "name": "vendor", - "children": "tool vendor" + "children": "tool group" }, { "type": "element", @@ -2085,6 +2085,22 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "g the group" + }, + { + "type": "element", + "name": "name", + "children": "tool name" + } + ] + }, { "type": "element", "name": "tool", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json index b886f8b03..43f81f2a9 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json @@ -55,83 +55,95 @@ "children": [ { "type": "element", - "name": "tool", + "name": "components", "children": [ { "type": "element", - "name": "vendor", - "children": "tool vendor" - }, - { - "type": "element", - "name": "name", - "children": "other tool" - }, - { - "type": "element", - "name": "externalReferences", + "name": "component", + "attributes": { + "type": "library" + }, "children": [ { "type": "element", - "name": "reference", - "attributes": { - "type": "website" - }, + "name": "group", + "children": "tool group" + }, + { + "type": "element", + "name": "name", + "children": "tool name" + }, + { + "type": "element", + "name": "externalReferences", "children": [ { "type": "element", - "name": "url", - "children": "https://cyclonedx.org/tool-center/" - }, - { - "type": "element", - "name": "comment", - "children": "the tools that made this" + "name": "reference", + "attributes": { + "type": "website" + }, + "children": [ + { + "type": "element", + "name": "url", + "children": "https://cyclonedx.org/tool-center/" + }, + { + "type": "element", + "name": "comment", + "children": "the tools that made this" + } + ] } ] } ] - } - ] - }, - { - "type": "element", - "name": "tool", - "children": [ - { - "type": "element", - "name": "vendor", - "children": "tool vendor" }, { "type": "element", - "name": "name", - "children": "tool name" - }, - { - "type": "element", - "name": "version", - "children": "0.8.15" - }, - { - "type": "element", - "name": "hashes", + "name": "component", + "attributes": { + "type": "application" + }, "children": [ { "type": "element", - "name": "hash", - "attributes": { - "alg": "MD5" - }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "name": "group", + "children": "tool group" }, { "type": "element", - "name": "hash", - "attributes": { - "alg": "SHA-1" - }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "name": "name", + "children": "tool name" + }, + { + "type": "element", + "name": "version", + "children": "0.8.15" + }, + { + "type": "element", + "name": "hashes", + "children": [ + { + "type": "element", + "name": "hash", + "attributes": { + "alg": "MD5" + }, + "children": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "type": "element", + "name": "hash", + "attributes": { + "alg": "SHA-1" + }, + "children": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] } ] } @@ -2118,6 +2130,22 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "g the group" + }, + { + "type": "element", + "name": "name", + "children": "tool name" + } + ] + }, { "type": "element", "name": "tool", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json index f8ecff77f..2233cb905 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json @@ -55,83 +55,95 @@ "children": [ { "type": "element", - "name": "tool", + "name": "components", "children": [ { "type": "element", - "name": "vendor", - "children": "tool vendor" - }, - { - "type": "element", - "name": "name", - "children": "other tool" - }, - { - "type": "element", - "name": "externalReferences", + "name": "component", + "attributes": { + "type": "library" + }, "children": [ { "type": "element", - "name": "reference", - "attributes": { - "type": "website" - }, + "name": "group", + "children": "tool group" + }, + { + "type": "element", + "name": "name", + "children": "tool name" + }, + { + "type": "element", + "name": "externalReferences", "children": [ { "type": "element", - "name": "url", - "children": "https://cyclonedx.org/tool-center/" - }, - { - "type": "element", - "name": "comment", - "children": "the tools that made this" + "name": "reference", + "attributes": { + "type": "website" + }, + "children": [ + { + "type": "element", + "name": "url", + "children": "https://cyclonedx.org/tool-center/" + }, + { + "type": "element", + "name": "comment", + "children": "the tools that made this" + } + ] } ] } ] - } - ] - }, - { - "type": "element", - "name": "tool", - "children": [ - { - "type": "element", - "name": "vendor", - "children": "tool vendor" }, { "type": "element", - "name": "name", - "children": "tool name" - }, - { - "type": "element", - "name": "version", - "children": "0.8.15" - }, - { - "type": "element", - "name": "hashes", + "name": "component", + "attributes": { + "type": "application" + }, "children": [ { "type": "element", - "name": "hash", - "attributes": { - "alg": "MD5" - }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "name": "group", + "children": "tool group" }, { "type": "element", - "name": "hash", - "attributes": { - "alg": "SHA-1" - }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "name": "name", + "children": "tool name" + }, + { + "type": "element", + "name": "version", + "children": "0.8.15" + }, + { + "type": "element", + "name": "hashes", + "children": [ + { + "type": "element", + "name": "hash", + "attributes": { + "alg": "MD5" + }, + "children": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "type": "element", + "name": "hash", + "attributes": { + "alg": "SHA-1" + }, + "children": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] } ] } @@ -2120,6 +2132,22 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "g the group" + }, + { + "type": "element", + "name": "name", + "children": "tool name" + } + ] + }, { "type": "element", "name": "tool", diff --git a/tests/unit/Models.Vulnerability.Vulnerability.spec.js b/tests/unit/Models.Vulnerability.Vulnerability.spec.js index 58ba2a48b..5e5a79844 100644 --- a/tests/unit/Models.Vulnerability.Vulnerability.spec.js +++ b/tests/unit/Models.Vulnerability.Vulnerability.spec.js @@ -22,7 +22,7 @@ const { suite, test } = require('mocha') const { Models: { - PropertyRepository, ToolRepository, + PropertyRepository, Tools, Vulnerability: { AdvisoryRepository, AffectRepository, Analysis, Credits, RatingRepository, ReferenceRepository, Source, Vulnerability @@ -53,7 +53,7 @@ suite('Models.Vulnerability.Vulnerability', () => { assert.strictEqual(vulnerability.published, undefined) assert.strictEqual(vulnerability.updated, undefined) assert.strictEqual(vulnerability.credits, undefined) - assert.ok(vulnerability.tools instanceof ToolRepository) + assert.ok(vulnerability.tools instanceof Tools) assert.strictEqual(vulnerability.tools.size, 0) assert.strictEqual(vulnerability.analysis, undefined) assert.ok(vulnerability.affects instanceof AffectRepository) @@ -72,7 +72,7 @@ suite('Models.Vulnerability.Vulnerability', () => { const dummyPublished = new Date() const dummyUpdated = new Date() const dummyCredits = new Credits() - const dummyTools = new ToolRepository() + const dummyTools = new Tools() const dummyAnalysis = new Analysis() const dummyAffects = new AffectRepository() const dummyProperties = new PropertyRepository() From e0046a07952aff865764e8851a0b2b504db71191 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 18:02:35 +0100 Subject: [PATCH 05/18] wip Signed-off-by: Jan Kowalleck --- src/models/tool.ts | 1 + tests/_data/models.js | 4 ++-- tests/_data/normalizeResults/json_sortedLists_spec1.2.json | 2 +- tests/_data/normalizeResults/json_sortedLists_spec1.3.json | 2 +- tests/_data/normalizeResults/json_sortedLists_spec1.4.json | 4 ++-- tests/_data/normalizeResults/json_sortedLists_spec1.5.json | 4 ++-- tests/_data/normalizeResults/json_sortedLists_spec1.6.json | 4 ++-- tests/_data/normalizeResults/xml_sortedLists_spec1.2.json | 2 +- tests/_data/normalizeResults/xml_sortedLists_spec1.3.json | 2 +- tests/_data/normalizeResults/xml_sortedLists_spec1.4.json | 4 ++-- tests/_data/normalizeResults/xml_sortedLists_spec1.5.json | 4 ++-- tests/_data/normalizeResults/xml_sortedLists_spec1.6.json | 4 ++-- 12 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/models/tool.ts b/src/models/tool.ts index 5cfd53409..43f6dd8dc 100644 --- a/src/models/tool.ts +++ b/src/models/tool.ts @@ -72,6 +72,7 @@ export class ToolRepository extends SortableComparables { export interface OptionalToolsProperties { components?: ComponentRepository + // TODO: services tools?: ToolRepository } diff --git a/tests/_data/models.js b/tests/_data/models.js index a01852059..3f4b70245 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -49,7 +49,7 @@ module.exports.createComplexStructure = function () { }), new Models.Component( Enums.ComponentType.Library, - 'tool name', { + 'other tool', { group: 'tool group', version: '', // empty string, not undefined externalReferences: new Models.ExternalReferenceRepository([ @@ -552,7 +552,7 @@ module.exports.createComplexStructure = function () { components: new Models.ComponentRepository([ new Models.Component( Enums.ComponentType.Application, - 'tool name', { + 'other tool name', { group: 'g the group' }) ]) diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json index 1f35435da..67187f485 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json @@ -9,7 +9,7 @@ "tools": [ { "vendor": "tool group", - "name": "tool name" + "name": "other tool" }, { "vendor": "tool group", diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json index afb94206c..296a603cf 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json @@ -9,7 +9,7 @@ "tools": [ { "vendor": "tool group", - "name": "tool name" + "name": "other tool" }, { "vendor": "tool group", diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json index c5f1cff41..2b1b99253 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json @@ -9,7 +9,7 @@ "tools": [ { "vendor": "tool group", - "name": "tool name", + "name": "other tool", "externalReferences": [ { "url": "https://cyclonedx.org/tool-center/", @@ -665,7 +665,7 @@ "tools": [ { "vendor": "g the group", - "name": "tool name" + "name": "other tool name" }, { "vendor": "v the vendor", diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json index c2eb1619d..881388b64 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json @@ -19,7 +19,7 @@ "components": [ { "type": "library", - "name": "tool name", + "name": "other tool", "group": "tool group", "externalReferences": [ { @@ -678,7 +678,7 @@ "tools": [ { "vendor": "g the group", - "name": "tool name" + "name": "other tool name" }, { "vendor": "v the vendor", diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json index 23a2b2f20..527b339e8 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json @@ -19,7 +19,7 @@ "components": [ { "type": "library", - "name": "tool name", + "name": "other tool", "group": "tool group", "externalReferences": [ { @@ -679,7 +679,7 @@ "tools": [ { "vendor": "g the group", - "name": "tool name" + "name": "other tool name" }, { "vendor": "v the vendor", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json index 97177bb08..c46fe5be1 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json @@ -32,7 +32,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool" } ] }, diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json index fd5e41adf..80636dd47 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json @@ -32,7 +32,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool" } ] }, diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json index 3c1a078ac..2dae45a53 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json @@ -32,7 +32,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool" }, { "type": "element", @@ -2097,7 +2097,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool name" } ] }, diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json index 43f81f2a9..6e52b8ed1 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json @@ -72,7 +72,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool" }, { "type": "element", @@ -2142,7 +2142,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool name" } ] }, diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json index 2233cb905..bac6474e1 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json @@ -72,7 +72,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool" }, { "type": "element", @@ -2144,7 +2144,7 @@ { "type": "element", "name": "name", - "children": "tool name" + "children": "other tool name" } ] }, From 9d0e8e6241dfe59456458446b3bdbcaccda3fb6c Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 5 Nov 2024 18:16:34 +0100 Subject: [PATCH 06/18] wip Signed-off-by: Jan Kowalleck --- HISTORY.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 29330001f..a7a949586 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,16 @@ All notable changes to this project will be documented in this file. +* BREAKING changes + * ... +* Added + * ... +* Changed + * ... + +[#1152]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1152 +[#1163]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1163 + ## 6.12.0 -- 2024-11-12 * Added From e0d98e22925d0b17a23097d3ed19c9185d635f1e Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 09:19:37 +0100 Subject: [PATCH 07/18] wip Signed-off-by: Jan Kowalleck --- src/models/tool.ts | 26 +++++++++++++++++++------- src/serialize/json/normalize.ts | 6 +++--- src/serialize/json/types.ts | 2 +- src/serialize/xml/normalize.ts | 10 ++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/models/tool.ts b/src/models/tool.ts index 43f6dd8dc..723da8549 100644 --- a/src/models/tool.ts +++ b/src/models/tool.ts @@ -19,9 +19,12 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import type { Comparable } from '../_helpers/sortable' import { SortableComparables } from '../_helpers/sortable' -import {type Component, ComponentRepository} from "./component"; +import type { Component } from "./component"; +import { ComponentRepository} from "./component"; import { ExternalReferenceRepository } from './externalReference' import { HashDictionary } from './hash' +import type { Service } from "./service"; +import { ServiceRepository } from "./service"; export interface OptionalToolProperties { vendor?: Tool['vendor'] @@ -64,6 +67,15 @@ export class Tool implements Comparable { externalReferences: component.externalReferences }) } + + static fromService(service: Service): Tool { + return new Tool({ + vendor: service.group, + name: service.name, + version: service.version, + externalReferences: service.externalReferences + }) + } } export class ToolRepository extends SortableComparables { @@ -71,25 +83,25 @@ export class ToolRepository extends SortableComparables { export interface OptionalToolsProperties { - components?: ComponentRepository - // TODO: services - tools?: ToolRepository + components?: Tools['components'] + services?: Tools['services'] + tools?: Tools['tools'] } export class Tools { components: ComponentRepository - // TODO: services + services: ServiceRepository tools: ToolRepository constructor(op: OptionalToolsProperties = {}) { this.components = op.components ?? new ComponentRepository() - // TODO: this.services + this.services = op.services ?? new ServiceRepository() this.tools = op.tools ?? new ToolRepository() } get size(): number { return this.components.size - // TODO: this.services + + this.services.size + this.tools.size } } diff --git a/src/serialize/json/normalize.ts b/src/serialize/json/normalize.ts index de08535d8..ae1322cce 100644 --- a/src/serialize/json/normalize.ts +++ b/src/serialize/json/normalize.ts @@ -297,13 +297,13 @@ export class ToolsNormalizer extends BaseJsonNormalizer { return this._factory.makeForTool().normalizeIterable( new ToolRepository(chainI( Array.from(data.components, Tool.fromComponent), - // TODO services + Array.from(data.services, Tool.fromService), data.tools, )), options) } return { - components: this._factory.makeForComponent().normalizeIterable(data.components, options) - // TODO services + components: this._factory.makeForComponent().normalizeIterable(data.components, options), + services: this._factory.makeForService().normalizeIterable(data.services, options) } } } diff --git a/src/serialize/json/types.ts b/src/serialize/json/types.ts index d5331f502..e8d24d8d2 100644 --- a/src/serialize/json/types.ts +++ b/src/serialize/json/types.ts @@ -121,7 +121,7 @@ export namespace Normalized { /** since CDX 1.5 */ export interface Tools { components: Component[] - // TODO: services + services: Service[] } export type ToolsType = Tools | Tool[] diff --git a/src/serialize/xml/normalize.ts b/src/serialize/xml/normalize.ts index a02147b0d..58e1f4287 100644 --- a/src/serialize/xml/normalize.ts +++ b/src/serialize/xml/normalize.ts @@ -378,7 +378,7 @@ export class ToolsNormalizer extends BaseXmlNormalizer { children = this._factory.makeForTool().normalizeIterable( new ToolRepository(chainI( Array.from(data.components, Tool.fromComponent), - // TODO services + Array.from(data.services, Tool.fromService), data.tools, )), options, 'tool') } else { @@ -390,7 +390,13 @@ export class ToolsNormalizer extends BaseXmlNormalizer { children: this._factory.makeForComponent().normalizeIterable(data.components, options, 'component') }) } - // TODO data.services + if (data.components.size > 0) { + children.push({ + type: 'element', + name: 'services', + children: this._factory.makeForService().normalizeIterable(data.services, options, 'service') + }) + } } return { type: 'element', From db731cfe6c7872c23fdd534a6c0789d08eecd6df Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 09:25:03 +0100 Subject: [PATCH 08/18] wip Signed-off-by: Jan Kowalleck --- tests/_data/models.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/_data/models.js b/tests/_data/models.js index 3f4b70245..6febb61b6 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -43,8 +43,8 @@ module.exports.createComplexStructure = function () { group: 'tool group', version: '0.8.15', hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm.MD5, 'f32a26e2a3a8aa338cd77b6e1263c535'], - [Enums.HashAlgorithm['SHA-1'], '829c3804401b0727f70f73d4415e162400cbe57b'] + [Enums.HashAlgorithm.MD5, '974e5cc07da6e4536bffd935fd4ddc61'], + [Enums.HashAlgorithm['SHA-1'], '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'] ]) }), new Models.Component( @@ -60,6 +60,9 @@ module.exports.createComplexStructure = function () { ) ]) }) + ]), + services: new Models.ServiceRepository([ + new Models.Service('sbom-generator-service') ]) }), authors: new Models.OrganizationalContactRepository([ From 0e42009c3e9ff2c4f3ff7441a44c3dc04faf8d96 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 09:31:49 +0100 Subject: [PATCH 09/18] wip Signed-off-by: Jan Kowalleck --- src/spec/_protocol.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/spec/_protocol.ts b/src/spec/_protocol.ts index 0c6ff80ff..50020e007 100644 --- a/src/spec/_protocol.ts +++ b/src/spec/_protocol.ts @@ -47,8 +47,8 @@ export interface _SpecProtocol { supportsMetadataProperties: boolean supportsExternalReferenceHashes: boolean supportsLicenseAcknowledgement: boolean - supportsServices:boolean - supportsToolsComponentsServices:boolean + supportsServices: boolean + supportsToolsComponentsServices: boolean } /** @@ -78,7 +78,7 @@ export class _Spec implements _SpecProtocol { readonly #supportsExternalReferenceHashes: boolean readonly #supportsLicenseAcknowledgement: boolean readonly #supportsServices: boolean - readonly #supportsToolsComponentsServices:boolean + readonly #supportsToolsComponentsServices: boolean /* eslint-disable-next-line @typescript-eslint/max-params -- architectural decision */ constructor ( @@ -100,9 +100,8 @@ export class _Spec implements _SpecProtocol { supportsMetadataProperties: boolean, supportsExternalReferenceHashes: boolean, supportsLicenseAcknowledgement: boolean, - supportsServices:boolean - supportsLicenseAcknowledgement: boolean, - supportsToolsComponentsServices:boolean + supportsServices: boolean, + supportsToolsComponentsServices: boolean ) { this.#version = version this.#formats = new Set(formats) @@ -123,7 +122,7 @@ export class _Spec implements _SpecProtocol { this.#supportsExternalReferenceHashes = supportsExternalReferenceHashes this.#supportsLicenseAcknowledgement = supportsLicenseAcknowledgement this.#supportsServices = supportsServices - this.#supportsToolsComponentsServices=supportsToolsComponentsServices + this.#supportsToolsComponentsServices = supportsToolsComponentsServices } get version (): Version { From f3e7197b1c5e480489f44ec752b510c5a2533756 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 09:53:35 +0100 Subject: [PATCH 10/18] wip Signed-off-by: Jan Kowalleck --- tests/_data/models.js | 75 ++++++++++++++++- .../json_sortedLists_spec1.2.json | 11 ++- .../json_sortedLists_spec1.3.json | 11 ++- .../json_sortedLists_spec1.4.json | 18 ++++- .../json_sortedLists_spec1.5.json | 20 ++++- .../json_sortedLists_spec1.6.json | 20 ++++- .../xml_sortedLists_spec1.2.json | 27 ++++++- .../xml_sortedLists_spec1.3.json | 27 ++++++- .../xml_sortedLists_spec1.4.json | 52 +++++++++++- .../xml_sortedLists_spec1.5.json | 59 +++++++++++++- .../xml_sortedLists_spec1.6.json | 59 +++++++++++++- .../json_complex_spec1.2.json.bin | 15 ++-- .../json_complex_spec1.3.json.bin | 15 ++-- .../json_complex_spec1.4.json.bin | 26 ++++-- .../json_complex_spec1.5.json.bin | 80 ++++++++++++------- .../json_complex_spec1.6.json.bin | 80 ++++++++++++------- .../xml_complex_spec1.2.xml.bin | 15 ++-- .../xml_complex_spec1.3.xml.bin | 15 ++-- .../xml_complex_spec1.4.xml.bin | 25 ++++-- .../xml_complex_spec1.5.xml.bin | 59 +++++++++----- .../xml_complex_spec1.6.xml.bin | 59 +++++++++----- 21 files changed, 608 insertions(+), 160 deletions(-) diff --git a/tests/_data/models.js b/tests/_data/models.js index 6febb61b6..d7c3c4503 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -62,7 +62,17 @@ module.exports.createComplexStructure = function () { }) ]), services: new Models.ServiceRepository([ - new Models.Service('sbom-generator-service') + new Models.Service('sbom-generator-service', { + group: 'Service service group', + version: '1', + externalReferences: new Models.ExternalReferenceRepository([ + new Models.ExternalReference( + 'https://example.com/sbom-generator-service/', + Enums.ExternalReferenceType.Website, + { comment: 'the service that made this' } + ) + ]) + }) ]) }), authors: new Models.OrganizationalContactRepository([ @@ -313,7 +323,6 @@ module.exports.createComplexStructure = function () { service.bomRef.value = 'some-service' service.provider = new Models.OrganizationalEntity({ name: 'Service Provider' }) service.group = 'acme' - service.version = '1.2+service-version' service.description = 'this is a test service' service.externalReferences.add(new Models.ExternalReference( 'https://localhost/service/docs', @@ -599,3 +608,65 @@ module.exports.createComplexStructure = function () { return bom } + + +/** + * @returns {Models.Bom} + */ +module.exports.createAllTools = function () { + const bomSerialNumberRaw = '8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e' + const bom = new Models.Bom({ + version: 7, + serialNumber: `urn:uuid:${bomSerialNumberRaw}`, + }) + bom.metadata.tools.components.push( + new Models.Component( + Enums.ComponentType.Application, + 'Component tool name', { + group: 'Component tool group', + version: '0.8.15', + hashes: new Models.HashDictionary([ + [Enums.HashAlgorithm.MD5, '974e5cc07da6e4536bffd935fd4ddc61'], + [Enums.HashAlgorithm['SHA-1'], '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'] + ]) + })) + bom.metadata.tools.services.push( + new Models.Service('sbom-generator-service', { + group: 'Service tool group', + version: '1', + externalReferences: new Models.ExternalReferenceRepository([ + new Models.ExternalReference( + 'https://example.com/sbom-generator-service/', + Enums.ExternalReferenceType.Website, + { comment: 'the service that made this' } + ) + ]) + }) + ) + bom.metadata.tools.tools.push( + new Models.Tool({ + vendor: 'Tool tool vendor', + name: 'Tool tool name', + version: '0.8.15', + hashes: new Models.HashDictionary([ + [Enums.HashAlgorithm.MD5, 'f32a26e2a3a8aa338cd77b6e1263c535'], + [Enums.HashAlgorithm['SHA-1'], '829c3804401b0727f70f73d4415e162400cbe57b'] + ]) + }) + ) + bom.metadata.tools.tools.push( + new Models.Tool({ + vendor: 'Tool tool vendor', + name: 'Tool other tool', + version: '', // empty string, not undefined + externalReferences: new Models.ExternalReferenceRepository([ + new Models.ExternalReference( + 'https://cyclonedx.org/tool-center/', + Enums.ExternalReferenceType.Website, + { comment: 'the tools that made this' } + ) + ]) + }) + ) + return bom +} diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json index 67187f485..6ee4cdeaf 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.2.json @@ -7,6 +7,11 @@ "metadata": { "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ + { + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1" + }, { "vendor": "tool group", "name": "other tool" @@ -18,11 +23,11 @@ "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -338,7 +343,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json index 296a603cf..4266ac0ac 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.3.json @@ -7,6 +7,11 @@ "metadata": { "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ + { + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1" + }, { "vendor": "tool group", "name": "other tool" @@ -18,11 +23,11 @@ "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -407,7 +412,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json index 2b1b99253..cbded2e08 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.4.json @@ -7,6 +7,18 @@ "metadata": { "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ + { + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + }, { "vendor": "tool group", "name": "other tool", @@ -25,11 +37,11 @@ "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -409,7 +421,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json index 881388b64..359392b83 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.5.json @@ -37,11 +37,25 @@ "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ], + "services": [ + { + "group": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" } ] } @@ -422,7 +436,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json index 527b339e8..57c946944 100644 --- a/tests/_data/normalizeResults/json_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/json_sortedLists_spec1.6.json @@ -37,11 +37,25 @@ "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ], + "services": [ + { + "group": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" } ] } @@ -423,7 +437,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json index c46fe5be1..1e88b14c1 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.2.json @@ -20,6 +20,27 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "Service service group" + }, + { + "type": "element", + "name": "name", + "children": "sbom-generator-service" + }, + { + "type": "element", + "name": "version", + "children": "1" + } + ] + }, { "type": "element", "name": "tool", @@ -65,7 +86,7 @@ "attributes": { "alg": "MD5" }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "children": "974e5cc07da6e4536bffd935fd4ddc61" }, { "type": "element", @@ -73,7 +94,7 @@ "attributes": { "alg": "SHA-1" }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "children": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -1084,7 +1105,7 @@ { "type": "element", "name": "version", - "children": "1.2+service-version" + "children": "1.0+service-version" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json index 80636dd47..5c60c3284 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.3.json @@ -20,6 +20,27 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "Service service group" + }, + { + "type": "element", + "name": "name", + "children": "sbom-generator-service" + }, + { + "type": "element", + "name": "version", + "children": "1" + } + ] + }, { "type": "element", "name": "tool", @@ -65,7 +86,7 @@ "attributes": { "alg": "MD5" }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "children": "974e5cc07da6e4536bffd935fd4ddc61" }, { "type": "element", @@ -73,7 +94,7 @@ "attributes": { "alg": "SHA-1" }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "children": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -1240,7 +1261,7 @@ { "type": "element", "name": "version", - "children": "1.2+service-version" + "children": "1.0+service-version" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json index 2dae45a53..9e19d0191 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.4.json @@ -20,6 +20,52 @@ "type": "element", "name": "tools", "children": [ + { + "type": "element", + "name": "tool", + "children": [ + { + "type": "element", + "name": "vendor", + "children": "Service service group" + }, + { + "type": "element", + "name": "name", + "children": "sbom-generator-service" + }, + { + "type": "element", + "name": "version", + "children": "1" + }, + { + "type": "element", + "name": "externalReferences", + "children": [ + { + "type": "element", + "name": "reference", + "attributes": { + "type": "website" + }, + "children": [ + { + "type": "element", + "name": "url", + "children": "https://example.com/sbom-generator-service/" + }, + { + "type": "element", + "name": "comment", + "children": "the service that made this" + } + ] + } + ] + } + ] + }, { "type": "element", "name": "tool", @@ -90,7 +136,7 @@ "attributes": { "alg": "MD5" }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "children": "974e5cc07da6e4536bffd935fd4ddc61" }, { "type": "element", @@ -98,7 +144,7 @@ "attributes": { "alg": "SHA-1" }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "children": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -1234,7 +1280,7 @@ { "type": "element", "name": "version", - "children": "1.2+service-version" + "children": "1.0+service-version" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json index 6e52b8ed1..c93e1334d 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.5.json @@ -133,7 +133,7 @@ "attributes": { "alg": "MD5" }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "children": "974e5cc07da6e4536bffd935fd4ddc61" }, { "type": "element", @@ -141,7 +141,60 @@ "attributes": { "alg": "SHA-1" }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "children": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ] + } + ] + }, + { + "type": "element", + "name": "services", + "children": [ + { + "type": "element", + "name": "service", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "group", + "children": "Service service group" + }, + { + "type": "element", + "name": "name", + "children": "sbom-generator-service" + }, + { + "type": "element", + "name": "version", + "children": "1" + }, + { + "type": "element", + "name": "externalReferences", + "children": [ + { + "type": "element", + "name": "reference", + "attributes": { + "type": "website" + }, + "children": [ + { + "type": "element", + "name": "url", + "children": "https://example.com/sbom-generator-service/" + }, + { + "type": "element", + "name": "comment", + "children": "the service that made this" + } + ] } ] } @@ -1279,7 +1332,7 @@ { "type": "element", "name": "version", - "children": "1.2+service-version" + "children": "1.0+service-version" }, { "type": "element", diff --git a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json index bac6474e1..ed5c34aae 100644 --- a/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json +++ b/tests/_data/normalizeResults/xml_sortedLists_spec1.6.json @@ -133,7 +133,7 @@ "attributes": { "alg": "MD5" }, - "children": "f32a26e2a3a8aa338cd77b6e1263c535" + "children": "974e5cc07da6e4536bffd935fd4ddc61" }, { "type": "element", @@ -141,7 +141,60 @@ "attributes": { "alg": "SHA-1" }, - "children": "829c3804401b0727f70f73d4415e162400cbe57b" + "children": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ] + } + ] + }, + { + "type": "element", + "name": "services", + "children": [ + { + "type": "element", + "name": "service", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "group", + "children": "Service service group" + }, + { + "type": "element", + "name": "name", + "children": "sbom-generator-service" + }, + { + "type": "element", + "name": "version", + "children": "1" + }, + { + "type": "element", + "name": "externalReferences", + "children": [ + { + "type": "element", + "name": "reference", + "attributes": { + "type": "website" + }, + "children": [ + { + "type": "element", + "name": "url", + "children": "https://example.com/sbom-generator-service/" + }, + { + "type": "element", + "name": "comment", + "children": "the service that made this" + } + ] } ] } @@ -1281,7 +1334,7 @@ { "type": "element", "name": "version", - "children": "1.2+service-version" + "children": "1.0+service-version" }, { "type": "element", diff --git a/tests/_data/serializeResults/json_complex_spec1.2.json.bin b/tests/_data/serializeResults/json_complex_spec1.2.json.bin index 5205f5eef..84148dcb4 100644 --- a/tests/_data/serializeResults/json_complex_spec1.2.json.bin +++ b/tests/_data/serializeResults/json_complex_spec1.2.json.bin @@ -8,21 +8,26 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1" + }, + { + "vendor": "tool group", "name": "other tool" }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -338,7 +343,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/serializeResults/json_complex_spec1.3.json.bin b/tests/_data/serializeResults/json_complex_spec1.3.json.bin index 961949f12..358fdda1f 100644 --- a/tests/_data/serializeResults/json_complex_spec1.3.json.bin +++ b/tests/_data/serializeResults/json_complex_spec1.3.json.bin @@ -8,21 +8,26 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1" + }, + { + "vendor": "tool group", "name": "other tool" }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -407,7 +412,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { diff --git a/tests/_data/serializeResults/json_complex_spec1.4.json.bin b/tests/_data/serializeResults/json_complex_spec1.4.json.bin index 390129033..6886fe52c 100644 --- a/tests/_data/serializeResults/json_complex_spec1.4.json.bin +++ b/tests/_data/serializeResults/json_complex_spec1.4.json.bin @@ -8,7 +8,19 @@ "timestamp": "2032-05-23T13:37:42.000Z", "tools": [ { - "vendor": "tool vendor", + "vendor": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + }, + { + "vendor": "tool group", "name": "other tool", "externalReferences": [ { @@ -19,17 +31,17 @@ ] }, { - "vendor": "tool vendor", + "vendor": "tool group", "name": "tool name", "version": "0.8.15", "hashes": [ { "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" + "content": "974e5cc07da6e4536bffd935fd4ddc61" }, { "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" } ] } @@ -409,7 +421,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { @@ -663,6 +675,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "other tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/serializeResults/json_complex_spec1.5.json.bin b/tests/_data/serializeResults/json_complex_spec1.5.json.bin index 07f543ae6..2a286217f 100644 --- a/tests/_data/serializeResults/json_complex_spec1.5.json.bin +++ b/tests/_data/serializeResults/json_complex_spec1.5.json.bin @@ -15,34 +15,52 @@ "phase": "design" } ], - "tools": [ - { - "vendor": "tool vendor", - "name": "other tool", - "externalReferences": [ - { - "url": "https://cyclonedx.org/tool-center/", - "type": "website", - "comment": "the tools that made this" - } - ] - }, - { - "vendor": "tool vendor", - "name": "tool name", - "version": "0.8.15", - "hashes": [ - { - "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" - }, - { - "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" - } - ] - } - ], + "tools": { + "components": [ + { + "type": "library", + "name": "other tool", + "group": "tool group", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "type": "application", + "name": "tool name", + "group": "tool group", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ], + "services": [ + { + "group": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + } + ] + }, "authors": [ { "name": "Jane \"the-author\" Doe", @@ -418,7 +436,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { @@ -672,6 +690,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "other tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/serializeResults/json_complex_spec1.6.json.bin b/tests/_data/serializeResults/json_complex_spec1.6.json.bin index bc4097fbc..aa520a610 100644 --- a/tests/_data/serializeResults/json_complex_spec1.6.json.bin +++ b/tests/_data/serializeResults/json_complex_spec1.6.json.bin @@ -15,34 +15,52 @@ "phase": "design" } ], - "tools": [ - { - "vendor": "tool vendor", - "name": "other tool", - "externalReferences": [ - { - "url": "https://cyclonedx.org/tool-center/", - "type": "website", - "comment": "the tools that made this" - } - ] - }, - { - "vendor": "tool vendor", - "name": "tool name", - "version": "0.8.15", - "hashes": [ - { - "alg": "MD5", - "content": "f32a26e2a3a8aa338cd77b6e1263c535" - }, - { - "alg": "SHA-1", - "content": "829c3804401b0727f70f73d4415e162400cbe57b" - } - ] - } - ], + "tools": { + "components": [ + { + "type": "library", + "name": "other tool", + "group": "tool group", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "type": "application", + "name": "tool name", + "group": "tool group", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + } + ], + "services": [ + { + "group": "Service service group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + } + ] + }, "authors": [ { "name": "Jane \"the-author\" Doe", @@ -419,7 +437,7 @@ }, "group": "acme", "name": "dummy-service", - "version": "1.2+service-version", + "version": "1.0+service-version", "description": "this is a test service", "licenses": [ { @@ -673,6 +691,10 @@ ] }, "tools": [ + { + "vendor": "g the group", + "name": "other tool name" + }, { "vendor": "v the vendor", "name": "tool name" diff --git a/tests/_data/serializeResults/xml_complex_spec1.2.xml.bin b/tests/_data/serializeResults/xml_complex_spec1.2.xml.bin index 2ee07e908..48937bf25 100644 --- a/tests/_data/serializeResults/xml_complex_spec1.2.xml.bin +++ b/tests/_data/serializeResults/xml_complex_spec1.2.xml.bin @@ -4,16 +4,21 @@ 2032-05-23T13:37:42.000Z - tool vendor + Service service group + sbom-generator-service + 1 + + + tool group other tool - tool vendor + tool group tool name 0.8.15 - f32a26e2a3a8aa338cd77b6e1263c535 - 829c3804401b0727f70f73d4415e162400cbe57b + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed @@ -237,7 +242,7 @@ acme dummy-service - 1.2+service-version + 1.0+service-version this is a test service diff --git a/tests/_data/serializeResults/xml_complex_spec1.3.xml.bin b/tests/_data/serializeResults/xml_complex_spec1.3.xml.bin index 8e8bc8813..786429019 100644 --- a/tests/_data/serializeResults/xml_complex_spec1.3.xml.bin +++ b/tests/_data/serializeResults/xml_complex_spec1.3.xml.bin @@ -4,16 +4,21 @@ 2032-05-23T13:37:42.000Z - tool vendor + Service service group + sbom-generator-service + 1 + + + tool group other tool - tool vendor + tool group tool name 0.8.15 - f32a26e2a3a8aa338cd77b6e1263c535 - 829c3804401b0727f70f73d4415e162400cbe57b + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed @@ -270,7 +275,7 @@ acme dummy-service - 1.2+service-version + 1.0+service-version this is a test service diff --git a/tests/_data/serializeResults/xml_complex_spec1.4.xml.bin b/tests/_data/serializeResults/xml_complex_spec1.4.xml.bin index 3f36a8aa2..60141a882 100644 --- a/tests/_data/serializeResults/xml_complex_spec1.4.xml.bin +++ b/tests/_data/serializeResults/xml_complex_spec1.4.xml.bin @@ -4,7 +4,18 @@ 2032-05-23T13:37:42.000Z - tool vendor + Service service group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + + tool group other tool @@ -14,12 +25,12 @@ - tool vendor + tool group tool name 0.8.15 - f32a26e2a3a8aa338cd77b6e1263c535 - 829c3804401b0727f70f73d4415e162400cbe57b + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed @@ -270,7 +281,7 @@ acme dummy-service - 1.2+service-version + 1.0+service-version this is a test service @@ -469,6 +480,10 @@ + + g the group + other tool name + v the vendor tool name diff --git a/tests/_data/serializeResults/xml_complex_spec1.5.xml.bin b/tests/_data/serializeResults/xml_complex_spec1.5.xml.bin index cc5fb7f9e..3ad96d85c 100644 --- a/tests/_data/serializeResults/xml_complex_spec1.5.xml.bin +++ b/tests/_data/serializeResults/xml_complex_spec1.5.xml.bin @@ -12,25 +12,40 @@ - - tool vendor - other tool - - - https://cyclonedx.org/tool-center/ - the tools that made this - - - - - tool vendor - tool name - 0.8.15 - - f32a26e2a3a8aa338cd77b6e1263c535 - 829c3804401b0727f70f73d4415e162400cbe57b - - + + + tool group + other tool + + + https://cyclonedx.org/tool-center/ + the tools that made this + + + + + tool group + tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + + + Service service group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + @@ -279,7 +294,7 @@ acme dummy-service - 1.2+service-version + 1.0+service-version this is a test service @@ -478,6 +493,10 @@ + + g the group + other tool name + v the vendor tool name diff --git a/tests/_data/serializeResults/xml_complex_spec1.6.xml.bin b/tests/_data/serializeResults/xml_complex_spec1.6.xml.bin index 216a7a3a2..ec8a02a19 100644 --- a/tests/_data/serializeResults/xml_complex_spec1.6.xml.bin +++ b/tests/_data/serializeResults/xml_complex_spec1.6.xml.bin @@ -12,25 +12,40 @@ - - tool vendor - other tool - - - https://cyclonedx.org/tool-center/ - the tools that made this - - - - - tool vendor - tool name - 0.8.15 - - f32a26e2a3a8aa338cd77b6e1263c535 - 829c3804401b0727f70f73d4415e162400cbe57b - - + + + tool group + other tool + + + https://cyclonedx.org/tool-center/ + the tools that made this + + + + + tool group + tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + + + Service service group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + @@ -279,7 +294,7 @@ acme dummy-service - 1.2+service-version + 1.0+service-version this is a test service @@ -478,6 +493,10 @@ + + g the group + other tool name + v the vendor tool name From 177afd61e770fd3d3af3b4c8cead62f3a512db00 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:18:12 +0100 Subject: [PATCH 11/18] wip Signed-off-by: Jan Kowalleck --- tests/_data/models.js | 8 +- .../json_allTools_spec1.2.json.bin | 52 +++++++++ .../json_allTools_spec1.3.json.bin | 52 +++++++++ .../json_allTools_spec1.4.json.bin | 66 +++++++++++ .../json_allTools_spec1.5.json.bin | 66 +++++++++++ .../json_allTools_spec1.6.json.bin | 66 +++++++++++ .../xml_allTools_spec1.2.xml.bin | 36 ++++++ .../xml_allTools_spec1.3.xml.bin | 36 ++++++ .../xml_allTools_spec1.4.xml.bin | 48 ++++++++ .../xml_allTools_spec1.5.xml.bin | 48 ++++++++ .../xml_allTools_spec1.6.xml.bin | 48 ++++++++ .../Serialize.JsonSerialize.test.js | 87 ++++++++------- .../Serialize.XmlSerialize.test.js | 104 +++++++++--------- 13 files changed, 623 insertions(+), 94 deletions(-) create mode 100644 tests/_data/serializeResults/json_allTools_spec1.2.json.bin create mode 100644 tests/_data/serializeResults/json_allTools_spec1.3.json.bin create mode 100644 tests/_data/serializeResults/json_allTools_spec1.4.json.bin create mode 100644 tests/_data/serializeResults/json_allTools_spec1.5.json.bin create mode 100644 tests/_data/serializeResults/json_allTools_spec1.6.json.bin create mode 100644 tests/_data/serializeResults/xml_allTools_spec1.2.xml.bin create mode 100644 tests/_data/serializeResults/xml_allTools_spec1.3.xml.bin create mode 100644 tests/_data/serializeResults/xml_allTools_spec1.4.xml.bin create mode 100644 tests/_data/serializeResults/xml_allTools_spec1.5.xml.bin create mode 100644 tests/_data/serializeResults/xml_allTools_spec1.6.xml.bin diff --git a/tests/_data/models.js b/tests/_data/models.js index d7c3c4503..50fce1888 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -619,7 +619,7 @@ module.exports.createAllTools = function () { version: 7, serialNumber: `urn:uuid:${bomSerialNumberRaw}`, }) - bom.metadata.tools.components.push( + bom.metadata.tools.components.add( new Models.Component( Enums.ComponentType.Application, 'Component tool name', { @@ -630,7 +630,7 @@ module.exports.createAllTools = function () { [Enums.HashAlgorithm['SHA-1'], '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'] ]) })) - bom.metadata.tools.services.push( + bom.metadata.tools.services.add( new Models.Service('sbom-generator-service', { group: 'Service tool group', version: '1', @@ -643,7 +643,7 @@ module.exports.createAllTools = function () { ]) }) ) - bom.metadata.tools.tools.push( + bom.metadata.tools.tools.add( new Models.Tool({ vendor: 'Tool tool vendor', name: 'Tool tool name', @@ -654,7 +654,7 @@ module.exports.createAllTools = function () { ]) }) ) - bom.metadata.tools.tools.push( + bom.metadata.tools.tools.add( new Models.Tool({ vendor: 'Tool tool vendor', name: 'Tool other tool', diff --git a/tests/_data/serializeResults/json_allTools_spec1.2.json.bin b/tests/_data/serializeResults/json_allTools_spec1.2.json.bin new file mode 100644 index 000000000..2c4a6fd76 --- /dev/null +++ b/tests/_data/serializeResults/json_allTools_spec1.2.json.bin @@ -0,0 +1,52 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "version": 7, + "serialNumber": "urn:uuid:8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e", + "metadata": { + "tools": [ + { + "vendor": "Component tool group", + "name": "Component tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + }, + { + "vendor": "Service tool group", + "name": "sbom-generator-service", + "version": "1" + }, + { + "vendor": "Tool tool vendor", + "name": "Tool other tool" + }, + { + "vendor": "Tool tool vendor", + "name": "Tool tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, + "components": [], + "dependencies": [] +} \ No newline at end of file diff --git a/tests/_data/serializeResults/json_allTools_spec1.3.json.bin b/tests/_data/serializeResults/json_allTools_spec1.3.json.bin new file mode 100644 index 000000000..081c5b374 --- /dev/null +++ b/tests/_data/serializeResults/json_allTools_spec1.3.json.bin @@ -0,0 +1,52 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "version": 7, + "serialNumber": "urn:uuid:8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e", + "metadata": { + "tools": [ + { + "vendor": "Component tool group", + "name": "Component tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + }, + { + "vendor": "Service tool group", + "name": "sbom-generator-service", + "version": "1" + }, + { + "vendor": "Tool tool vendor", + "name": "Tool other tool" + }, + { + "vendor": "Tool tool vendor", + "name": "Tool tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, + "components": [], + "dependencies": [] +} \ No newline at end of file diff --git a/tests/_data/serializeResults/json_allTools_spec1.4.json.bin b/tests/_data/serializeResults/json_allTools_spec1.4.json.bin new file mode 100644 index 000000000..43cbb457a --- /dev/null +++ b/tests/_data/serializeResults/json_allTools_spec1.4.json.bin @@ -0,0 +1,66 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 7, + "serialNumber": "urn:uuid:8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e", + "metadata": { + "tools": [ + { + "vendor": "Component tool group", + "name": "Component tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + }, + { + "vendor": "Service tool group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool other tool", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, + "components": [], + "dependencies": [] +} \ No newline at end of file diff --git a/tests/_data/serializeResults/json_allTools_spec1.5.json.bin b/tests/_data/serializeResults/json_allTools_spec1.5.json.bin new file mode 100644 index 000000000..8cdf548a4 --- /dev/null +++ b/tests/_data/serializeResults/json_allTools_spec1.5.json.bin @@ -0,0 +1,66 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 7, + "serialNumber": "urn:uuid:8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e", + "metadata": { + "tools": [ + { + "vendor": "Component tool group", + "name": "Component tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + }, + { + "vendor": "Service tool group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool other tool", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, + "components": [], + "dependencies": [] +} \ No newline at end of file diff --git a/tests/_data/serializeResults/json_allTools_spec1.6.json.bin b/tests/_data/serializeResults/json_allTools_spec1.6.json.bin new file mode 100644 index 000000000..e81facca6 --- /dev/null +++ b/tests/_data/serializeResults/json_allTools_spec1.6.json.bin @@ -0,0 +1,66 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "version": 7, + "serialNumber": "urn:uuid:8fd9e244-73b6-4cd3-ab3a-a0fefdee5c9e", + "metadata": { + "tools": [ + { + "vendor": "Component tool group", + "name": "Component tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "974e5cc07da6e4536bffd935fd4ddc61" + }, + { + "alg": "SHA-1", + "content": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" + } + ] + }, + { + "vendor": "Service tool group", + "name": "sbom-generator-service", + "version": "1", + "externalReferences": [ + { + "url": "https://example.com/sbom-generator-service/", + "type": "website", + "comment": "the service that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool other tool", + "externalReferences": [ + { + "url": "https://cyclonedx.org/tool-center/", + "type": "website", + "comment": "the tools that made this" + } + ] + }, + { + "vendor": "Tool tool vendor", + "name": "Tool tool name", + "version": "0.8.15", + "hashes": [ + { + "alg": "MD5", + "content": "f32a26e2a3a8aa338cd77b6e1263c535" + }, + { + "alg": "SHA-1", + "content": "829c3804401b0727f70f73d4415e162400cbe57b" + } + ] + } + ] + }, + "components": [], + "dependencies": [] +} \ No newline at end of file diff --git a/tests/_data/serializeResults/xml_allTools_spec1.2.xml.bin b/tests/_data/serializeResults/xml_allTools_spec1.2.xml.bin new file mode 100644 index 000000000..8640d3bd0 --- /dev/null +++ b/tests/_data/serializeResults/xml_allTools_spec1.2.xml.bin @@ -0,0 +1,36 @@ + + + + + + Component tool group + Component tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + Service tool group + sbom-generator-service + 1 + + + Tool tool vendor + Tool other tool + + + Tool tool vendor + Tool tool name + 0.8.15 + + f32a26e2a3a8aa338cd77b6e1263c535 + 829c3804401b0727f70f73d4415e162400cbe57b + + + + + + + \ No newline at end of file diff --git a/tests/_data/serializeResults/xml_allTools_spec1.3.xml.bin b/tests/_data/serializeResults/xml_allTools_spec1.3.xml.bin new file mode 100644 index 000000000..77340ea4a --- /dev/null +++ b/tests/_data/serializeResults/xml_allTools_spec1.3.xml.bin @@ -0,0 +1,36 @@ + + + + + + Component tool group + Component tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + Service tool group + sbom-generator-service + 1 + + + Tool tool vendor + Tool other tool + + + Tool tool vendor + Tool tool name + 0.8.15 + + f32a26e2a3a8aa338cd77b6e1263c535 + 829c3804401b0727f70f73d4415e162400cbe57b + + + + + + + \ No newline at end of file diff --git a/tests/_data/serializeResults/xml_allTools_spec1.4.xml.bin b/tests/_data/serializeResults/xml_allTools_spec1.4.xml.bin new file mode 100644 index 000000000..d0ac8ded5 --- /dev/null +++ b/tests/_data/serializeResults/xml_allTools_spec1.4.xml.bin @@ -0,0 +1,48 @@ + + + + + + Component tool group + Component tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + Service tool group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + + Tool tool vendor + Tool other tool + + + https://cyclonedx.org/tool-center/ + the tools that made this + + + + + Tool tool vendor + Tool tool name + 0.8.15 + + f32a26e2a3a8aa338cd77b6e1263c535 + 829c3804401b0727f70f73d4415e162400cbe57b + + + + + + + \ No newline at end of file diff --git a/tests/_data/serializeResults/xml_allTools_spec1.5.xml.bin b/tests/_data/serializeResults/xml_allTools_spec1.5.xml.bin new file mode 100644 index 000000000..f3c90ac9e --- /dev/null +++ b/tests/_data/serializeResults/xml_allTools_spec1.5.xml.bin @@ -0,0 +1,48 @@ + + + + + + Component tool group + Component tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + Service tool group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + + Tool tool vendor + Tool other tool + + + https://cyclonedx.org/tool-center/ + the tools that made this + + + + + Tool tool vendor + Tool tool name + 0.8.15 + + f32a26e2a3a8aa338cd77b6e1263c535 + 829c3804401b0727f70f73d4415e162400cbe57b + + + + + + + \ No newline at end of file diff --git a/tests/_data/serializeResults/xml_allTools_spec1.6.xml.bin b/tests/_data/serializeResults/xml_allTools_spec1.6.xml.bin new file mode 100644 index 000000000..7b36d67a8 --- /dev/null +++ b/tests/_data/serializeResults/xml_allTools_spec1.6.xml.bin @@ -0,0 +1,48 @@ + + + + + + Component tool group + Component tool name + 0.8.15 + + 974e5cc07da6e4536bffd935fd4ddc61 + 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + + + + Service tool group + sbom-generator-service + 1 + + + https://example.com/sbom-generator-service/ + the service that made this + + + + + Tool tool vendor + Tool other tool + + + https://cyclonedx.org/tool-center/ + the tools that made this + + + + + Tool tool vendor + Tool tool name + 0.8.15 + + f32a26e2a3a8aa338cd77b6e1263c535 + 829c3804401b0727f70f73d4415e162400cbe57b + + + + + + + \ No newline at end of file diff --git a/tests/integration/Serialize.JsonSerialize.test.js b/tests/integration/Serialize.JsonSerialize.test.js index 2678a76e0..e49f0a2af 100644 --- a/tests/integration/Serialize.JsonSerialize.test.js +++ b/tests/integration/Serialize.JsonSerialize.test.js @@ -20,7 +20,7 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const assert = require('assert') const { describe, beforeEach, afterEach, it } = require('mocha') -const { createComplexStructure } = require('../_data/models') +const { createComplexStructure, createAllTools } = require('../_data/models') const { loadSerializeResult, writeSerializeResult } = require('../_data/serialize') const { @@ -39,52 +39,57 @@ const { describe('Serialize.JsonSerialize', function () { this.timeout(60000); - [ - Spec.Spec1dot6, - Spec.Spec1dot5, - Spec.Spec1dot4, - Spec.Spec1dot3, - Spec.Spec1dot2 - ].forEach(spec => describe(`complex with spec v${spec.version}`, () => { - const normalizerFactory = new JsonNormalizeFactory(spec) - - beforeEach(function () { - this.bom = createComplexStructure() - }) + Object.entries({ + complex: createComplexStructure, + allTools: createAllTools + }).forEach(([fixtureName, bomFixture]) => describe(`from fixture ${fixtureName}`, () => { + [ + Spec.Spec1dot6, + Spec.Spec1dot5, + Spec.Spec1dot4, + Spec.Spec1dot3, + Spec.Spec1dot2 + ].forEach(spec => describe(`with spec v${spec.version}`, () => { + const normalizerFactory = new JsonNormalizeFactory(spec) + + beforeEach(function () { + this.bom = bomFixture() + }) - afterEach(function () { - delete this.bom - }) + afterEach(function () { + delete this.bom + }) - it('serialize', async function () { - const serializer = new JsonSerializer(normalizerFactory) + it('serialize', async function () { + const serializer = new JsonSerializer(normalizerFactory) + + const serialized = serializer.serialize( + this.bom, { + sortLists: true, + space: 4 + }) - const serialized = serializer.serialize( - this.bom, { - sortLists: true, - space: 4 - }) - - const validator = new JsonStrictValidator(spec.version) - try { - const validationError = await validator.validate(serialized) - assert.strictEqual(validationError, null) - } catch (err) { - if (!(err instanceof MissingOptionalDependencyError)) { - // unexpected error - assert.fail(err) + const validator = new JsonStrictValidator(spec.version) + try { + const validationError = await validator.validate(serialized) + assert.strictEqual(validationError, null) + } catch (err) { + if (!(err instanceof MissingOptionalDependencyError)) { + // unexpected error + assert.fail(err) + } } - } - if (process.env.CJL_TEST_UPDATE_SNAPSHOTS) { - writeSerializeResult(serialized, 'json_complex', spec.version, 'json') - } - assert.strictEqual( - serialized, - loadSerializeResult('json_complex', spec.version, 'json')) - }) + if (process.env.CJL_TEST_UPDATE_SNAPSHOTS) { + writeSerializeResult(serialized, `json_${fixtureName}`, spec.version, 'json') + } + assert.strictEqual( + serialized, + loadSerializeResult(`json_${fixtureName}`, spec.version, 'json')) + }) - // TODO add more tests + // TODO add more tests + })) })) describe('make bom-refs unique', () => { diff --git a/tests/integration/Serialize.XmlSerialize.test.js b/tests/integration/Serialize.XmlSerialize.test.js index bc8964d28..0b1384346 100644 --- a/tests/integration/Serialize.XmlSerialize.test.js +++ b/tests/integration/Serialize.XmlSerialize.test.js @@ -20,7 +20,7 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const assert = require('assert') const { describe, beforeEach, afterEach, it } = require('mocha') -const { createComplexStructure } = require('../_data/models') +const { createComplexStructure, createAllTools } = require('../_data/models') const { loadSerializeResult, writeSerializeResult } = require('../_data/serialize') const { @@ -40,62 +40,68 @@ describe('Serialize.XmlSerialize', function () { this.timeout(60000); - [ - Spec.Spec1dot6, - Spec.Spec1dot5, - Spec.Spec1dot4, - Spec.Spec1dot3, - Spec.Spec1dot2 - ].forEach(spec => describe(`complex with spec v${spec.version}`, () => { - const normalizerFactory = new XmlNormalizeFactory(spec) - - beforeEach(function () { - this.bom = createComplexStructure() - }) - - afterEach(function () { - delete this.bom - }) + Object.entries({ + complex: createComplexStructure, + allTools: createAllTools + }).forEach(([fixtureName, bomFixture]) => describe(`from fixture ${fixtureName}`, () => { + [ + Spec.Spec1dot6, + Spec.Spec1dot5, + Spec.Spec1dot4, + Spec.Spec1dot3, + Spec.Spec1dot2 + ].forEach(spec => describe(`with spec v${spec.version}`, () => { + const normalizerFactory = new XmlNormalizeFactory(spec) + + beforeEach(function () { + this.bom = bomFixture() + }) - if (expectMissingDepError) { - it('throws MissingOptionalDependencyError', function () { - const serializer = new XmlSerializer(normalizerFactory) - assert.throws( - () => { serializer.serialize(this.bom, {}) }, - (err) => err instanceof MissingOptionalDependencyError - ) + afterEach(function () { + delete this.bom }) - return // skip other tests - } - it('serialize', async function () { - const serializer = new XmlSerializer(normalizerFactory) - const serialized = await serializer.serialize( - this.bom, { - sortLists: true, - space: 4 + if (expectMissingDepError) { + it('throws MissingOptionalDependencyError', function () { + const serializer = new XmlSerializer(normalizerFactory) + assert.throws( + () => { serializer.serialize(this.bom, {}) }, + (err) => err instanceof MissingOptionalDependencyError + ) }) + return // skip other tests + } - const validator = new Validation.XmlValidator(spec.version) - try { - const validationError = await validator.validate(serialized) - assert.strictEqual(validationError, null) - } catch (err) { - if (!(err instanceof Validation.MissingOptionalDependencyError)) { - // unexpected error - throw err + it('serialize', async function () { + const serializer = new XmlSerializer(normalizerFactory) + const serialized = await serializer.serialize( + this.bom, { + sortLists: true, + space: 4 + }) + + const validator = new Validation.XmlValidator(spec.version) + try { + const validationError = await validator.validate(serialized) + assert.strictEqual(validationError, null) + } catch (err) { + if (!(err instanceof Validation.MissingOptionalDependencyError)) { + // unexpected error + throw err + } } - } - if (process.env.CJL_TEST_UPDATE_SNAPSHOTS) { - writeSerializeResult(serialized, 'xml_complex', spec.version, 'xml') - } - assert.strictEqual( - serialized, - loadSerializeResult('xml_complex', spec.version, 'xml')) - }) + if (process.env.CJL_TEST_UPDATE_SNAPSHOTS) { + writeSerializeResult(serialized, `xml_${fixtureName}`, spec.version, 'xml') + } + assert.strictEqual( + serialized, + loadSerializeResult(`xml_${fixtureName}`, spec.version, 'xml')) + }) + + // TODO add more tests + })) - // TODO add more tests })) describe('make bom-refs unique', () => { From 57f92bb114bb4a723d10ee932ce32797d3771523 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:34:20 +0100 Subject: [PATCH 12/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a7a949586..2d60febf2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,11 +7,14 @@ All notable changes to this project will be documented in this file. * BREAKING changes - * ... + * Property `Models.Bom.tools` is an instance of `Models.Tools` now ([#1152] via [#1163]) + Before, it was an instance of `Models.ToolRepository`. * Added - * ... + * Class `Models.Tools` ([#1152] via [#1163]) + * Static function `Models.Tool.fromComponent()` (via [#1163]) + * Static function `Models.Tool.fromService()` (via [#1163]) * Changed - * ... + * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) [#1152]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1152 [#1163]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1163 From 90c276de63b6fa77e95f609e735e67a3cad2e183 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:37:20 +0100 Subject: [PATCH 13/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 2d60febf2..06dbe6452 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,9 +13,11 @@ All notable changes to this project will be documented in this file. * Class `Models.Tools` ([#1152] via [#1163]) * Static function `Models.Tool.fromComponent()` (via [#1163]) * Static function `Models.Tool.fromService()` (via [#1163]) + * New data models and serialization/normalization for `Models.Tools` ([#1152] via [#1163]) * Changed * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) + [#1152]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1152 [#1163]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1163 From 165941ae34533330eaed5ba0bdead258cec9fb24 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:37:48 +0100 Subject: [PATCH 14/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 06dbe6452..8af4343eb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -17,7 +17,6 @@ All notable changes to this project will be documented in this file. * Changed * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) - [#1152]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1152 [#1163]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1163 From 99a39e70301ee7c4bee70adbe481bb1e534c0602 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:38:33 +0100 Subject: [PATCH 15/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8af4343eb..f7caf6361 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. * Class `Models.Tools` ([#1152] via [#1163]) * Static function `Models.Tool.fromComponent()` (via [#1163]) * Static function `Models.Tool.fromService()` (via [#1163]) - * New data models and serialization/normalization for `Models.Tools` ([#1152] via [#1163]) + * New serialization/normalization for `Models.Tools` ([#1152] via [#1163]) * Changed * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) From 6f7b917ffaa718f239b12965343f500239b22906 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:39:34 +0100 Subject: [PATCH 16/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f7caf6361..e6fe589eb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,15 +7,15 @@ All notable changes to this project will be documented in this file. * BREAKING changes - * Property `Models.Bom.tools` is an instance of `Models.Tools` now ([#1152] via [#1163]) - Before, it was an instance of `Models.ToolRepository`. + * Property `Models.Bom.tools` is an instance of `Models.Tools` now ([#1152] via [#1163]) + Before, it was an instance of `Models.ToolRepository`. * Added - * Class `Models.Tools` ([#1152] via [#1163]) - * Static function `Models.Tool.fromComponent()` (via [#1163]) - * Static function `Models.Tool.fromService()` (via [#1163]) - * New serialization/normalization for `Models.Tools` ([#1152] via [#1163]) + * Class `Models.Tools` ([#1152] via [#1163]) + * Static function `Models.Tool.fromComponent()` (via [#1163]) + * Static function `Models.Tool.fromService()` (via [#1163]) + * New serialization/normalization for `Models.Tools` ([#1152] via [#1163]) * Changed - * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) + * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) [#1152]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1152 [#1163]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1163 From 251cb3b567a68e52237090769b75acd4c553de95 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 13 Nov 2024 10:40:12 +0100 Subject: [PATCH 17/18] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e6fe589eb..c81cfa57d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -10,9 +10,9 @@ All notable changes to this project will be documented in this file. * Property `Models.Bom.tools` is an instance of `Models.Tools` now ([#1152] via [#1163]) Before, it was an instance of `Models.ToolRepository`. * Added - * Class `Models.Tools` ([#1152] via [#1163]) * Static function `Models.Tool.fromComponent()` (via [#1163]) * Static function `Models.Tool.fromService()` (via [#1163]) + * New class `Models.Tools` ([#1152] via [#1163]) * New serialization/normalization for `Models.Tools` ([#1152] via [#1163]) * Changed * Serializers and `Bom`-Normalizers will take changed `Models.Bom.tools` into account ([#1152] via [#1163]) From cfb5d5a84942412c0b8b0e635b5b455657804ffe Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Sat, 16 Nov 2024 14:08:07 +0100 Subject: [PATCH 18/18] cs Signed-off-by: Jan Kowalleck --- src/serialize/xml/normalize.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/serialize/xml/normalize.ts b/src/serialize/xml/normalize.ts index 58e1f4287..733518056 100644 --- a/src/serialize/xml/normalize.ts +++ b/src/serialize/xml/normalize.ts @@ -373,7 +373,7 @@ export class ToolNormalizer extends BaseXmlNormalizer { export class ToolsNormalizer extends BaseXmlNormalizer { normalize (data: Models.Tools, options: NormalizerOptions, elementName: string): SimpleXml.Element { - let children: SimpleXml.Element[] + let children: SimpleXml.Element[] = [] if (data.tools.size > 0 || !this._factory.spec.supportsToolsComponentsServices) { children = this._factory.makeForTool().normalizeIterable( new ToolRepository(chainI( @@ -382,7 +382,6 @@ export class ToolsNormalizer extends BaseXmlNormalizer { data.tools, )), options, 'tool') } else { - children = [] if (data.components.size > 0) { children.push({ type: 'element',