@cyclonedx/cyclonedx-library 1.3.0 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +3 -2
  2. package/dist.node/builders/fromNodePackageJson.node.js.map +1 -1
  3. package/dist.node/factories/license.js +2 -2
  4. package/dist.node/factories/license.js.map +1 -1
  5. package/dist.node/factories/packageUrl.js.map +1 -1
  6. package/dist.node/models/attachment.js.map +1 -1
  7. package/dist.node/models/bomRef.js +1 -1
  8. package/dist.node/models/bomRef.js.map +1 -1
  9. package/dist.node/models/externalReference.js.map +1 -1
  10. package/dist.node/models/license.js.map +1 -1
  11. package/dist.node/models/swid.js.map +1 -1
  12. package/dist.node/serialize/baseSerializer.js +8 -3
  13. package/dist.node/serialize/baseSerializer.js.map +1 -1
  14. package/dist.node/serialize/json/normalize.js +3 -3
  15. package/dist.node/serialize/json/normalize.js.map +1 -1
  16. package/dist.node/serialize/jsonSerializer.js.map +1 -1
  17. package/dist.node/serialize/xml/normalize.js +8 -8
  18. package/dist.node/serialize/xml/normalize.js.map +1 -1
  19. package/dist.node/serialize/xml/types.js +25 -3
  20. package/dist.node/serialize/xml/types.js.map +1 -1
  21. package/dist.node/serialize/xmlBaseSerializer.js.map +1 -1
  22. package/dist.node/spec.js +11 -6
  23. package/dist.node/spec.js.map +1 -1
  24. package/dist.web/lib.dev.js +58 -26
  25. package/dist.web/lib.dev.js.map +1 -1
  26. package/dist.web/lib.js +1 -1
  27. package/package.json +1 -1
  28. package/res/README.md +1 -1
  29. package/src/builders/fromNodePackageJson.node.ts +3 -3
  30. package/src/factories/license.ts +2 -2
  31. package/src/factories/packageUrl.ts +1 -1
  32. package/src/models/attachment.ts +1 -1
  33. package/src/models/bom.ts +1 -1
  34. package/src/models/bomRef.ts +2 -2
  35. package/src/models/externalReference.ts +1 -1
  36. package/src/models/license.ts +3 -3
  37. package/src/models/swid.ts +1 -1
  38. package/src/serialize/baseSerializer.ts +11 -4
  39. package/src/serialize/json/normalize.ts +11 -8
  40. package/src/serialize/jsonSerializer.ts +1 -1
  41. package/src/serialize/xml/normalize.ts +16 -13
  42. package/src/serialize/xml/types.ts +36 -5
  43. package/src/serialize/xmlBaseSerializer.ts +1 -1
  44. package/src/spec.ts +28 -22
@@ -28,7 +28,7 @@ import { treeIterator } from '../../helpers/tree'
28
28
  export class Factory {
29
29
  readonly #spec: Spec
30
30
 
31
- constructor (spec: Spec) {
31
+ constructor (spec: Factory['spec']) {
32
32
  this.#spec = spec
33
33
  }
34
34
 
@@ -104,7 +104,7 @@ interface Normalizer {
104
104
  abstract class Base implements Normalizer {
105
105
  protected readonly _factory: Factory
106
106
 
107
- constructor (factory: Factory) {
107
+ constructor (factory: Base['factory']) {
108
108
  this._factory = factory
109
109
  }
110
110
 
@@ -260,7 +260,8 @@ export class HashNormalizer extends Base {
260
260
  options.sortLists ?? false
261
261
  ? data.sorted()
262
262
  : Array.from(data)
263
- ).map(h => this.normalize(h, options, elementName)
263
+ ).map(
264
+ h => this.normalize(h, options, elementName)
264
265
  ).filter(isNotUndefined)
265
266
  }
266
267
  }
@@ -344,18 +345,18 @@ export class ComponentNormalizer extends Base {
344
345
  .normalizeRepository(data.externalReferences, options, 'reference')
345
346
  }
346
347
  : undefined
347
- const components: SimpleXml.Element | undefined = data.components.size > 0
348
+ const properties: SimpleXml.Element | undefined = spec.supportsProperties(data) && data.properties.size > 0
348
349
  ? {
349
350
  type: 'element',
350
- name: 'components',
351
- children: this.normalizeRepository(data.components, options, 'component')
351
+ name: 'properties',
352
+ children: this._factory.makeForProperty().normalizeRepository(data.properties, options, 'property')
352
353
  }
353
354
  : undefined
354
- const properties: SimpleXml.Element | undefined = data.properties.size > 0
355
+ const components: SimpleXml.Element | undefined = data.components.size > 0
355
356
  ? {
356
357
  type: 'element',
357
- name: 'properties',
358
- children: this._factory.makeForProperty().normalizeRepository(data.properties, options, 'property')
358
+ name: 'components',
359
+ children: this.normalizeRepository(data.components, options, 'component')
359
360
  }
360
361
  : undefined
361
362
  return {
@@ -381,8 +382,8 @@ export class ComponentNormalizer extends Base {
381
382
  makeOptionalTextElement(data.purl, 'purl'),
382
383
  swid,
383
384
  extRefs,
384
- components,
385
- properties
385
+ properties,
386
+ components
386
387
  ].filter(isNotUndefined)
387
388
  }
388
389
  }
@@ -392,7 +393,8 @@ export class ComponentNormalizer extends Base {
392
393
  options.sortLists ?? false
393
394
  ? data.sorted()
394
395
  : Array.from(data)
395
- ).map(c => this.normalize(c, options, elementName)
396
+ ).map(
397
+ c => this.normalize(c, options, elementName)
396
398
  ).filter(isNotUndefined)
397
399
  }
398
400
  }
@@ -510,7 +512,8 @@ export class ExternalReferenceNormalizer extends Base {
510
512
  options.sortLists ?? false
511
513
  ? data.sorted()
512
514
  : Array.from(data)
513
- ).map(r => this.normalize(r, options, elementName)
515
+ ).map(
516
+ r => this.normalize(r, options, elementName)
514
517
  ).filter(isNotUndefined)
515
518
  }
516
519
  }
@@ -20,6 +20,8 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
20
20
  // eslint-disable-next-line @typescript-eslint/no-namespace
21
21
  export namespace XmlSchema {
22
22
 
23
+ const _anyUriSchemePattern = /^[a-z][a-z0-9+\-.]*$/i
24
+
23
25
  /**
24
26
  * @see isAnyURI
25
27
  */
@@ -28,13 +30,42 @@ export namespace XmlSchema {
28
30
  * Test whether format is XML::anyURI - best-effort.
29
31
  *
30
32
  * @see {@link http://www.w3.org/TR/xmlschema-2/#anyURI}
31
- * @see {@link http://www.datypic.com/sc/xsd/t-xsd_anyURI.html}
33
+ * @see {@link https://www.w3.org/2011/04/XMLSchema/TypeLibrary-URI-RFC3986.xsd}
34
+ * @see {@link https://www.w3.org/2011/04/XMLSchema/TypeLibrary-IRI-RFC3987.xsd}
32
35
  */
33
36
  export function isAnyURI (value: AnyURI | any): value is AnyURI {
34
- return typeof value === 'string' &&
35
- value.length > 0 &&
36
- Array.from(value).filter(c => c === '#').length <= 1
37
- // TODO add more validation according to spec
37
+ if (typeof value !== 'string') {
38
+ // not a string
39
+ return false
40
+ }
41
+ if (value.length === 0) {
42
+ // empty string
43
+ return false
44
+ }
45
+
46
+ const fragmentPos = value.indexOf('#')
47
+ let beforeFragment: string
48
+ if (fragmentPos >= 0) {
49
+ if (value.includes('#', fragmentPos + 1)) {
50
+ // has a second fragment marker
51
+ return false
52
+ }
53
+ beforeFragment = value.slice(undefined, fragmentPos)
54
+ } else {
55
+ beforeFragment = value
56
+ }
57
+
58
+ const schemePos = beforeFragment.indexOf(':')
59
+ if (schemePos >= 0) {
60
+ if (!_anyUriSchemePattern.test(beforeFragment.slice(undefined, schemePos))) {
61
+ // invalid schema
62
+ return false
63
+ }
64
+ }
65
+
66
+ // @TODO add more validation according to spec
67
+
68
+ return true
38
69
  }
39
70
 
40
71
  }
@@ -33,7 +33,7 @@ export abstract class XmlBaseSerializer extends BaseSerializer<SimpleXml.Element
33
33
  /**
34
34
  * @throws {UnsupportedFormatError} if {@see normalizerFactory.spec} does not support {@see Format.XML}.
35
35
  */
36
- constructor (normalizerFactory: NormalizerFactory) {
36
+ constructor (normalizerFactory: XmlBaseSerializer['normalizerFactory']) {
37
37
  if (!normalizerFactory.spec.supportsFormat(Format.JSON)) {
38
38
  throw new UnsupportedFormatError('Spec does not support JSON format.')
39
39
  }
package/src/spec.ts CHANGED
@@ -37,28 +37,21 @@ export class UnsupportedFormatError extends Error {
37
37
  }
38
38
 
39
39
  export interface Protocol {
40
- readonly version: Version
41
-
40
+ version: Version
42
41
  supportsFormat: (f: Format | any) => boolean
43
-
44
42
  supportsComponentType: (ct: ComponentType | any) => boolean
45
-
46
43
  supportsHashAlgorithm: (ha: HashAlgorithm | any) => boolean
47
-
48
44
  supportsHashValue: (hv: HashContent | any) => boolean
49
-
50
45
  supportsExternalReferenceType: (ert: ExternalReferenceType | any) => boolean
51
-
52
- readonly supportsDependencyGraph: boolean
53
-
54
- readonly supportsToolReferences: boolean
55
-
56
- readonly requiresComponentVersion: boolean
46
+ supportsDependencyGraph: boolean
47
+ supportsToolReferences: boolean
48
+ requiresComponentVersion: boolean
49
+ supportsProperties: (model: any) => boolean
57
50
  }
58
51
 
59
52
  /**
60
- * @internal This class was never intended to be public,
61
- * but it is a helper to get the exact spec-versions implemented according to {@see Protocol}.
53
+ * @internal This class was never intended to be public, but
54
+ * it is a helper to get the exact spec-versions implemented according to {@see Protocol}.
62
55
  */
63
56
  class Spec implements Protocol {
64
57
  readonly #version: Version
@@ -70,6 +63,7 @@ class Spec implements Protocol {
70
63
  readonly #supportsDependencyGraph: boolean
71
64
  readonly #supportsToolReferences: boolean
72
65
  readonly #requiresComponentVersion: boolean
66
+ readonly #supportsProperties: boolean
73
67
 
74
68
  constructor (
75
69
  version: Version,
@@ -80,7 +74,8 @@ class Spec implements Protocol {
80
74
  externalReferenceTypes: Iterable<ExternalReferenceType>,
81
75
  supportsDependencyGraph: boolean,
82
76
  supportsToolReferences: boolean,
83
- requiresComponentVersion: boolean
77
+ requiresComponentVersion: boolean,
78
+ supportsProperties: boolean
84
79
  ) {
85
80
  this.#version = version
86
81
  this.#formats = new Set(formats)
@@ -91,6 +86,7 @@ class Spec implements Protocol {
91
86
  this.#supportsDependencyGraph = supportsDependencyGraph
92
87
  this.#supportsToolReferences = supportsToolReferences
93
88
  this.#requiresComponentVersion = requiresComponentVersion
89
+ this.#supportsProperties = supportsProperties
94
90
  }
95
91
 
96
92
  get version (): Version {
@@ -129,6 +125,11 @@ class Spec implements Protocol {
129
125
  get requiresComponentVersion (): boolean {
130
126
  return this.#requiresComponentVersion
131
127
  }
128
+
129
+ supportsProperties (): boolean {
130
+ // currently a global allow/deny -- might work based on input, in the future
131
+ return this.#supportsProperties
132
+ }
132
133
  }
133
134
 
134
135
  /** Specification v1.2 */
@@ -182,7 +183,8 @@ export const Spec1dot2: Readonly<Protocol> = Object.freeze(new Spec(
182
183
  ],
183
184
  true,
184
185
  false,
185
- true
186
+ true,
187
+ false
186
188
  ))
187
189
 
188
190
  /** Specification v1.3 */
@@ -236,6 +238,7 @@ export const Spec1dot3: Readonly<Protocol> = Object.freeze(new Spec(
236
238
  ],
237
239
  true,
238
240
  false,
241
+ true,
239
242
  true
240
243
  ))
241
244
 
@@ -291,11 +294,14 @@ export const Spec1dot4: Readonly<Protocol> = Object.freeze(new Spec(
291
294
  ],
292
295
  true,
293
296
  true,
294
- false
297
+ false,
298
+ true
295
299
  ))
296
300
 
297
- export const SpecVersionDict = Object.freeze(Object.fromEntries([
298
- [Version.v1dot2, Spec1dot2],
299
- [Version.v1dot3, Spec1dot3],
300
- [Version.v1dot4, Spec1dot4]
301
- ]) as { [key in Version]?: Readonly<Protocol> })
301
+ export const SpecVersionDict: { readonly [key in Version]?: Readonly<Protocol> } = Object.freeze(
302
+ Object.fromEntries([
303
+ [Version.v1dot2, Spec1dot2],
304
+ [Version.v1dot3, Spec1dot3],
305
+ [Version.v1dot4, Spec1dot4]
306
+ ])
307
+ )