Skip to content

Commit ca9bd8b

Browse files
authored
feat: add ExternalReferences[].hashes (#985)
fixes #984 --------- Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 557dd91 commit ca9bd8b

24 files changed

+338
-4
lines changed

HISTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ All notable changes to this project will be documented in this file.
44

55
## unreleased
66

7+
* Added
8+
* Class `Models.ExternalReference` got a new property `hashes` ([#984] via [#985])
9+
* Serializers and `ExternalReference`-Normalizers will take `Models.ExternalReference.hashes` into account ([#984] via [#985])
10+
711
* Build
812
* Use _Webpack_ `v5.89.0` now, was `v5.88.2` (via [#979])
913
* Use _ts-loader_ `v9.5.0` now, was `v9.4.4` (via [#977])
1014

1115
[#977]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/977
1216
[#979]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/979
17+
[#984]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/984
18+
[#985]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/985
1319

1420
## 6.0.0 -- 2023-08-26
1521

src/models/externalReference.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,23 @@ import type { Comparable } from '../_helpers/sortable'
2121
import { SortableComparables } from '../_helpers/sortable'
2222
import type { ExternalReferenceType } from '../enums'
2323
import type { BomLink } from './bomLink'
24+
import { HashDictionary } from './hash'
2425

2526
export interface OptionalExternalReferenceProperties {
27+
hashes?: ExternalReference['hashes']
2628
comment?: ExternalReference['comment']
2729
}
2830

2931
export class ExternalReference implements Comparable<ExternalReference> {
3032
url: URL | BomLink | string
3133
type: ExternalReferenceType
34+
hashes: HashDictionary
3235
comment?: string
3336

3437
constructor (url: ExternalReference['url'], type: ExternalReference['type'], op: OptionalExternalReferenceProperties = {}) {
3538
this.url = url
3639
this.type = type
40+
this.hashes = op.hashes ?? new HashDictionary()
3741
this.comment = op.comment
3842
}
3943

src/serialize/json/normalize.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ export class ExternalReferenceNormalizer extends BaseJsonNormalizer<Models.Exter
516516
? {
517517
url: data.url.toString(),
518518
type: data.type,
519+
hashes: this._factory.spec.supportsExternalReferenceHashes && data.hashes.size > 0
520+
? this._factory.makeForHash().normalizeIterable(data.hashes, options)
521+
: undefined,
519522
comment: data.comment || undefined
520523
}
521524
: undefined

src/serialize/json/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ export namespace Normalized {
202202
export interface ExternalReference {
203203
url: JsonSchema.IriReference | BomLink
204204
type: Enums.ExternalReferenceType
205+
hashes?: Hash[]
205206
comment?: string
206207
}
207208

src/serialize/xml/normalize.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,13 @@ export class SWIDNormalizer extends BaseXmlNormalizer<Models.SWID> {
642642
export class ExternalReferenceNormalizer extends BaseXmlNormalizer<Models.ExternalReference> {
643643
normalize (data: Models.ExternalReference, options: NormalizerOptions, elementName: string): SimpleXml.Element | undefined {
644644
const url = data.url.toString()
645+
const hashes: SimpleXml.Element | undefined = this._factory.spec.supportsExternalReferenceHashes && data.hashes.size > 0
646+
? {
647+
type: 'element',
648+
name: 'hashes',
649+
children: this._factory.makeForHash().normalizeIterable(data.hashes, options, 'hash')
650+
}
651+
: undefined
645652
return this._factory.spec.supportsExternalReferenceType(data.type) &&
646653
XmlSchema.isAnyURI(url)
647654
? {
@@ -652,7 +659,8 @@ export class ExternalReferenceNormalizer extends BaseXmlNormalizer<Models.Extern
652659
},
653660
children: [
654661
makeTextElement(url, 'url'),
655-
makeOptionalTextElement(data.comment, 'comment')
662+
makeOptionalTextElement(data.comment, 'comment'),
663+
hashes
656664
].filter(isNotUndefined)
657665
}
658666
: undefined

src/spec/_protocol.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export interface _SpecProtocol {
4343
supportsVulnerabilityRatingMethod: (rm: Vulnerability.RatingMethod | any) => boolean
4444
supportsComponentEvidence: boolean
4545
supportsMetadataLifecycles: boolean
46+
supportsExternalReferenceHashes: boolean
4647
}
4748

4849
/**
@@ -67,6 +68,7 @@ export class _Spec implements _SpecProtocol {
6768
readonly #supportsVulnerabilities: boolean
6869
readonly #supportsComponentEvidence: boolean
6970
readonly #supportsMetadataLifecycles: boolean
71+
readonly #supportsExternalReferenceHashes: boolean
7072

7173
constructor (
7274
version: Version,
@@ -82,7 +84,8 @@ export class _Spec implements _SpecProtocol {
8284
supportsVulnerabilities: boolean,
8385
vulnerabilityRatingMethods: Iterable<Vulnerability.RatingMethod>,
8486
supportsComponentEvidence: boolean,
85-
supportsMetadataLifecycles: boolean
87+
supportsMetadataLifecycles: boolean,
88+
supportsExternalReferenceHashes: boolean
8689
) {
8790
this.#version = version
8891
this.#formats = new Set(formats)
@@ -98,6 +101,7 @@ export class _Spec implements _SpecProtocol {
98101
this.#vulnerabilityRatingMethods = new Set(vulnerabilityRatingMethods)
99102
this.#supportsComponentEvidence = supportsComponentEvidence
100103
this.#supportsMetadataLifecycles = supportsMetadataLifecycles
104+
this.#supportsExternalReferenceHashes = supportsExternalReferenceHashes
101105
}
102106

103107
get version (): Version {
@@ -157,4 +161,8 @@ export class _Spec implements _SpecProtocol {
157161
get supportsMetadataLifecycles (): boolean {
158162
return this.#supportsMetadataLifecycles
159163
}
164+
165+
get supportsExternalReferenceHashes (): boolean {
166+
return this.#supportsExternalReferenceHashes
167+
}
160168
}

src/spec/consts.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export const Spec1dot2: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
7878
false,
7979
[],
8080
false,
81+
false,
8182
false
8283
))
8384

@@ -137,7 +138,8 @@ export const Spec1dot3: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
137138
false,
138139
[],
139140
true,
140-
false
141+
false,
142+
true
141143
))
142144

143145
/** Specification v1.4 */
@@ -203,7 +205,8 @@ export const Spec1dot4: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
203205
Vulnerability.RatingMethod.Other
204206
],
205207
true,
206-
false
208+
false,
209+
true
207210
))
208211

209212
/** Specification v1.5 */
@@ -298,6 +301,7 @@ export const Spec1dot5: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
298301
Vulnerability.RatingMethod.Other
299302
],
300303
true,
304+
true,
301305
true
302306
))
303307

tests/_data/models.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ module.exports.createComplexStructure = function () {
107107
new URL('https://localhost/acme/support'),
108108
Enums.ExternalReferenceType.Support
109109
))
110+
component.externalReferences.add(new Models.ExternalReference(
111+
'https://localhost/download/acme.tar.gz',
112+
Enums.ExternalReferenceType.Distribution,
113+
{
114+
hashes: new Models.HashDictionary([
115+
[Enums.HashAlgorithm.MD5, '327b6f07435811239bc47e1544353273'],
116+
[Enums.HashAlgorithm['SHA-1'], 'd53a205a336e07cf9eac45471b3870f9489288ec'],
117+
[Enums.HashAlgorithm['SHA-256'], '1f2ec52b774368781bed1d1fb140a92e0eb6348090619c9291f9a5a3c8e8d151']
118+
])
119+
}
120+
))
110121
component.externalReferences.add(new Models.ExternalReference(
111122
'git+https://localhost/acme.git',
112123
Enums.ExternalReferenceType.VCS

tests/_data/normalizeResults/json_sortedLists_spec1.2.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/_data/normalizeResults/json_sortedLists_spec1.3.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)