Skip to content

Commit e183d0c

Browse files
committed
fix: BaseSerializer discriminate nested components
fixes #175 Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 3dbf4cb commit e183d0c

File tree

3 files changed

+114
-4
lines changed

3 files changed

+114
-4
lines changed

src/serialize/baseSerializer.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0
1717
Copyright (c) OWASP Foundation. All Rights Reserved.
1818
*/
1919

20-
import { Bom, BomRef } from '../models'
20+
import { Component, Bom, BomRef } from '../models'
2121
import { BomRefDiscriminator } from './bomRefDiscriminator'
2222
import { NormalizerOptions, Serializer, SerializerOptions } from './types'
2323

@@ -38,12 +38,19 @@ export abstract class BaseSerializer<NormalizedBom> implements Serializer {
3838

3939
#getAllBomRefs (bom: Bom): Iterable<BomRef> {
4040
const bomRefs = new Set<BomRef>()
41+
function iterComponents (cs: Iterable<Component>): void {
42+
for (const { bomRef, components } of cs) {
43+
bomRefs.add(bomRef)
44+
iterComponents(components)
45+
}
46+
}
47+
4148
if (bom.metadata.component !== undefined) {
4249
bomRefs.add(bom.metadata.component.bomRef)
50+
iterComponents(bom.metadata.component.components)
4351
}
44-
for (const { bomRef } of bom.components) {
45-
bomRefs.add(bomRef)
46-
}
52+
iterComponents(bom.components)
53+
4754
return bomRefs.values()
4855
}
4956

tests/integration/Serialize.JsonSerialize.test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const { createComplexStructure } = require('../_data/models')
2525
const { loadSerializeResult, writeSerializeResult } = require('../_data/serialize')
2626

2727
const {
28+
Models, Enums,
2829
Serialize: {
2930
JSON: { Normalize: { Factory: JsonNormalizeFactory } },
3031
JsonSerializer
@@ -52,6 +53,7 @@ describe('Serialize.JsonSerialize', function () {
5253

5354
it('serialize', function () {
5455
const serializer = new JsonSerializer(normalizerFactory)
56+
5557
const serialized = serializer.serialize(
5658
this.bom, {
5759
sortLists: true,
@@ -69,4 +71,56 @@ describe('Serialize.JsonSerialize', function () {
6971

7072
// TODO add more tests
7173
}))
74+
75+
describe('make bom-refs unique', () => {
76+
it('as expected', () => {
77+
const bom = new Models.Bom({
78+
metadata: new Models.Metadata({
79+
component: new Models.Component(Enums.ComponentType.Library, 'root', {
80+
bomRef: 'testing',
81+
components: new Models.ComponentRepository([
82+
new Models.Component(Enums.ComponentType.Library, 'c2', {
83+
bomRef: 'testing'
84+
})
85+
])
86+
})
87+
}),
88+
components: new Models.ComponentRepository([
89+
new Models.Component(Enums.ComponentType.Library, 'c1', {
90+
bomRef: 'testing',
91+
components: new Models.ComponentRepository([
92+
new Models.Component(Enums.ComponentType.Library, 'c2', {
93+
bomRef: 'testing'
94+
})
95+
])
96+
})
97+
])
98+
})
99+
const knownBomRefs = [
100+
bom.metadata.component.bomRef,
101+
[...bom.metadata.component.components][0].bomRef,
102+
[...bom.components.values()][0].bomRef,
103+
[...[...bom.components][0].components][0].bomRef
104+
]
105+
const normalizedBomRefs = new Set(/* will be filled on call */)
106+
const bomNormalizer = {
107+
normalize: (bom) => {
108+
normalizedBomRefs.add(bom.metadata.component.bomRef.value)
109+
normalizedBomRefs.add([...bom.metadata.component.components][0].bomRef.value)
110+
normalizedBomRefs.add([...bom.components.values()][0].bomRef.value)
111+
normalizedBomRefs.add([...[...bom.components][0].components][0].bomRef.value)
112+
return {}
113+
}
114+
}
115+
const normalizerFactory = { makeForBom: () => bomNormalizer, spec: Spec1dot4 }
116+
const serializer = new JsonSerializer(normalizerFactory)
117+
118+
serializer.serialize(bom)
119+
120+
assert.strictEqual(normalizedBomRefs.has('testing'), true)
121+
assert.strictEqual(normalizedBomRefs.size, 4, 'not every value was unique')
122+
// everything back to before - all have
123+
knownBomRefs.forEach(({ value }) => assert.strictEqual(value, 'testing'))
124+
})
125+
})
72126
})

tests/integration/Serialize.XmlSerialize.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const { createComplexStructure } = require('../_data/models')
2525
const { loadSerializeResult, writeSerializeResult } = require('../_data/serialize')
2626

2727
const {
28+
Models, Enums,
2829
Serialize: {
2930
XML: { Normalize: { Factory: XmlNormalizeFactory } },
3031
XmlSerializer
@@ -52,6 +53,7 @@ describe('Serialize.XmlSerialize', function () {
5253

5354
it('serialize', function () {
5455
const serializer = new XmlSerializer(normalizerFactory)
56+
5557
const serialized = serializer.serialize(
5658
this.bom, {
5759
sortLists: true,
@@ -69,4 +71,51 @@ describe('Serialize.XmlSerialize', function () {
6971

7072
// TODO add more tests
7173
}))
74+
75+
describe('make bom-refs unique', () => {
76+
it('as expected', () => {
77+
const bom = new Models.Bom({
78+
metadata: new Models.Metadata({
79+
component: new Models.Component(Enums.ComponentType.Library, 'root', {
80+
bomRef: 'testing'
81+
})
82+
}),
83+
components: new Models.ComponentRepository([
84+
new Models.Component(Enums.ComponentType.Library, 'c1', {
85+
bomRef: 'testing',
86+
components: new Models.ComponentRepository([
87+
new Models.Component(Enums.ComponentType.Library, 'c2', {
88+
bomRef: 'testing'
89+
})
90+
])
91+
})
92+
])
93+
})
94+
const knownBomRefs = [
95+
bom.metadata.component.bomRef,
96+
[...bom.metadata.component.components][0].bomRef,
97+
[...bom.components.values()][0].bomRef,
98+
[...[...bom.components][0].components][0].bomRef
99+
]
100+
const normalizedBomRefs = new Set(/* will be filled on call */)
101+
const bomNormalizer = {
102+
normalize: (bom) => {
103+
normalizedBomRefs.add(bom.metadata.component.bomRef.value)
104+
normalizedBomRefs.add([...bom.metadata.component.components][0].bomRef.value)
105+
normalizedBomRefs.add([...bom.components.values()][0].bomRef.value)
106+
normalizedBomRefs.add([...[...bom.components][0].components][0].bomRef.value)
107+
return { type: 'element', name: 'dummy' }
108+
}
109+
}
110+
const normalizerFactory = { makeForBom: () => bomNormalizer, spec: Spec1dot4 }
111+
const serializer = new XmlSerializer(normalizerFactory)
112+
113+
serializer.serialize(bom)
114+
115+
assert.strictEqual(normalizedBomRefs.has('testing'), true)
116+
assert.strictEqual(normalizedBomRefs.size, 4, 'not every value was unique')
117+
// everything back to before - all have
118+
knownBomRefs.forEach(({ value }) => assert.strictEqual(value, 'testing'))
119+
})
120+
})
72121
})

0 commit comments

Comments
 (0)