From 26b151cba7d7d484f23ee7888444f09ad6d016b1 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 24 Oct 2023 12:57:55 +0200 Subject: [PATCH] feat!: v5.0.0 (#440) BREAKING CHANGES ---------------- * Dropped support for python<3.8 ([#436] via [#441]; enable [#433]) * Reworked license related models, collections, and factories ([#365] via [#466]) * Behavior * Method `model.bom.Bom.validate()` will throw `exception.LicenseExpressionAlongWithOthersException`, if detecting invalid license constellation ([#453] via [#452]) * Fixed tuple comparison when unequal lengths (via [#461]) * API * Enum `schema.SchemaVersion` is no longer string-like ([#442] via [#447]) * Enum `schema.OutputVersion` is no longer string-like ([#442] via [#447]) * Abstract class `output.BaseOutput` requires implementation of new method `output_format` ([#446] via [#447]) * Abstract method `output.BaseOutput.output_as_string()` got new optional parameter `indent` ([#437] via [#458]) * Abstract method `output.BaseOutput.output_as_string()` accepts arbitrary kwargs (via [#458], [#462]) * Removed class `factory.license.LicenseChoiceFactory` (via [#466]) The old functionality was integrated into `factory.license.LicenseFactory`. * Method `factory.license.LicenseFactory.make_from_string()`'s parameter `name_or_spdx` was renamed to `value` (via [#466]) * Method `factory.license.LicenseFactory.make_from_string()`'s return value can also be a `LicenseExpression` ([#365] via [#466]) The behavior imitates the old `factory.license.LicenseChoiceFactory.make_from_string()` * Renamed class `module.License` to `module.license.DisjunctliveLicense` ([#365] via [#466]) * Removed class `module.LicenseChoice` ([#365] via [#466]) Use dedicated classes `module.license.DisjunctliveLicense` and `module.license.LicenseExpression` instead * All occurrences of `models.LicenseChoice` were replaced by `models.licenses.License` ([#365] via [#466]) * All occurrences of `SortedSet[LicenseChoice]` were specialized to `models.license.LicenseRepository` ([#365] via [#466]) Fixed ---------------- * Serialization of multy-licenses ([#365] via [#466]) * Detect unused "dependent" components in `model.bom.validate()` (via [#464]) Changed ---------------- * Updated latest supported list of supported SPDX license identifiers (via [#433]) * Shipped schema files are moved to a protected space (via [#433]) These files were never intended for public use. * XML output uses a default namespace, which makes results smaller. ([#438] via [#458]) Added ---------------- * Support for Python 3.12 (via [#460]) * JSON- & XML-Validators ([#432], [#446] via [#433], [#448]) The functionality might require additional dependencies, that can be installed with the extra "validation". See the docs in section "Installation" for details. * JSON & XML can be generated in a more human-friendly form ([#437], [#438] via [#458]) * Type hints, typings & overloads for better integration downstream (via [#463]) * API * New function `output.make_outputter()` (via [#469]) This replaces the deprecated function `output.get_instance()`. * New sub-package `validation` ([#432], [#446] via [#433], [#448], [#469], [#468], [#469]) * New class `exception.MissingOptionalDependencyException` ([#432] via [#433]) * New class `exception.LicenseExpressionAlongWithOthersException` ([#453] via [#452]) * New dictionaries `output.{json,xml}.BY_SCHEMA_VERSION` ([#446] via [#447]) * Existing implementations of class `output.BaseOutput` now have a new method `output_format` ([#446] via [#447]) * Existing implementations of method `output.BaseOutput.output_as_string()` got new optional parameter `indent` ([#437] via [#458]) * Existing implementations of method `output.BaseOutput.output_to_file()` got new optional parameter `indent` ([#437] via [#458]) * New method `factory.license.LicenseFactory.make_with_expression()` (via [#466]) * New class `model.license.DisjunctiveLicense` ([#365] via [#466]) * New class `model.license.LicenseExpression` ([#365] via [#466]) * New class `model.license.LicenseRepository` ([#365] via [#466]) * New class `serialization.LicenseRepositoryHelper` ([#365] via [#466]) Deprecated ---------------- * Function `output.get_instance()` might be removed, use `output.make_outputter()` instead (via [#469]) Tests ---------------- * Added validation tests with official CycloneDX schema test data ([#432] via [#433]) * Use proper snapshots, instead of pseudo comparison ([#437] via [#464]) * Added regression test for bug [#365] (via [#466], [#467]) Misc ---------------- * Dependencies: bumped `py-serializable@^0.15.0`, was `@^0.11.1` (via [#458], [#463], [#464], [#466]) * Style: streamlined quotes and strings (via [#472]) * Chore: bumped internal dev- and QA-tools ([#436] via [#441], [#472]) * Chore: added more QA tools to prevent common security issues (via [#473]) [#432]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/432 [#433]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/433 [#436]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/436 [#437]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/437 [#365]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/365 [#438]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/438 [#440]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/440 [#441]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/441 [#442]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/442 [#446]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/446 [#447]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/447 [#448]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/448 [#452]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/452 [#453]: https://github.com/CycloneDX/cyclonedx-python-lib/issues/453 [#458]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/458 [#460]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/460 [#461]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/461 [#462]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/462 [#463]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/463 [#464]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/464 [#466]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/466 [#467]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/467 [#468]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/468 [#469]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/469 [#472]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/472 [#473]: https://github.com/CycloneDX/cyclonedx-python-lib/pull/473 --------- Signed-off-by: Jan Kowalleck Signed-off-by: Jan Kowalleck Signed-off-by: semantic-release Co-authored-by: semantic-release --- .editorconfig | 2 +- .flake8 | 20 + .github/workflows/python.yml | 82 +- .github/workflows/release.yml | 24 + .isort.cfg | 4 +- .mypy.ini | 6 +- .readthedocs.yaml | 4 +- CONTRIBUTING.md | 10 +- README.md | 2 +- bandit.yml | 9 + cyclonedx/__init__.py | 7 +- cyclonedx/exception/__init__.py | 12 +- cyclonedx/exception/factory.py | 5 +- cyclonedx/exception/model.py | 16 +- cyclonedx/exception/output.py | 5 +- cyclonedx/factory/__init__.py | 2 - cyclonedx/factory/license.py | 93 +- cyclonedx/model/__init__.py | 301 +- cyclonedx/model/bom.py | 110 +- cyclonedx/model/bom_ref.py | 2 - cyclonedx/model/component.py | 159 +- cyclonedx/model/dependency.py | 20 +- cyclonedx/model/impact_analysis.py | 2 - cyclonedx/model/issue.py | 16 +- cyclonedx/model/license.py | 224 ++ cyclonedx/model/release_note.py | 34 +- cyclonedx/model/service.py | 68 +- cyclonedx/model/vulnerability.py | 126 +- cyclonedx/output/__init__.py | 108 +- cyclonedx/output/json.py | 78 +- cyclonedx/output/xml.py | 92 +- cyclonedx/parser/__init__.py | 6 +- cyclonedx/schema/__init__.py | 99 +- cyclonedx/schema/_res/.editorconfig | 10 + cyclonedx/schema/_res/.gitattributes | 6 + cyclonedx/schema/_res/README.md | 30 + cyclonedx/schema/_res/__init__.py | 61 + .../bom-1.0.SNAPSHOT.xsd} | 4 +- .../bom-1.1.SNAPSHOT.xsd} | 11 +- .../bom-1.2-strict.SNAPSHOT.schema.json} | 20 +- .../bom-1.2.SNAPSHOT.schema.json} | 25 +- .../bom-1.2.SNAPSHOT.xsd} | 17 +- .../bom-1.3-strict.SNAPSHOT.schema.json} | 19 +- .../bom-1.3.SNAPSHOT.schema.json} | 27 +- .../bom-1.3.SNAPSHOT.xsd} | 23 +- .../bom-1.4.SNAPSHOT.schema.json} | 15 +- .../bom-1.4.SNAPSHOT.xsd} | 10 +- .../schema/_res/jsf-0.82.SNAPSHOT.schema.json | 240 ++ .../spdx.SNAPSHOT.schema.json} | 1057 +++---- .../{spdx.xsd => _res/spdx.SNAPSHOT.xsd} | 2521 ++++++++++------- cyclonedx/schema/bom-1.2-strict.schema.json | 1020 ------- cyclonedx/schema/bom-1.3-strict.schema.json | 1085 ------- cyclonedx/schema/bom-1.3.proto | 452 --- cyclonedx/schema/ext/bom-descriptor-0.9.xsd | 175 -- cyclonedx/schema/ext/bom-descriptor-1.0.xsd | 183 -- cyclonedx/schema/ext/dependency-graph-1.0.xsd | 70 - .../vulnerability-1.0-SNAPSHOT.schema.json | 182 -- cyclonedx/schema/ext/vulnerability-1.0.xsd | 291 -- cyclonedx/schema/schema.py | 27 +- cyclonedx/serialization/__init__.py | 89 +- cyclonedx/spdx.py | 11 +- cyclonedx/validation/__init__.py | 119 + cyclonedx/validation/json.py | 117 + cyclonedx/validation/model.py | 20 + cyclonedx/validation/xml.py | 100 + deps.lowest.r | 7 - docs/conf.py | 11 +- docs/contributing.rst | 84 +- docs/examples.rst | 6 +- docs/install.rst | 20 +- docs/requirements.txt | 6 +- examples/build_and_serialize.py | 51 - examples/complex.py | 116 + pyproject.toml | 66 +- tests/__init__.py | 138 +- tests/_data/__init__.py | 18 + tests/{data.py => _data/models.py} | 329 ++- tests/_data/own/.gitattributes | 2 + tests/_data/own/README.md | 1 + .../own/json/1.2/bom_with_mixed_licenses.json | 47 + .../own/json/1.3/bom_with_mixed_licenses.json | 47 + .../own/json/1.4/bom_with_mixed_licenses.json | 47 + .../own}/xml/1.4/bom_setuptools.xml | 0 .../own}/xml/1.4/webgoat-6.1.xml | 0 tests/_data/schemaTestData/.gitattributes | 3 + .../schemaTestData/1.0/valid-bom-1.0.xml | 69 + .../1.0/valid-component-hashes-1.0.xml | 19 + .../1.1/invalid-component-ref-1.1.xml | 15 + .../1.1/invalid-component-type-1.1.xml | 9 + .../1.1/invalid-empty-component-1.1.xml | 7 + .../1.1/invalid-hash-alg-1.1.xml | 16 + .../1.1/invalid-hash-md5-1.1.xml | 16 + .../1.1/invalid-hash-sha1-1.1.xml | 16 + .../1.1/invalid-hash-sha256-1.1.xml | 16 + .../1.1/invalid-hash-sha512-1.1.xml | 16 + .../1.1/invalid-license-choice-1.1.xml | 26 + .../1.1/invalid-license-encoding-1.1.xml | 27 + .../1.1/invalid-license-id-1.1.xml | 27 + .../1.1/invalid-license-id-count-1.1.xml | 27 + .../1.1/invalid-license-name-count-1.1.xml | 27 + .../invalid-missing-component-type-1.1.xml | 9 + .../1.1/invalid-namespace-1.1.xml | 118 + .../schemaTestData/1.1/invalid-scope-1.1.xml | 10 + .../1.1/invalid-serialnumber-1.1.xml | 118 + .../schemaTestData/1.1/valid-bom-1.1.xml | 118 + .../1.1/valid-component-hashes-1.1.xml | 18 + .../1.1/valid-component-ref-1.1.xml | 19 + .../1.1/valid-component-types-1.1.xml | 29 + .../1.1/valid-empty-components-1.1.xml | 5 + .../1.1/valid-external-elements-1.1.xml | 158 ++ .../1.1/valid-license-expression-1.1.xml | 23 + .../1.1/valid-license-id-1.1.xml | 25 + .../1.1/valid-license-name-1.1.xml | 25 + .../1.1/valid-minimal-viable-1.1.xml | 9 + .../1.1/valid-random-attributes-1.1.xml | 118 + .../1.1/valid-xml-signature-1.1.xml | 177 ++ .../1.2/invalid-bomformat-1.2.json | 8 + .../1.2/invalid-component-ref-1.2.json | 20 + .../1.2/invalid-component-ref-1.2.xml | 15 + .../1.2/invalid-component-swid-1.2.json | 18 + .../1.2/invalid-component-swid-1.2.xml | 11 + .../1.2/invalid-component-type-1.2.json | 13 + .../1.2/invalid-component-type-1.2.xml | 9 + .../1.2/invalid-dependency-1.2.json | 37 + .../1.2/invalid-dependency-1.2.xml | 23 + .../1.2/invalid-empty-component-1.2.xml | 7 + .../1.2/invalid-hash-alg-1.2.json | 32 + .../1.2/invalid-hash-alg-1.2.xml | 16 + .../1.2/invalid-hash-md5-1.2.json | 32 + .../1.2/invalid-hash-md5-1.2.xml | 16 + .../1.2/invalid-hash-sha1-1.2.json | 32 + .../1.2/invalid-hash-sha1-1.2.xml | 16 + .../1.2/invalid-hash-sha256-1.2.json | 32 + .../1.2/invalid-hash-sha256-1.2.xml | 16 + .../1.2/invalid-hash-sha512-1.2.json | 32 + .../1.2/invalid-hash-sha512-1.2.xml | 16 + .../1.2/invalid-issue-type-1.2.json | 48 + .../1.2/invalid-issue-type-1.2.xml | 37 + .../1.2/invalid-license-choice-1.2.json | 23 + .../1.2/invalid-license-choice-1.2.xml | 26 + .../1.2/invalid-license-encoding-1.2.json | 28 + .../1.2/invalid-license-encoding-1.2.xml | 27 + .../1.2/invalid-license-id-1.2.json | 22 + .../1.2/invalid-license-id-1.2.xml | 27 + .../1.2/invalid-license-id-count-1.2.xml | 27 + .../1.2/invalid-license-name-count-1.2.xml | 27 + .../1.2/invalid-metadata-timestamp-1.2.json | 10 + .../1.2/invalid-metadata-timestamp-1.2.xml | 7 + .../invalid-missing-component-type-1.2.xml | 9 + .../1.2/invalid-namespace-1.2.xml | 118 + .../1.2/invalid-patch-type-1.2.json | 48 + .../1.2/invalid-patch-type-1.2.xml | 37 + .../schemaTestData/1.2/invalid-scope-1.2.json | 14 + .../schemaTestData/1.2/invalid-scope-1.2.xml | 10 + .../1.2/invalid-serialnumber-1.2.json | 8 + .../1.2/invalid-serialnumber-1.2.xml | 118 + .../1.2/invalid-service-data-1.2.json | 20 + .../1.2/invalid-service-data-1.2.xml | 11 + .../1.2/skip_invalid-empty-component-1.2.json | 12 + ...ip_invalid-missing-component-type-1.2.json | 13 + .../1.2/valid-assembly-1.2.json | 30 + .../schemaTestData/1.2/valid-assembly-1.2.xml | 25 + .../schemaTestData/1.2/valid-bom-1.2.json | 177 ++ .../schemaTestData/1.2/valid-bom-1.2.xml | 181 ++ .../1.2/valid-component-hashes-1.2.json | 63 + .../1.2/valid-component-hashes-1.2.xml | 23 + .../1.2/valid-component-ref-1.2.json | 20 + .../1.2/valid-component-ref-1.2.xml | 19 + .../1.2/valid-component-swid-1.2.json | 19 + .../1.2/valid-component-swid-1.2.xml | 11 + .../1.2/valid-component-swid-full-1.2.json | 24 + .../1.2/valid-component-swid-full-1.2.xml | 13 + .../1.2/valid-component-types-1.2.json | 48 + .../1.2/valid-component-types-1.2.xml | 37 + .../1.2/valid-dependency-1.2.json | 38 + .../1.2/valid-dependency-1.2.xml | 23 + .../1.2/valid-empty-components-1.2.json | 8 + .../1.2/valid-empty-components-1.2.xml | 5 + .../1.2/valid-external-elements-1.2.xml | 158 ++ .../1.2/valid-license-expression-1.2.json | 20 + .../1.2/valid-license-expression-1.2.xml | 23 + .../1.2/valid-license-id-1.2.json | 22 + .../1.2/valid-license-id-1.2.xml | 25 + .../1.2/valid-license-name-1.2.json | 22 + .../1.2/valid-license-name-1.2.xml | 25 + .../1.2/valid-metadata-author-1.2.json | 16 + .../1.2/valid-metadata-author-1.2.xml | 13 + .../1.2/valid-metadata-manufacture-1.2.json | 21 + .../1.2/valid-metadata-manufacture-1.2.xml | 14 + .../1.2/valid-metadata-supplier-1.2.json | 21 + .../1.2/valid-metadata-supplier-1.2.xml | 14 + .../1.2/valid-metadata-timestamp-1.2.json | 10 + .../1.2/valid-metadata-timestamp-1.2.xml | 7 + .../1.2/valid-metadata-tool-1.2.json | 26 + .../1.2/valid-metadata-tool-1.2.xml | 17 + .../1.2/valid-minimal-viable-1.2.json | 13 + .../1.2/valid-minimal-viable-1.2.xml | 9 + .../schemaTestData/1.2/valid-patch-1.2.json | 88 + .../schemaTestData/1.2/valid-patch-1.2.xml | 70 + .../1.2/valid-random-attributes-1.2.xml | 118 + .../schemaTestData/1.2/valid-service-1.2.json | 101 + .../schemaTestData/1.2/valid-service-1.2.xml | 66 + .../1.2/valid-service-empty-objects-1.2.json | 22 + .../1.2/valid-service-empty-objects-1.2.xml | 16 + .../1.2/valid-xml-signature-1.2.xml | 177 ++ .../1.3/invalid-bomformat-1.3.json | 8 + .../1.3/invalid-component-ref-1.3.json | 20 + .../1.3/invalid-component-ref-1.3.xml | 15 + .../1.3/invalid-component-swid-1.3.json | 18 + .../1.3/invalid-component-swid-1.3.xml | 11 + .../1.3/invalid-component-type-1.3.json | 13 + .../1.3/invalid-component-type-1.3.xml | 9 + .../1.3/invalid-dependency-1.3.json | 37 + .../1.3/invalid-dependency-1.3.xml | 23 + .../1.3/invalid-empty-component-1.3.json | 11 + .../1.3/invalid-empty-component-1.3.xml | 7 + .../1.3/invalid-hash-alg-1.3.json | 32 + .../1.3/invalid-hash-alg-1.3.xml | 16 + .../1.3/invalid-hash-md5-1.3.json | 32 + .../1.3/invalid-hash-md5-1.3.xml | 16 + .../1.3/invalid-hash-sha1-1.3.json | 32 + .../1.3/invalid-hash-sha1-1.3.xml | 16 + .../1.3/invalid-hash-sha256-1.3.json | 32 + .../1.3/invalid-hash-sha256-1.3.xml | 16 + .../1.3/invalid-hash-sha512-1.3.json | 32 + .../1.3/invalid-hash-sha512-1.3.xml | 16 + .../1.3/invalid-issue-type-1.3.json | 48 + .../1.3/invalid-issue-type-1.3.xml | 37 + .../1.3/invalid-license-choice-1.3.json | 23 + .../1.3/invalid-license-choice-1.3.xml | 26 + .../1.3/invalid-license-encoding-1.3.json | 28 + .../1.3/invalid-license-encoding-1.3.xml | 27 + .../1.3/invalid-license-id-1.3.json | 22 + .../1.3/invalid-license-id-1.3.xml | 27 + .../1.3/invalid-license-id-count-1.3.xml | 27 + .../1.3/invalid-license-name-count-1.3.xml | 27 + .../1.3/invalid-metadata-license-1.3.json | 16 + .../1.3/invalid-metadata-license-1.3.xml | 11 + .../1.3/invalid-metadata-timestamp-1.3.json | 10 + .../1.3/invalid-metadata-timestamp-1.3.xml | 7 + .../invalid-missing-component-type-1.3.json | 12 + .../invalid-missing-component-type-1.3.xml | 9 + .../1.3/invalid-namespace-1.3.xml | 118 + .../1.3/invalid-patch-type-1.3.json | 48 + .../1.3/invalid-patch-type-1.3.xml | 37 + .../schemaTestData/1.3/invalid-scope-1.3.json | 14 + .../schemaTestData/1.3/invalid-scope-1.3.xml | 10 + .../1.3/invalid-serialnumber-1.3.json | 8 + .../1.3/invalid-serialnumber-1.3.xml | 118 + .../1.3/invalid-service-data-1.3.json | 20 + .../1.3/invalid-service-data-1.3.xml | 11 + .../1.3/valid-assembly-1.3.json | 30 + .../schemaTestData/1.3/valid-assembly-1.3.xml | 25 + .../schemaTestData/1.3/valid-bom-1.3.json | 177 ++ .../schemaTestData/1.3/valid-bom-1.3.xml | 181 ++ .../1.3/valid-component-hashes-1.3.json | 63 + .../1.3/valid-component-hashes-1.3.xml | 23 + .../1.3/valid-component-ref-1.3.json | 20 + .../1.3/valid-component-ref-1.3.xml | 19 + .../1.3/valid-component-swid-1.3.json | 19 + .../1.3/valid-component-swid-1.3.xml | 11 + .../1.3/valid-component-swid-full-1.3.json | 24 + .../1.3/valid-component-swid-full-1.3.xml | 13 + .../1.3/valid-component-types-1.3.json | 48 + .../1.3/valid-component-types-1.3.xml | 37 + .../1.3/valid-compositions-1.3.json | 65 + .../1.3/valid-compositions-1.3.xml | 51 + .../1.3/valid-dependency-1.3.json | 38 + .../1.3/valid-dependency-1.3.xml | 23 + .../1.3/valid-empty-components-1.3.json | 8 + .../1.3/valid-empty-components-1.3.xml | 5 + .../1.3/valid-evidence-1.3.json | 53 + .../schemaTestData/1.3/valid-evidence-1.3.xml | 35 + .../1.3/valid-external-elements-1.3.xml | 158 ++ .../1.3/valid-external-reference-1.3.json | 38 + .../1.3/valid-external-reference-1.3.xml | 27 + .../1.3/valid-license-expression-1.3.json | 20 + .../1.3/valid-license-expression-1.3.xml | 23 + .../1.3/valid-license-id-1.3.json | 22 + .../1.3/valid-license-id-1.3.xml | 25 + .../1.3/valid-license-name-1.3.json | 22 + .../1.3/valid-license-name-1.3.xml | 25 + .../1.3/valid-metadata-author-1.3.json | 16 + .../1.3/valid-metadata-author-1.3.xml | 13 + .../1.3/valid-metadata-license-1.3.json | 16 + .../1.3/valid-metadata-license-1.3.xml | 11 + .../1.3/valid-metadata-manufacture-1.3.json | 21 + .../1.3/valid-metadata-manufacture-1.3.xml | 14 + .../1.3/valid-metadata-supplier-1.3.json | 21 + .../1.3/valid-metadata-supplier-1.3.xml | 14 + .../1.3/valid-metadata-timestamp-1.3.json | 10 + .../1.3/valid-metadata-timestamp-1.3.xml | 7 + .../1.3/valid-metadata-tool-1.3.json | 26 + .../1.3/valid-metadata-tool-1.3.xml | 17 + .../1.3/valid-minimal-viable-1.3.json | 13 + .../1.3/valid-minimal-viable-1.3.xml | 9 + .../schemaTestData/1.3/valid-patch-1.3.json | 88 + .../schemaTestData/1.3/valid-patch-1.3.xml | 70 + .../1.3/valid-properties-1.3.json | 55 + .../1.3/valid-properties-1.3.xml | 34 + .../1.3/valid-random-attributes-1.3.xml | 118 + .../schemaTestData/1.3/valid-service-1.3.json | 101 + .../schemaTestData/1.3/valid-service-1.3.xml | 66 + .../1.3/valid-service-empty-objects-1.3.json | 22 + .../1.3/valid-service-empty-objects-1.3.xml | 16 + .../1.3/valid-xml-signature-1.3.xml | 177 ++ .../1.4/invalid-bomformat-1.4.json | 8 + .../1.4/invalid-component-ref-1.4.json | 20 + .../1.4/invalid-component-ref-1.4.xml | 15 + .../1.4/invalid-component-swid-1.4.json | 18 + .../1.4/invalid-component-swid-1.4.xml | 11 + .../1.4/invalid-component-type-1.4.json | 13 + .../1.4/invalid-component-type-1.4.xml | 9 + .../1.4/invalid-dependency-1.4.json | 37 + .../1.4/invalid-dependency-1.4.xml | 23 + .../1.4/invalid-empty-component-1.4.json | 11 + .../1.4/invalid-empty-component-1.4.xml | 7 + .../1.4/invalid-hash-alg-1.4.json | 32 + .../1.4/invalid-hash-alg-1.4.xml | 16 + .../1.4/invalid-hash-md5-1.4.json | 32 + .../1.4/invalid-hash-md5-1.4.xml | 16 + .../1.4/invalid-hash-sha1-1.4.json | 32 + .../1.4/invalid-hash-sha1-1.4.xml | 16 + .../1.4/invalid-hash-sha256-1.4.json | 32 + .../1.4/invalid-hash-sha256-1.4.xml | 16 + .../1.4/invalid-hash-sha512-1.4.json | 32 + .../1.4/invalid-hash-sha512-1.4.xml | 16 + .../1.4/invalid-issue-type-1.4.json | 48 + .../1.4/invalid-issue-type-1.4.xml | 37 + .../1.4/invalid-license-choice-1.4.json | 23 + .../1.4/invalid-license-choice-1.4.xml | 26 + .../1.4/invalid-license-encoding-1.4.json | 28 + .../1.4/invalid-license-encoding-1.4.xml | 27 + .../1.4/invalid-license-id-1.4.json | 22 + .../1.4/invalid-license-id-1.4.xml | 27 + .../1.4/invalid-license-id-count-1.4.xml | 27 + .../1.4/invalid-license-name-count-1.4.xml | 27 + .../1.4/invalid-metadata-license-1.4.json | 16 + .../1.4/invalid-metadata-license-1.4.xml | 11 + .../1.4/invalid-metadata-timestamp-1.4.json | 10 + .../1.4/invalid-metadata-timestamp-1.4.xml | 7 + .../invalid-missing-component-type-1.4.json | 12 + .../invalid-missing-component-type-1.4.xml | 9 + .../1.4/invalid-namespace-1.4.xml | 118 + .../1.4/invalid-patch-type-1.4.json | 48 + .../1.4/invalid-patch-type-1.4.xml | 37 + .../schemaTestData/1.4/invalid-scope-1.4.json | 14 + .../schemaTestData/1.4/invalid-scope-1.4.xml | 10 + .../1.4/invalid-serialnumber-1.4.json | 8 + .../1.4/invalid-serialnumber-1.4.xml | 118 + .../1.4/invalid-service-data-1.4.json | 20 + .../1.4/invalid-service-data-1.4.xml | 11 + .../1.4/valid-assembly-1.4.json | 30 + .../schemaTestData/1.4/valid-assembly-1.4.xml | 25 + .../schemaTestData/1.4/valid-bom-1.4.json | 177 ++ .../schemaTestData/1.4/valid-bom-1.4.xml | 181 ++ .../1.4/valid-component-hashes-1.4.json | 63 + .../1.4/valid-component-hashes-1.4.xml | 23 + .../1.4/valid-component-ref-1.4.json | 20 + .../1.4/valid-component-ref-1.4.xml | 19 + .../1.4/valid-component-swid-1.4.json | 19 + .../1.4/valid-component-swid-1.4.xml | 11 + .../1.4/valid-component-swid-full-1.4.json | 24 + .../1.4/valid-component-swid-full-1.4.xml | 13 + .../1.4/valid-component-types-1.4.json | 48 + .../1.4/valid-component-types-1.4.xml | 37 + .../1.4/valid-compositions-1.4.json | 65 + .../1.4/valid-compositions-1.4.xml | 51 + .../1.4/valid-dependency-1.4.json | 38 + .../1.4/valid-dependency-1.4.xml | 23 + .../1.4/valid-empty-components-1.4.json | 8 + .../1.4/valid-empty-components-1.4.xml | 5 + .../1.4/valid-evidence-1.4.json | 53 + .../schemaTestData/1.4/valid-evidence-1.4.xml | 35 + .../1.4/valid-external-elements-1.4.xml | 158 ++ .../1.4/valid-external-reference-1.4.json | 38 + .../1.4/valid-external-reference-1.4.xml | 27 + .../1.4/valid-license-expression-1.4.json | 20 + .../1.4/valid-license-expression-1.4.xml | 23 + .../1.4/valid-license-id-1.4.json | 22 + .../1.4/valid-license-id-1.4.xml | 25 + .../1.4/valid-license-name-1.4.json | 22 + .../1.4/valid-license-name-1.4.xml | 25 + .../1.4/valid-metadata-author-1.4.json | 16 + .../1.4/valid-metadata-author-1.4.xml | 13 + .../1.4/valid-metadata-license-1.4.json | 16 + .../1.4/valid-metadata-license-1.4.xml | 11 + .../1.4/valid-metadata-manufacture-1.4.json | 21 + .../1.4/valid-metadata-manufacture-1.4.xml | 14 + .../1.4/valid-metadata-supplier-1.4.json | 21 + .../1.4/valid-metadata-supplier-1.4.xml | 14 + .../1.4/valid-metadata-timestamp-1.4.json | 10 + .../1.4/valid-metadata-timestamp-1.4.xml | 7 + .../1.4/valid-metadata-tool-1.4.json | 26 + .../1.4/valid-metadata-tool-1.4.xml | 17 + .../1.4/valid-minimal-viable-1.4.json | 12 + .../1.4/valid-minimal-viable-1.4.xml | 8 + .../schemaTestData/1.4/valid-patch-1.4.json | 88 + .../schemaTestData/1.4/valid-patch-1.4.xml | 70 + .../1.4/valid-properties-1.4.json | 55 + .../1.4/valid-properties-1.4.xml | 34 + .../1.4/valid-random-attributes-1.4.xml | 118 + .../1.4/valid-release-notes-1.4.json | 194 ++ .../1.4/valid-release-notes-1.4.xml | 149 + .../schemaTestData/1.4/valid-service-1.4.json | 101 + .../schemaTestData/1.4/valid-service-1.4.xml | 66 + .../1.4/valid-service-empty-objects-1.4.json | 22 + .../1.4/valid-service-empty-objects-1.4.xml | 16 + .../1.4/valid-signatures-1.4.json | 78 + .../1.4/valid-vulnerability-1.4.json | 140 + .../1.4/valid-vulnerability-1.4.xml | 127 + .../1.4/valid-xml-signature-1.4.xml | 177 ++ tests/_data/schemaTestData/README.md | 2 + tests/_data/schemaTestData/fetch.sh | 21 + tests/_data/snapshots/.gitattributes | 3 + tests/{fixtures => _data/snapshots}/README.md | 0 ...t_bom_for_issue_275_components-1.0.xml.bin | 22 + ...t_bom_for_issue_275_components-1.1.xml.bin | 19 + ...bom_for_issue_275_components-1.2.json.bin} | 72 +- ...t_bom_for_issue_275_components-1.2.xml.bin | 44 + ...bom_for_issue_275_components-1.3.json.bin} | 72 +- ...t_bom_for_issue_275_components-1.3.xml.bin | 44 + ...bom_for_issue_275_components-1.4.json.bin} | 140 +- ...t_bom_for_issue_275_components-1.4.xml.bin | 70 + ...t_bom_for_issue_328_components-1.0.xml.bin | 24 + ...t_bom_for_issue_328_components-1.1.xml.bin | 21 + ...bom_for_issue_328_components-1.2.json.bin} | 87 +- ...t_bom_for_issue_328_components-1.2.xml.bin | 47 + ...bom_for_issue_328_components-1.3.json.bin} | 87 +- ...t_bom_for_issue_328_components-1.3.xml.bin | 47 + ...bom_for_issue_328_components-1.4.json.bin} | 155 +- ...t_bom_for_issue_328_components-1.4.xml.bin | 73 + ...et_bom_just_complete_metadata-1.0.xml.bin} | 4 +- ...get_bom_just_complete_metadata-1.1.xml.bin | 4 + ...t_bom_just_complete_metadata-1.2.json.bin} | 342 +-- ...get_bom_just_complete_metadata-1.2.xml.bin | 204 ++ ...t_bom_just_complete_metadata-1.3.json.bin} | 432 +-- ...get_bom_just_complete_metadata-1.3.xml.bin | 237 ++ ...t_bom_just_complete_metadata-1.4.json.bin} | 568 ++-- ...get_bom_just_complete_metadata-1.4.xml.bin | 305 ++ ...ith_component_setuptools_basic-1.0.xml.bin | 11 + ...ith_component_setuptools_basic-1.1.xml.bin | 15 + ...h_component_setuptools_basic-1.2.json.bin} | 48 +- ...ith_component_setuptools_basic-1.2.xml.bin | 29 + ...h_component_setuptools_basic-1.3.json.bin} | 48 +- ...ith_component_setuptools_basic-1.3.xml.bin | 29 + ...h_component_setuptools_basic-1.4.json.bin} | 94 +- ...ith_component_setuptools_basic-1.4.xml.bin | 55 + ..._component_setuptools_complete-1.0.xml.bin | 33 + ..._component_setuptools_complete-1.1.xml.bin | 135 + ...omponent_setuptools_complete-1.2.json.bin} | 320 ++- ..._component_setuptools_complete-1.2.xml.bin | 173 ++ ...omponent_setuptools_complete-1.3.json.bin} | 372 +-- ..._component_setuptools_complete-1.3.xml.bin | 195 ++ ...omponent_setuptools_complete-1.4.json.bin} | 508 ++-- ..._component_setuptools_complete-1.4.xml.bin | 263 ++ ...etuptools_no_component_version-1.0.xml.bin | 11 + ...etuptools_no_component_version-1.1.xml.bin | 15 + ...uptools_no_component_version-1.2.json.bin} | 48 +- ...etuptools_no_component_version-1.2.xml.bin | 29 + ...uptools_no_component_version-1.3.json.bin} | 48 +- ...etuptools_no_component_version-1.3.xml.bin | 29 + ...uptools_no_component_version-1.4.json.bin} | 92 +- ...etuptools_no_component_version-1.4.xml.bin | 54 + ..._component_setuptools_with_cpe-1.0.xml.bin | 12 + ..._component_setuptools_with_cpe-1.1.xml.bin | 16 + ...omponent_setuptools_with_cpe-1.2.json.bin} | 50 +- ..._component_setuptools_with_cpe-1.2.xml.bin | 30 + ...omponent_setuptools_with_cpe-1.3.json.bin} | 50 +- ..._component_setuptools_with_cpe-1.3.xml.bin | 30 + ...omponent_setuptools_with_cpe-1.4.json.bin} | 96 +- ..._component_setuptools_with_cpe-1.4.xml.bin | 56 + ..._setuptools_with_release_notes-1.0.xml.bin | 11 + ..._setuptools_with_release_notes-1.1.xml.bin | 15 + ...setuptools_with_release_notes-1.2.json.bin | 39 + ..._setuptools_with_release_notes-1.2.xml.bin | 29 + ...setuptools_with_release_notes-1.3.json.bin | 39 + ..._setuptools_with_release_notes-1.3.xml.bin | 29 + ...etuptools_with_release_notes-1.4.json.bin} | 178 +- ..._setuptools_with_release_notes-1.4.xml.bin | 99 + ..._setuptools_with_vulnerability-1.0.xml.bin | 11 + ..._setuptools_with_vulnerability-1.1.xml.bin | 15 + ...setuptools_with_vulnerability-1.2.json.bin | 39 + ..._setuptools_with_vulnerability-1.2.xml.bin | 29 + ...setuptools_with_vulnerability-1.3.json.bin | 39 + ..._setuptools_with_vulnerability-1.3.xml.bin | 29 + ...etuptools_with_vulnerability-1.4.json.bin} | 270 +- ..._setuptools_with_vulnerability-1.4.xml.bin | 168 ++ .../get_bom_with_component_toml_1-1.0.xml.bin | 14 + .../get_bom_with_component_toml_1-1.1.xml.bin | 19 + ...et_bom_with_component_toml_1-1.2.json.bin} | 54 +- .../get_bom_with_component_toml_1-1.2.xml.bin | 32 + ...et_bom_with_component_toml_1-1.3.json.bin} | 62 +- .../get_bom_with_component_toml_1-1.3.xml.bin | 35 + ...et_bom_with_component_toml_1-1.4.json.bin} | 118 +- .../get_bom_with_component_toml_1-1.4.xml.bin | 61 + ..._bom_with_dependencies_hanging-1.0.xml.bin | 20 + ..._bom_with_dependencies_hanging-1.1.xml.bin | 29 + ...bom_with_dependencies_hanging-1.2.json.bin | 74 + ..._bom_with_dependencies_hanging-1.2.xml.bin | 51 + ...om_with_dependencies_hanging-1.3.json.bin} | 46 +- ..._bom_with_dependencies_hanging-1.3.xml.bin | 54 + ...bom_with_dependencies_hanging-1.4.json.bin | 113 + ..._bom_with_dependencies_hanging-1.4.xml.bin | 79 + ...et_bom_with_dependencies_valid-1.0.xml.bin | 20 + ...et_bom_with_dependencies_valid-1.1.xml.bin | 29 + ..._bom_with_dependencies_valid-1.2.json.bin} | 72 +- ...et_bom_with_dependencies_valid-1.2.xml.bin | 46 + ..._bom_with_dependencies_valid-1.3.json.bin} | 80 +- ...et_bom_with_dependencies_valid-1.3.xml.bin | 49 + ..._bom_with_dependencies_valid-1.4.json.bin} | 148 +- ...et_bom_with_dependencies_valid-1.4.xml.bin | 75 + ...t_bom_with_external_references-1.0.xml.bin | 4 + ...t_bom_with_external_references-1.1.xml.bin | 13 + ...bom_with_external_references-1.2.json.bin} | 36 +- ...t_bom_with_external_references-1.2.xml.bin | 22 + ...bom_with_external_references-1.3.json.bin} | 44 +- ...t_bom_with_external_references-1.3.xml.bin | 25 + ...bom_with_external_references-1.4.json.bin} | 86 +- ...t_bom_with_external_references-1.4.xml.bin | 51 + .../get_bom_with_licenses-1.0.xml.bin | 20 + .../get_bom_with_licenses-1.1.xml.bin | 30 + .../get_bom_with_licenses-1.2.json.bin | 125 + .../get_bom_with_licenses-1.2.xml.bin | 82 + .../get_bom_with_licenses-1.3.json.bin | 132 + .../get_bom_with_licenses-1.3.xml.bin | 87 + .../get_bom_with_licenses-1.4.json.bin | 162 ++ .../get_bom_with_licenses-1.4.xml.bin | 109 + ...t_bom_with_licenses_expression-1.0.xml.bin | 4 + ...t_bom_with_licenses_expression-1.1.xml.bin | 4 + ..._bom_with_licenses_expression-1.2.json.bin | 17 + ...t_bom_with_licenses_expression-1.2.xml.bin | 13 + ..._bom_with_licenses_expression-1.3.json.bin | 22 + ...t_bom_with_licenses_expression-1.3.xml.bin | 16 + ..._bom_with_licenses_expression-1.4.json.bin | 56 + ...t_bom_with_licenses_expression-1.4.xml.bin | 42 + ...ata_component_and_dependencies-1.0.xml.bin | 14 + ...ata_component_and_dependencies-1.1.xml.bin | 19 + ...a_component_and_dependencies-1.2.json.bin} | 86 +- ...ata_component_and_dependencies-1.2.xml.bin | 46 + ...a_component_and_dependencies-1.3.json.bin} | 94 +- ...ata_component_and_dependencies-1.3.xml.bin | 49 + ...a_component_and_dependencies-1.4.json.bin} | 162 +- ...ata_component_and_dependencies-1.4.xml.bin | 75 + ...get_bom_with_multiple_licenses-1.0.xml.bin | 10 + ...get_bom_with_multiple_licenses-1.1.xml.bin | 17 + ...et_bom_with_multiple_licenses-1.2.json.bin | 84 + ...get_bom_with_multiple_licenses-1.2.xml.bin | 57 + ...et_bom_with_multiple_licenses-1.3.json.bin | 96 + ...get_bom_with_multiple_licenses-1.3.xml.bin | 65 + ...et_bom_with_multiple_licenses-1.4.json.bin | 128 + ...get_bom_with_multiple_licenses-1.4.xml.bin | 89 + .../get_bom_with_nested_services-1.0.xml.bin | 4 + .../get_bom_with_nested_services-1.1.xml.bin | 4 + ...get_bom_with_nested_services-1.2.json.bin} | 74 +- .../get_bom_with_nested_services-1.2.xml.bin | 114 + ...get_bom_with_nested_services-1.3.json.bin} | 188 +- .../get_bom_with_nested_services-1.3.xml.bin | 121 + ...get_bom_with_nested_services-1.4.json.bin} | 310 +- .../get_bom_with_nested_services-1.4.xml.bin | 191 ++ .../get_bom_with_services_complex-1.0.xml.bin | 4 + .../get_bom_with_services_complex-1.1.xml.bin | 4 + ...et_bom_with_services_complex-1.2.json.bin} | 116 +- .../get_bom_with_services_complex-1.2.xml.bin | 66 + ...et_bom_with_services_complex-1.3.json.bin} | 128 +- .../get_bom_with_services_complex-1.3.xml.bin | 73 + ...et_bom_with_services_complex-1.4.json.bin} | 246 +- .../get_bom_with_services_complex-1.4.xml.bin | 143 + .../get_bom_with_services_simple-1.0.xml.bin | 4 + .../get_bom_with_services_simple-1.1.xml.bin | 4 + ...get_bom_with_services_simple-1.2.json.bin} | 54 +- .../get_bom_with_services_simple-1.2.xml.bin | 30 + ...get_bom_with_services_simple-1.3.json.bin} | 54 +- .../get_bom_with_services_simple-1.3.xml.bin | 30 + ...get_bom_with_services_simple-1.4.json.bin} | 92 +- .../get_bom_with_services_simple-1.4.xml.bin | 56 + tests/base.py | 148 - .../xml/1.0/bom_issue_275_components.xml | 22 - .../xml/1.0/bom_issue_328_components.xml | 24 - tests/fixtures/xml/1.0/bom_setuptools.xml | 11 - .../xml/1.0/bom_setuptools_complete.xml | 33 - .../xml/1.0/bom_setuptools_no_version.xml | 11 - .../xml/1.0/bom_setuptools_with_cpe.xml | 12 - .../1.0/bom_toml_hashes_and_references.xml | 14 - tests/fixtures/xml/1.1/bom_dependencies.xml | 28 - tests/fixtures/xml/1.1/bom_empty.xml | 5 - .../xml/1.1/bom_external_references.xml | 14 - .../xml/1.1/bom_issue_275_components.xml | 20 - .../xml/1.1/bom_issue_328_components.xml | 22 - tests/fixtures/xml/1.1/bom_setuptools.xml | 14 - .../xml/1.1/bom_setuptools_complete.xml | 124 - .../xml/1.1/bom_setuptools_no_version.xml | 14 - .../xml/1.1/bom_setuptools_with_cpe.xml | 15 - .../bom_setuptools_with_vulnerabilities.xml | 53 - .../1.1/bom_toml_hashes_and_references.xml | 20 - tests/fixtures/xml/1.2/bom_dependencies.xml | 45 - .../xml/1.2/bom_dependencies_component.xml | 45 - .../xml/1.2/bom_external_references.xml | 23 - .../xml/1.2/bom_issue_275_components.xml | 45 - .../xml/1.2/bom_issue_328_components.xml | 48 - .../fixtures/xml/1.2/bom_services_complex.xml | 65 - .../fixtures/xml/1.2/bom_services_nested.xml | 113 - .../fixtures/xml/1.2/bom_services_simple.xml | 31 - tests/fixtures/xml/1.2/bom_setuptools.xml | 28 - .../xml/1.2/bom_setuptools_complete.xml | 162 -- .../xml/1.2/bom_setuptools_no_version.xml | 28 - .../xml/1.2/bom_setuptools_with_cpe.xml | 29 - .../bom_setuptools_with_vulnerabilities.xml | 67 - .../1.2/bom_toml_hashes_and_references.xml | 33 - .../xml/1.2/bom_with_full_metadata.xml | 193 -- tests/fixtures/xml/1.3/bom_dependencies.xml | 48 - .../xml/1.3/bom_dependencies_component.xml | 48 - .../xml/1.3/bom_external_references.xml | 26 - .../xml/1.3/bom_issue_275_components.xml | 45 - .../xml/1.3/bom_issue_328_components.xml | 48 - .../fixtures/xml/1.3/bom_services_complex.xml | 72 - .../fixtures/xml/1.3/bom_services_nested.xml | 120 - .../fixtures/xml/1.3/bom_services_simple.xml | 31 - tests/fixtures/xml/1.3/bom_setuptools.xml | 28 - .../xml/1.3/bom_setuptools_complete.xml | 184 -- .../xml/1.3/bom_setuptools_no_version.xml | 28 - .../xml/1.3/bom_setuptools_with_cpe.xml | 29 - .../bom_setuptools_with_vulnerabilities.xml | 67 - .../1.3/bom_toml_hashes_and_references.xml | 36 - .../xml/1.3/bom_with_full_metadata.xml | 226 -- tests/fixtures/xml/1.4/bom_dependencies.xml | 74 - .../xml/1.4/bom_dependencies_component.xml | 74 - .../xml/1.4/bom_external_references.xml | 51 - .../xml/1.4/bom_issue_275_components.xml | 71 - .../xml/1.4/bom_issue_328_components.xml | 73 - .../fixtures/xml/1.4/bom_services_complex.xml | 142 - .../fixtures/xml/1.4/bom_services_nested.xml | 190 -- .../fixtures/xml/1.4/bom_services_simple.xml | 57 - .../xml/1.4/bom_setuptools_complete.xml | 252 -- .../xml/1.4/bom_setuptools_no_version.xml | 53 - .../xml/1.4/bom_setuptools_with_cpe.xml | 55 - .../1.4/bom_setuptools_with_release_notes.xml | 98 - .../bom_setuptools_with_vulnerabilities.xml | 166 -- .../1.4/bom_toml_hashes_and_references.xml | 62 - .../xml/1.4/bom_with_dependencies_hanging.xml | 47 - .../xml/1.4/bom_with_full_metadata.xml | 294 -- tests/test_component.py | 16 +- tests/test_deserialize_json.py | 466 +-- tests/test_deserialize_xml.py | 706 +---- tests/test_e2e_environment.py | 82 - tests/test_factory_license.py | 111 +- tests/test_model.py | 58 +- tests/test_model_bom.py | 45 +- tests/test_model_bom_ref.py | 5 +- tests/test_model_component.py | 45 +- tests/test_model_dependency.py | 18 +- tests/test_model_issue.py | 14 +- tests/test_model_license.py | 117 + tests/test_model_release_note.py | 12 +- tests/test_model_service.py | 19 +- tests/test_model_vulnerability.py | 14 +- tests/test_output.py | 51 + tests/test_output_generic.py | 12 +- tests/test_output_json.py | 450 +-- tests/test_output_xml.py | 581 +--- tests/test_real_world_examples.py | 27 +- tests/test_schema_SchemaVersion.py | 76 + tests/test_schema__res.py | 42 + tests/test_spdx.py | 9 +- tests/test_validation.py | 54 + tests/test_validation_json.py | 111 + tests/test_validation_xml.py | 77 + tools/schema-downloader.py | 108 + tox.ini | 40 +- typings/sortedcontainers.pyi | 5 +- 670 files changed, 27318 insertions(+), 16049 deletions(-) create mode 100644 .flake8 create mode 100644 bandit.yml create mode 100644 cyclonedx/model/license.py create mode 100644 cyclonedx/schema/_res/.editorconfig create mode 100644 cyclonedx/schema/_res/.gitattributes create mode 100644 cyclonedx/schema/_res/README.md create mode 100644 cyclonedx/schema/_res/__init__.py rename cyclonedx/schema/{bom-1.0.xsd => _res/bom-1.0.SNAPSHOT.xsd} (99%) rename cyclonedx/schema/{bom-1.1.xsd => _res/bom-1.1.SNAPSHOT.xsd} (99%) rename cyclonedx/schema/{bom-1.2b.schema.json => _res/bom-1.2-strict.SNAPSHOT.schema.json} (98%) rename cyclonedx/schema/{bom-1.2.schema.json => _res/bom-1.2.SNAPSHOT.schema.json} (98%) rename cyclonedx/schema/{bom-1.2.xsd => _res/bom-1.2.SNAPSHOT.xsd} (99%) rename cyclonedx/schema/{bom-1.3a.schema.json => _res/bom-1.3-strict.SNAPSHOT.schema.json} (98%) rename cyclonedx/schema/{bom-1.3.schema.json => _res/bom-1.3.SNAPSHOT.schema.json} (98%) rename cyclonedx/schema/{bom-1.3.xsd => _res/bom-1.3.SNAPSHOT.xsd} (99%) rename cyclonedx/schema/{bom-1.4.schema.json => _res/bom-1.4.SNAPSHOT.schema.json} (98%) rename cyclonedx/schema/{bom-1.4.xsd => _res/bom-1.4.SNAPSHOT.xsd} (99%) create mode 100644 cyclonedx/schema/_res/jsf-0.82.SNAPSHOT.schema.json rename cyclonedx/schema/{spdx.schema.json => _res/spdx.SNAPSHOT.schema.json} (84%) rename cyclonedx/schema/{spdx.xsd => _res/spdx.SNAPSHOT.xsd} (86%) delete mode 100644 cyclonedx/schema/bom-1.2-strict.schema.json delete mode 100644 cyclonedx/schema/bom-1.3-strict.schema.json delete mode 100644 cyclonedx/schema/bom-1.3.proto delete mode 100644 cyclonedx/schema/ext/bom-descriptor-0.9.xsd delete mode 100644 cyclonedx/schema/ext/bom-descriptor-1.0.xsd delete mode 100644 cyclonedx/schema/ext/dependency-graph-1.0.xsd delete mode 100644 cyclonedx/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json delete mode 100644 cyclonedx/schema/ext/vulnerability-1.0.xsd create mode 100644 cyclonedx/validation/__init__.py create mode 100644 cyclonedx/validation/json.py create mode 100644 cyclonedx/validation/model.py create mode 100644 cyclonedx/validation/xml.py delete mode 100644 deps.lowest.r delete mode 100644 examples/build_and_serialize.py create mode 100644 examples/complex.py create mode 100644 tests/_data/__init__.py rename tests/{data.py => _data/models.py} (68%) create mode 100644 tests/_data/own/.gitattributes create mode 100644 tests/_data/own/README.md create mode 100644 tests/_data/own/json/1.2/bom_with_mixed_licenses.json create mode 100644 tests/_data/own/json/1.3/bom_with_mixed_licenses.json create mode 100644 tests/_data/own/json/1.4/bom_with_mixed_licenses.json rename tests/{fixtures => _data/own}/xml/1.4/bom_setuptools.xml (100%) rename tests/{fixtures => _data/own}/xml/1.4/webgoat-6.1.xml (100%) create mode 100644 tests/_data/schemaTestData/.gitattributes create mode 100644 tests/_data/schemaTestData/1.0/valid-bom-1.0.xml create mode 100644 tests/_data/schemaTestData/1.0/valid-component-hashes-1.0.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-component-ref-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-component-type-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-empty-component-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-hash-alg-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-hash-md5-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-hash-sha1-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-hash-sha256-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-hash-sha512-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-license-choice-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-license-encoding-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-license-id-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-license-id-count-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-license-name-count-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-missing-component-type-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-namespace-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-scope-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/invalid-serialnumber-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-bom-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-component-hashes-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-component-ref-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-component-types-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-empty-components-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-external-elements-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-license-expression-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-license-id-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-license-name-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-minimal-viable-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-random-attributes-1.1.xml create mode 100644 tests/_data/schemaTestData/1.1/valid-xml-signature-1.1.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-bomformat-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-type-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-component-type-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-dependency-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-dependency-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-empty-component-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-id-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-id-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-id-count-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-license-name-count-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-missing-component-type-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-namespace-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-scope-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-scope-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/invalid-service-data-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/invalid-service-data-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/skip_invalid-empty-component-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/skip_invalid-missing-component-type-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-assembly-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-assembly-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-bom-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-bom-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-component-ref-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-component-ref-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-component-swid-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-component-swid-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-component-types-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-component-types-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-dependency-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-dependency-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-empty-components-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-empty-components-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-external-elements-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-license-expression-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-license-expression-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-license-id-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-license-id-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-license-name-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-license-name-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-patch-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-patch-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-random-attributes-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-service-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-service-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.json create mode 100644 tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.xml create mode 100644 tests/_data/schemaTestData/1.2/valid-xml-signature-1.2.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-bomformat-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-type-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-component-type-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-dependency-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-dependency-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-id-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-id-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-id-count-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-license-name-count-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-namespace-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-scope-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-scope-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/invalid-service-data-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/invalid-service-data-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-assembly-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-assembly-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-bom-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-bom-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-component-ref-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-component-ref-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-component-swid-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-component-swid-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-component-types-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-component-types-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-compositions-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-compositions-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-dependency-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-dependency-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-empty-components-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-empty-components-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-evidence-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-evidence-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-external-elements-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-external-reference-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-external-reference-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-license-expression-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-license-expression-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-license-id-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-license-id-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-license-name-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-license-name-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-patch-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-patch-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-properties-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-properties-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-random-attributes-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-service-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-service-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.json create mode 100644 tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.xml create mode 100644 tests/_data/schemaTestData/1.3/valid-xml-signature-1.3.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-bomformat-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-type-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-component-type-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-dependency-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-dependency-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-id-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-id-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-id-count-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-license-name-count-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-namespace-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-scope-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-scope-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/invalid-service-data-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/invalid-service-data-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-assembly-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-assembly-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-bom-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-bom-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-component-ref-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-component-ref-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-component-swid-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-component-swid-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-component-types-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-component-types-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-compositions-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-compositions-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-dependency-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-dependency-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-empty-components-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-empty-components-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-evidence-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-evidence-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-external-elements-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-external-reference-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-external-reference-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-license-expression-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-license-expression-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-license-id-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-license-id-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-license-name-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-license-name-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-patch-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-patch-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-properties-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-properties-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-random-attributes-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-release-notes-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-release-notes-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-service-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-service-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-signatures-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.json create mode 100644 tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.xml create mode 100644 tests/_data/schemaTestData/1.4/valid-xml-signature-1.4.xml create mode 100644 tests/_data/schemaTestData/README.md create mode 100755 tests/_data/schemaTestData/fetch.sh create mode 100644 tests/_data/snapshots/.gitattributes rename tests/{fixtures => _data/snapshots}/README.md (100%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_275_components-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_for_issue_275_components-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_issue_275_components.json => _data/snapshots/get_bom_for_issue_275_components-1.2.json.bin} (79%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_275_components-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_issue_275_components.json => _data/snapshots/get_bom_for_issue_275_components-1.3.json.bin} (79%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_275_components-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_issue_275_components.json => _data/snapshots/get_bom_for_issue_275_components-1.4.json.bin} (71%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_275_components-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_for_issue_328_components-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_for_issue_328_components-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_issue_328_components.json => _data/snapshots/get_bom_for_issue_328_components-1.2.json.bin} (72%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_328_components-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_issue_328_components.json => _data/snapshots/get_bom_for_issue_328_components-1.3.json.bin} (72%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_328_components-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_issue_328_components.json => _data/snapshots/get_bom_for_issue_328_components-1.4.json.bin} (66%) create mode 100644 tests/_data/snapshots/get_bom_for_issue_328_components-1.4.xml.bin rename tests/{fixtures/xml/1.0/bom_empty.xml => _data/snapshots/get_bom_just_complete_metadata-1.0.xml.bin} (54%) create mode 100644 tests/_data/snapshots/get_bom_just_complete_metadata-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_with_full_metadata.json => _data/snapshots/get_bom_just_complete_metadata-1.2.json.bin} (76%) create mode 100644 tests/_data/snapshots/get_bom_just_complete_metadata-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_with_full_metadata.json => _data/snapshots/get_bom_just_complete_metadata-1.3.json.bin} (80%) create mode 100644 tests/_data/snapshots/get_bom_just_complete_metadata-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_with_full_metadata.json => _data/snapshots/get_bom_just_complete_metadata-1.4.json.bin} (79%) create mode 100644 tests/_data/snapshots/get_bom_just_complete_metadata-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_setuptools.json => _data/snapshots/get_bom_with_component_setuptools_basic-1.2.json.bin} (73%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_setuptools.json => _data/snapshots/get_bom_with_component_setuptools_basic-1.3.json.bin} (73%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools.json => _data/snapshots/get_bom_with_component_setuptools_basic-1.4.json.bin} (65%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_setuptools_complete.json => _data/snapshots/get_bom_with_component_setuptools_complete-1.2.json.bin} (75%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_setuptools_complete.json => _data/snapshots/get_bom_with_component_setuptools_complete-1.3.json.bin} (79%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools_complete.json => _data/snapshots/get_bom_with_component_setuptools_complete-1.4.json.bin} (81%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_setuptools_no_version.json => _data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.json.bin} (73%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_setuptools_no_version.json => _data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.json.bin} (73%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools_no_version.json => _data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.json.bin} (64%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_setuptools_with_cpe.json => _data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.json.bin} (74%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_setuptools_with_cpe.json => _data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.json.bin} (74%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools_with_cpe.json => _data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.json.bin} (66%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools_with_release_notes.json => _data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.json.bin} (77%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_setuptools_with_vulnerabilities.json => _data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.json.bin} (76%) create mode 100644 tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_toml_1-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_component_toml_1-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_toml_1.json => _data/snapshots/get_bom_with_component_toml_1-1.2.json.bin} (80%) create mode 100644 tests/_data/snapshots/get_bom_with_component_toml_1-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_toml_1.json => _data/snapshots/get_bom_with_component_toml_1-1.3.json.bin} (85%) create mode 100644 tests/_data/snapshots/get_bom_with_component_toml_1-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_toml_1.json => _data/snapshots/get_bom_with_component_toml_1-1.4.json.bin} (72%) create mode 100644 tests/_data/snapshots/get_bom_with_component_toml_1-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.xml.bin rename tests/{fixtures/json/1.4/bom_with_dependencies_hanging.json => _data/snapshots/get_bom_with_dependencies_hanging-1.3.json.bin} (72%) create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_valid-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_valid-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_dependencies.json => _data/snapshots/get_bom_with_dependencies_valid-1.2.json.bin} (69%) create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_dependencies.json => _data/snapshots/get_bom_with_dependencies_valid-1.3.json.bin} (74%) create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_dependencies.json => _data/snapshots/get_bom_with_dependencies_valid-1.4.json.bin} (70%) create mode 100644 tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_external_references-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_external_references-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_external_references.json => _data/snapshots/get_bom_with_external_references-1.2.json.bin} (64%) create mode 100644 tests/_data/snapshots/get_bom_with_external_references-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_external_references.json => _data/snapshots/get_bom_with_external_references-1.3.json.bin} (74%) create mode 100644 tests/_data/snapshots/get_bom_with_external_references-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_external_references.json => _data/snapshots/get_bom_with_external_references-1.4.json.bin} (65%) create mode 100644 tests/_data/snapshots/get_bom_with_external_references-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.2.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.3.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.3.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.4.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.2.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.3.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.3.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.4.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_licenses_expression-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_dependencies_component.json => _data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.json.bin} (69%) create mode 100644 tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_dependencies_component.json => _data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.json.bin} (73%) create mode 100644 tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_dependencies_component.json => _data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.json.bin} (67%) create mode 100644 tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.1.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.json.bin create mode 100644 tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_nested_services-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_nested_services-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_services_nested.json => _data/snapshots/get_bom_with_nested_services-1.2.json.bin} (86%) create mode 100644 tests/_data/snapshots/get_bom_with_nested_services-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_services_nested.json => _data/snapshots/get_bom_with_nested_services-1.3.json.bin} (77%) create mode 100644 tests/_data/snapshots/get_bom_with_nested_services-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_services_nested.json => _data/snapshots/get_bom_with_nested_services-1.4.json.bin} (77%) create mode 100644 tests/_data/snapshots/get_bom_with_nested_services-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_services_complex-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_services_complex-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_services_complex.json => _data/snapshots/get_bom_with_services_complex-1.2.json.bin} (79%) create mode 100644 tests/_data/snapshots/get_bom_with_services_complex-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_services_complex.json => _data/snapshots/get_bom_with_services_complex-1.3.json.bin} (74%) create mode 100644 tests/_data/snapshots/get_bom_with_services_complex-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_services_complex.json => _data/snapshots/get_bom_with_services_complex-1.4.json.bin} (75%) create mode 100644 tests/_data/snapshots/get_bom_with_services_complex-1.4.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_services_simple-1.0.xml.bin create mode 100644 tests/_data/snapshots/get_bom_with_services_simple-1.1.xml.bin rename tests/{fixtures/json/1.2/bom_services_simple.json => _data/snapshots/get_bom_with_services_simple-1.2.json.bin} (57%) create mode 100644 tests/_data/snapshots/get_bom_with_services_simple-1.2.xml.bin rename tests/{fixtures/json/1.3/bom_services_simple.json => _data/snapshots/get_bom_with_services_simple-1.3.json.bin} (57%) create mode 100644 tests/_data/snapshots/get_bom_with_services_simple-1.3.xml.bin rename tests/{fixtures/json/1.4/bom_services_simple.json => _data/snapshots/get_bom_with_services_simple-1.4.json.bin} (58%) create mode 100644 tests/_data/snapshots/get_bom_with_services_simple-1.4.xml.bin delete mode 100644 tests/base.py delete mode 100644 tests/fixtures/xml/1.0/bom_issue_275_components.xml delete mode 100644 tests/fixtures/xml/1.0/bom_issue_328_components.xml delete mode 100644 tests/fixtures/xml/1.0/bom_setuptools.xml delete mode 100644 tests/fixtures/xml/1.0/bom_setuptools_complete.xml delete mode 100644 tests/fixtures/xml/1.0/bom_setuptools_no_version.xml delete mode 100644 tests/fixtures/xml/1.0/bom_setuptools_with_cpe.xml delete mode 100644 tests/fixtures/xml/1.0/bom_toml_hashes_and_references.xml delete mode 100644 tests/fixtures/xml/1.1/bom_dependencies.xml delete mode 100644 tests/fixtures/xml/1.1/bom_empty.xml delete mode 100644 tests/fixtures/xml/1.1/bom_external_references.xml delete mode 100644 tests/fixtures/xml/1.1/bom_issue_275_components.xml delete mode 100644 tests/fixtures/xml/1.1/bom_issue_328_components.xml delete mode 100644 tests/fixtures/xml/1.1/bom_setuptools.xml delete mode 100644 tests/fixtures/xml/1.1/bom_setuptools_complete.xml delete mode 100644 tests/fixtures/xml/1.1/bom_setuptools_no_version.xml delete mode 100644 tests/fixtures/xml/1.1/bom_setuptools_with_cpe.xml delete mode 100644 tests/fixtures/xml/1.1/bom_setuptools_with_vulnerabilities.xml delete mode 100644 tests/fixtures/xml/1.1/bom_toml_hashes_and_references.xml delete mode 100644 tests/fixtures/xml/1.2/bom_dependencies.xml delete mode 100644 tests/fixtures/xml/1.2/bom_dependencies_component.xml delete mode 100644 tests/fixtures/xml/1.2/bom_external_references.xml delete mode 100644 tests/fixtures/xml/1.2/bom_issue_275_components.xml delete mode 100644 tests/fixtures/xml/1.2/bom_issue_328_components.xml delete mode 100644 tests/fixtures/xml/1.2/bom_services_complex.xml delete mode 100644 tests/fixtures/xml/1.2/bom_services_nested.xml delete mode 100644 tests/fixtures/xml/1.2/bom_services_simple.xml delete mode 100644 tests/fixtures/xml/1.2/bom_setuptools.xml delete mode 100644 tests/fixtures/xml/1.2/bom_setuptools_complete.xml delete mode 100644 tests/fixtures/xml/1.2/bom_setuptools_no_version.xml delete mode 100644 tests/fixtures/xml/1.2/bom_setuptools_with_cpe.xml delete mode 100644 tests/fixtures/xml/1.2/bom_setuptools_with_vulnerabilities.xml delete mode 100644 tests/fixtures/xml/1.2/bom_toml_hashes_and_references.xml delete mode 100644 tests/fixtures/xml/1.2/bom_with_full_metadata.xml delete mode 100644 tests/fixtures/xml/1.3/bom_dependencies.xml delete mode 100644 tests/fixtures/xml/1.3/bom_dependencies_component.xml delete mode 100644 tests/fixtures/xml/1.3/bom_external_references.xml delete mode 100644 tests/fixtures/xml/1.3/bom_issue_275_components.xml delete mode 100644 tests/fixtures/xml/1.3/bom_issue_328_components.xml delete mode 100644 tests/fixtures/xml/1.3/bom_services_complex.xml delete mode 100644 tests/fixtures/xml/1.3/bom_services_nested.xml delete mode 100644 tests/fixtures/xml/1.3/bom_services_simple.xml delete mode 100644 tests/fixtures/xml/1.3/bom_setuptools.xml delete mode 100644 tests/fixtures/xml/1.3/bom_setuptools_complete.xml delete mode 100644 tests/fixtures/xml/1.3/bom_setuptools_no_version.xml delete mode 100644 tests/fixtures/xml/1.3/bom_setuptools_with_cpe.xml delete mode 100644 tests/fixtures/xml/1.3/bom_setuptools_with_vulnerabilities.xml delete mode 100644 tests/fixtures/xml/1.3/bom_toml_hashes_and_references.xml delete mode 100644 tests/fixtures/xml/1.3/bom_with_full_metadata.xml delete mode 100644 tests/fixtures/xml/1.4/bom_dependencies.xml delete mode 100644 tests/fixtures/xml/1.4/bom_dependencies_component.xml delete mode 100644 tests/fixtures/xml/1.4/bom_external_references.xml delete mode 100644 tests/fixtures/xml/1.4/bom_issue_275_components.xml delete mode 100644 tests/fixtures/xml/1.4/bom_issue_328_components.xml delete mode 100644 tests/fixtures/xml/1.4/bom_services_complex.xml delete mode 100644 tests/fixtures/xml/1.4/bom_services_nested.xml delete mode 100644 tests/fixtures/xml/1.4/bom_services_simple.xml delete mode 100644 tests/fixtures/xml/1.4/bom_setuptools_complete.xml delete mode 100644 tests/fixtures/xml/1.4/bom_setuptools_no_version.xml delete mode 100644 tests/fixtures/xml/1.4/bom_setuptools_with_cpe.xml delete mode 100644 tests/fixtures/xml/1.4/bom_setuptools_with_release_notes.xml delete mode 100644 tests/fixtures/xml/1.4/bom_setuptools_with_vulnerabilities.xml delete mode 100644 tests/fixtures/xml/1.4/bom_toml_hashes_and_references.xml delete mode 100644 tests/fixtures/xml/1.4/bom_with_dependencies_hanging.xml delete mode 100644 tests/fixtures/xml/1.4/bom_with_full_metadata.xml delete mode 100644 tests/test_e2e_environment.py create mode 100644 tests/test_model_license.py create mode 100644 tests/test_output.py create mode 100644 tests/test_schema_SchemaVersion.py create mode 100644 tests/test_schema__res.py create mode 100644 tests/test_validation.py create mode 100644 tests/test_validation_json.py create mode 100644 tests/test_validation_xml.py create mode 100644 tools/schema-downloader.py diff --git a/.editorconfig b/.editorconfig index 17d087db..0b244df1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,7 +31,7 @@ trim_trailing_whitespace = false indent_style = space indent_size = 4 -[*.ini] +[{*.ini,.bandit,.flake8}] charset = latin1 indent_style = space indent_size = 4 diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..ff61f2bd --- /dev/null +++ b/.flake8 @@ -0,0 +1,20 @@ +[flake8] +## https://flake8.pycqa.org/en/latest/user/configuration.html +## keep in sync with isort config - in `isort.cfg` file + +exclude = + build,dist,__pycache__,.eggs,*.egg-info*, + *_cache,*.cache, + .git,.tox,.venv,venv,.venv*,venv*, + _OLD,_TEST, + docs + +max-line-length = 120 + +max-complexity = 10 + +ignore = + # ignore `self`, `cls` markers of flake8-annotations>=2.0 + ANN101,ANN102 + # ignore ANN401 for dynamically typed *args and **kwargs + ANN401 diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index ebb67faa..be8b5813 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -46,24 +46,48 @@ jobs: - name: Install dependencies run: poetry install --no-root - name: Run tox - run: poetry run tox -e flake8 -s false + run: poetry run tox run -e flake8 -s false + + security-issues: + name: find Security Issues + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@v4 + - name: Setup Python Environment + # see https://github.com/actions/setup-python + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION_DEFAULT }} + architecture: 'x64' + - name: Install poetry + # see https://github.com/marketplace/actions/setup-poetry + uses: Gr1N/setup-poetry@v8 + with: + poetry-version: ${{ env.POETRY_VERSION }} + - name: Install dependencies + run: poetry install --no-root + - name: Run tox + run: poetry run tox run -e bandit -s false static-code-analysis: - name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factor }}) + name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factors }}) runs-on: ${{ matrix.os }} timeout-minutes: 10 strategy: fail-fast: false matrix: include: - - # test with the locked dependencies + - # test with the latest dependencies os: ubuntu-latest - python-version: '3.11' - toxenv-factor: 'locked' + python-version: '3.12' + toxenv-factors: '-current' - # test with the lowest dependencies os: ubuntu-latest - python-version: '3.7' - toxenv-factor: 'lowest' + python-version: '3.8' + toxenv-factors: '-lowest' steps: - name: Checkout # see https://github.com/actions/checkout @@ -82,10 +106,10 @@ jobs: - name: Install dependencies run: poetry install --no-root - name: Run tox - run: poetry run tox -e mypy-${{ matrix.toxenv-factor }} -s false + run: poetry run tox run -e mypy${{ matrix.toxenv-factors }} -s false build-and-test: - name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factor }}) + name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factors }}) runs-on: ${{ matrix.os }} timeout-minutes: 15 strategy: @@ -93,17 +117,14 @@ jobs: matrix: os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] python-version: - - "3.11" # highest supported + - "3.12" # highest supported + - "3.11" - "3.10" - "3.9" - - "3.8" - - "3.7" # lowest supported - toxenv-factor: ['locked'] - include: - - # test with the lowest dependencies - os: ubuntu-latest - python-version: '3.7' - toxenv-factor: 'lowest' + - "3.8" # lowest supported + toxenv-factors: + - '-allExtras' + - '-noExtras' steps: - name: Disabled Git auto EOL CRLF transforms run: | @@ -135,14 +156,14 @@ jobs: - name: Ensure build successful run: poetry build - name: Run tox - run: poetry run tox -e py-${{ matrix.toxenv-factor }} -s false + run: poetry run tox run -e py${{ matrix.toxenv-factors }} -s false - name: Generate coverage reports + if: ${{ failure() || success() }} shell: bash run: | set -eux - poetry run coverage report - poetry run coverage xml -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.cobertura.xml" - # poetry run coverage lcov -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.lcov.xml" + poetry run coverage report -m + poetry run coverage xml -o '${{ env.REPORTS_DIR }}/coverage/${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factors }}.cobertura.xml' - name: Artifact reports if: ${{ ! cancelled() }} # see https://github.com/actions/upload-artifact @@ -172,12 +193,19 @@ jobs: uses: codacy/codacy-coverage-reporter-action@v1 with: project-token: ${{ env.CODACY_PROJECT_TOKEN }} - coverage-reports: ${{ env.REPORTS_DIR }}/coverage.* + coverage-reports: ${{ env.REPORTS_DIR }}/coverage/* examples: - name: Examples + name: Examples E:${{ matrix.install-extras || '' }} runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + install-extras: + - '' # none + - json-validation + - xml-validation steps: - name: Checkout # see https://github.com/actions/checkout @@ -186,7 +214,7 @@ jobs: # see https://github.com/actions/setup-python uses: actions/setup-python@v4 with: - python-version: '>=3.7 <=3.11' # supported version range + python-version: '>=3.8 <=3.12' # supported version range - name: Validate Python Environment shell: python run: | @@ -198,7 +226,7 @@ jobs: with: poetry-version: ${{ env.POETRY_VERSION }} - name: Install package and prod dependencies - run: poetry install --only=main -vvv + run: poetry install --only=main --extras='${{ matrix.install-extras }}' -vvv - name: run all examples run: > find examples -type f -name '*.py' -print0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bc3415e2..c770a7c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,31 @@ env: POETRY_VERSION: "1.4.1" jobs: + quicktest: + runs-on: ubuntu-latest + steps: + - name: Checkout code + # see https://github.com/actions/checkout + uses: actions/checkout@v4 + - name: Setup Python Environment + # see https://github.com/actions/setup-python + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION_DEFAULT }} + architecture: 'x64' + - name: Install poetry + # see https://github.com/marketplace/actions/setup-poetry + uses: Gr1N/setup-poetry@v8 + with: + poetry-version: ${{ env.POETRY_VERSION }} + - name: Install dependencies + run: poetry install --no-root + - name: Run tox + run: poetry run tox run -e py -s false + release: + needs: + - quicktest # https://github.community/t/how-do-i-specify-job-dependency-running-in-another-workflow/16482 # limit this to being run on regular commits, not the commits that semantic-release will create # but also allow manual workflow dispatch diff --git a/.isort.cfg b/.isort.cfg index 2b28db04..85e125dc 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,6 +1,6 @@ [settings] ## read the docs: https://pycqa.github.io/isort/docs/configuration/options.html -## keep in sync with flake8 config - in `tox.ini` file +## keep in sync with flake8 config - in `.flake8` file known_first_party = cyclonedx skip_gitignore = false skip_glob = @@ -20,3 +20,5 @@ src_paths = cyclonedx tests typings + examples + tools diff --git a/.mypy.ini b/.mypy.ini index f3dc121d..f86c1953 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,6 +1,6 @@ [mypy] -files = cyclonedx/ +files = cyclonedx/, examples/ mypy_path = $MYPY_CONFIG_FILE_DIR/typings show_error_codes = True @@ -26,9 +26,7 @@ no_implicit_optional = True warn_redundant_casts = True warn_return_any = True no_implicit_reexport = True - -# needed to silence some py37|py38 differences -warn_unused_ignores = False +warn_unused_ignores = True [mypy-pytest.*] ignore_missing_imports = True diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 2249d149..18c0946d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -42,4 +40,4 @@ python: install: - method: pip path: . - - requirements: docs/requirements.txt \ No newline at end of file + - requirements: docs/requirements.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c0275f2..8b8a5a2a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ This project uses [poetry]. Have it installed and setup first. To install dev-dependencies and tools: ```shell -poetry install +poetry install --all-extras ``` ## Code style @@ -23,9 +23,13 @@ Get it all applied via: ```shell poetry run isort . -poetry run flake8 cyclonedx/ tests/ typings/ +poetry run autopep8 -ir cyclonedx/ tests/ typings/ examples/ ``` +This project prefers `f'strings'` over `'string'.format()`. +This project prefers `'single quotes'` over `"double quotes"`. +This project prefers `lower_snake_case` variable names. + ## Documentation This project uses [Sphinx] to generate documentation which is automatically published to [readthedocs.io]. @@ -45,7 +49,7 @@ make html Run all tests in dedicated environments, via: ```shell -poetry run tox +poetry run tox run ``` ## Sign off your commits diff --git a/README.md b/README.md index 980cb80b..42c39644 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Python Library for generating CycloneDX +# CycloneDX Python Library [![shield_pypi-version]][link_pypi] [![shield_conda-forge-version]][link_conda-forge] diff --git a/bandit.yml b/bandit.yml new file mode 100644 index 00000000..03d6ead6 --- /dev/null +++ b/bandit.yml @@ -0,0 +1,9 @@ +# https://bandit.readthedocs.io +# filename must be like this, so codacy can pick it up: https://github.com/codacy/codacy-bandit/blob/master/src/main/scala/codacy/bandit/Bandit.scala#L35C49-L35C59 + +exclude_dirs: + - docs + - .venv + +skips: + - B101 diff --git a/cyclonedx/__init__.py b/cyclonedx/__init__.py index 14f49baa..b737880f 100644 --- a/cyclonedx/__init__.py +++ b/cyclonedx/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,6 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Python library for generating and representing CycloneDX software bill-of-materials. @@ -20,4 +20,5 @@ # !! version is managed by semantic_release # do not use typing here, or else `semantic_release` might have issues finding the variable -__version__ = "4.2.3" +# flake8: noqa +__version__ = "5.0.0-rc.2" diff --git a/cyclonedx/exception/__init__.py b/cyclonedx/exception/__init__.py index dc915bfb..ef1ce340 100644 --- a/cyclonedx/exception/__init__.py +++ b/cyclonedx/exception/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,15 +11,21 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 -# +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Exceptions that are specific to the CycloneDX library implementation. """ -class CycloneDxException(Exception): +class CycloneDxException(Exception): # noqa: N818 """ Root exception thrown by this library. """ pass + + +class MissingOptionalDependencyException(CycloneDxException): # noqa: N818 + """Validation did not happen, due to missing dependencies.""" + pass diff --git a/cyclonedx/exception/factory.py b/cyclonedx/exception/factory.py index 87540f85..322e1fc3 100644 --- a/cyclonedx/exception/factory.py +++ b/cyclonedx/exception/factory.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,7 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 -# +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Exceptions relating to specific conditions that occur when factoring a model. diff --git a/cyclonedx/exception/model.py b/cyclonedx/exception/model.py index 43b3045d..05633e24 100644 --- a/cyclonedx/exception/model.py +++ b/cyclonedx/exception/model.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,7 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 -# +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Exceptions relating to specific conditions that occur when modelling CycloneDX BOM. @@ -73,6 +72,7 @@ class UnknownComponentDependencyException(CycloneDxModelException): """ Exception raised when a dependency has been noted for a Component that is NOT a Component BomRef in this Bom. """ + pass class UnknownHashTypeException(CycloneDxModelException): @@ -80,3 +80,13 @@ class UnknownHashTypeException(CycloneDxModelException): Exception raised when we are unable to determine the type of hash from a composite hash string. """ pass + + +class LicenseExpressionAlongWithOthersException(CycloneDxModelException): + """ + Exception raised when a LicenseExpression was detected along with other licenses. + If a LicenseExpression exists, than it must stand alone. + + See https://github.com/CycloneDX/specification/pull/205 + """ + pass diff --git a/cyclonedx/exception/output.py b/cyclonedx/exception/output.py index 4dbb7078..c3109f13 100644 --- a/cyclonedx/exception/output.py +++ b/cyclonedx/exception/output.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,7 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 -# +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Exceptions that are for specific error scenarios during the output of a Model to a SBOM. diff --git a/cyclonedx/factory/__init__.py b/cyclonedx/factory/__init__.py index 4cf62cdc..50e0bf37 100644 --- a/cyclonedx/factory/__init__.py +++ b/cyclonedx/factory/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 diff --git a/cyclonedx/factory/license.py b/cyclonedx/factory/license.py index 5d21c012..d6446569 100644 --- a/cyclonedx/factory/license.py +++ b/cyclonedx/factory/license.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -15,76 +13,59 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from typing import Optional +from typing import TYPE_CHECKING, Optional from ..exception.factory import InvalidLicenseExpressionException, InvalidSpdxLicenseException -from ..model import AttachedText, License, LicenseChoice, XsUri +from ..model.license import DisjunctiveLicense, LicenseExpression from ..spdx import fixup_id as spdx_fixup, is_compound_expression as is_spdx_compound_expression +if TYPE_CHECKING: # pragma: no cover + from ..model import AttachedText, XsUri + from ..model.license import License -class LicenseFactory: - """Factory for :class:`cyclonedx.model.License`.""" - - def make_from_string(self, name_or_spdx: str, *, - license_text: Optional[AttachedText] = None, - license_url: Optional[XsUri] = None) -> License: - """Make a :class:`cyclonedx.model.License` from a string.""" - try: - return self.make_with_id(name_or_spdx, text=license_text, url=license_url) - except InvalidSpdxLicenseException: - return self.make_with_name(name_or_spdx, text=license_text, url=license_url) - - def make_with_id(self, spdx_id: str, *, text: Optional[AttachedText] = None, - url: Optional[XsUri] = None) -> License: - """Make a :class:`cyclonedx.model.License` from an SPDX-ID. - - :raises InvalidSpdxLicenseException: if `spdx_id` was not known/supported SPDX-ID - """ - spdx_license_id = spdx_fixup(spdx_id) - if spdx_license_id is None: - raise InvalidSpdxLicenseException(spdx_id) - return License(id=spdx_license_id, text=text, url=url) - - def make_with_name(self, name: str, *, text: Optional[AttachedText] = None, url: Optional[XsUri] = None) -> License: - """Make a :class:`cyclonedx.model.License` with a name.""" - return License(name=name, text=text, url=url) +class LicenseFactory: + """Factory for :class:`cyclonedx.model.license.License`.""" -class LicenseChoiceFactory: - """Factory for :class:`cyclonedx.model.LicenseChoice`.""" - - def __init__(self, *, license_factory: LicenseFactory) -> None: - self.license_factory = license_factory - - def make_from_string(self, expression_or_name_or_spdx: str) -> LicenseChoice: - """Make a :class:`cyclonedx.model.LicenseChoice` from a string. - - Priority: SPDX license ID, SPDX license expression, named license - """ + def make_from_string(self, value: str, *, + license_text: Optional['AttachedText'] = None, + license_url: Optional['XsUri'] = None) -> 'License': + """Make a :class:`cyclonedx.model.license.License` from a string.""" try: - return LicenseChoice(license=self.license_factory.make_with_id(expression_or_name_or_spdx)) + return self.make_with_id(value, text=license_text, url=license_url) except InvalidSpdxLicenseException: pass try: - return self.make_with_compound_expression(expression_or_name_or_spdx) + return self.make_with_expression(value) except InvalidLicenseExpressionException: pass - return LicenseChoice(license=self.license_factory.make_with_name(expression_or_name_or_spdx)) + return self.make_with_name(value, text=license_text, url=license_url) - def make_with_compound_expression(self, compound_expression: str) -> LicenseChoice: - """Make a :class:`cyclonedx.model.LicenseChoice` with a compound expression. + def make_with_expression(self, expression: str) -> LicenseExpression: + """Make a :class:`cyclonedx.model.license.LicenseExpression` with a compound expression. Utilizes :func:`cyclonedx.spdx.is_compound_expression`. - :raises InvalidLicenseExpressionException: if `expression` is not known/supported license expression + :raises InvalidLicenseExpressionException: if param `value` is not known/supported license expression """ - if is_spdx_compound_expression(compound_expression): - return LicenseChoice(expression=compound_expression) - raise InvalidLicenseExpressionException(compound_expression) + if is_spdx_compound_expression(expression): + return LicenseExpression(expression) + raise InvalidLicenseExpressionException(expression) + + def make_with_id(self, spdx_id: str, *, + text: Optional['AttachedText'] = None, + url: Optional['XsUri'] = None) -> DisjunctiveLicense: + """Make a :class:`cyclonedx.model.license.DisjunctiveLicense` from an SPDX-ID. + + :raises InvalidSpdxLicenseException: if param `spdx_id` was not known/supported SPDX-ID + """ + spdx_license_id = spdx_fixup(spdx_id) + if spdx_license_id is None: + raise InvalidSpdxLicenseException(spdx_id) + return DisjunctiveLicense(id=spdx_license_id, text=text, url=url) - def make_with_license(self, name_or_spdx: str, *, - license_text: Optional[AttachedText] = None, - license_url: Optional[XsUri] = None) -> LicenseChoice: - """Make a :class:`cyclonedx.model.LicenseChoice` with a license (name or SPDX-ID).""" - return LicenseChoice(license=self.license_factory.make_from_string( - name_or_spdx, license_text=license_text, license_url=license_url)) + def make_with_name(self, name: str, *, + text: Optional['AttachedText'] = None, + url: Optional['XsUri'] = None) -> DisjunctiveLicense: + """Make a :class:`cyclonedx.model.license.DisjunctiveLicense` with a name.""" + return DisjunctiveLicense(name=name, text=text, url=url) diff --git a/cyclonedx/model/__init__.py b/cyclonedx/model/__init__.py index 59b45cca..5441049c 100644 --- a/cyclonedx/model/__init__.py +++ b/cyclonedx/model/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -15,21 +13,20 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -import hashlib import re -import warnings from datetime import datetime, timezone from enum import Enum +from hashlib import sha1 +from itertools import zip_longest from typing import Any, Iterable, Optional, Tuple, TypeVar import serializable from sortedcontainers import SortedSet -from .. import __version__ as __ThisToolVersion +from .. import __version__ as __ThisToolVersion # noqa: N812 from ..exception.model import ( InvalidLocaleTypeException, InvalidUriException, - MutuallyExclusivePropertiesException, NoPropertiesProvidedException, UnknownHashTypeException, ) @@ -58,9 +55,9 @@ def sha1sum(filename: str) -> str: Returns: SHA-1 hash """ - h = hashlib.sha1() + h = sha1() # nosec B303, B324 with open(filename, 'rb') as f: - for byte_block in iter(lambda: f.read(4096), b""): + for byte_block in iter(lambda: f.read(4096), b''): h.update(byte_block) return h.hexdigest() @@ -74,31 +71,27 @@ class ComparableTuple(Tuple[Optional[_T], ...]): """ def __lt__(self, other: Any) -> bool: - for s, o in zip(self, other): + for s, o in zip_longest(self, other): if s == o: continue + # the idea is to have any consistent order, not necessarily "natural" order. if s is None: return False if o is None: return True - if s < o: - return True - if s > o: - return False + return True if s < o else False return False def __gt__(self, other: Any) -> bool: - for s, o in zip(self, other): + for s, o in zip_longest(self, other): if s == o: continue + # the idea is to have any consistent order, not necessarily "natural" order. if s is None: return True if o is None: return False - if s < o: - return False - if s > o: - return True + return True if s > o else False return False @@ -109,10 +102,10 @@ class DataFlow(str, Enum): .. note:: See the CycloneDX Schema: https://cyclonedx.org/docs/1.4/xml/#type_dataFlowType """ - INBOUND = "inbound" - OUTBOUND = "outbound" - BI_DIRECTIONAL = "bi-directional" - UNKNOWN = "unknown" + INBOUND = 'inbound' + OUTBOUND = 'outbound' + BI_DIRECTIONAL = 'bi-directional' + UNKNOWN = 'unknown' @serializable.serializable_class @@ -129,7 +122,7 @@ def __init__(self, *, flow: DataFlow, classification: str) -> None: self.flow = flow self.classification = classification - @property # type: ignore[misc] + @property @serializable.xml_attribute() def flow(self) -> DataFlow: """ @@ -153,7 +146,7 @@ def flow(self) -> DataFlow: def flow(self, flow: DataFlow) -> None: self._flow = flow - @property # type: ignore[misc] + @property @serializable.xml_name('.') def classification(self) -> str: """ @@ -207,7 +200,7 @@ def __init__(self, *, content: str, content_type: str = DEFAULT_CONTENT_TYPE, self.encoding = encoding self.content = content - @property # type: ignore[misc] + @property @serializable.xml_attribute() @serializable.xml_name('content-type') def content_type(self) -> str: @@ -223,7 +216,7 @@ def content_type(self) -> str: def content_type(self, content_type: str) -> None: self._content_type = content_type - @property # type: ignore[misc] + @property @serializable.xml_attribute() def encoding(self) -> Optional[Encoding]: """ @@ -238,7 +231,7 @@ def encoding(self) -> Optional[Encoding]: def encoding(self, encoding: Optional[Encoding]) -> None: self._encoding = encoding - @property # type: ignore[misc] + @property @serializable.xml_name('.') def content(self) -> str: """ @@ -332,22 +325,22 @@ def from_composite_str(composite_hash: str) -> 'HashType': ) elif algorithm_prefix[0:3] == 'sha': return HashType( - alg=getattr(HashAlgorithm, 'SHA_{}'.format(algorithm_prefix[3:])), + alg=getattr(HashAlgorithm, f'SHA_{algorithm_prefix[3:]}'), content=parts[1].lower() ) elif algorithm_prefix[0:6] == 'blake2': return HashType( - alg=getattr(HashAlgorithm, 'BLAKE2b_{}'.format(algorithm_prefix[6:])), + alg=getattr(HashAlgorithm, f'BLAKE2b_{algorithm_prefix[6:]}'), content=parts[1].lower() ) - raise UnknownHashTypeException(f"Unable to determine hash type from '{composite_hash}'") + raise UnknownHashTypeException(f'Unable to determine hash type from {composite_hash!r}') def __init__(self, *, alg: HashAlgorithm, content: str) -> None: self.alg = alg self.content = content - @property # type: ignore[misc] + @property @serializable.xml_attribute() def alg(self) -> HashAlgorithm: """ @@ -362,7 +355,7 @@ def alg(self) -> HashAlgorithm: def alg(self, alg: HashAlgorithm) -> None: self._alg = alg - @property # type: ignore[misc] + @property @serializable.xml_name('.') def content(self) -> str: """ @@ -442,27 +435,26 @@ def __init__(self, uri: str) -> None: ) self._uri = uri - @property # type: ignore[misc] + @property @serializable.json_name('.') @serializable.xml_name('.') def uri(self) -> str: return self._uri @classmethod - def serialize(cls, o: object) -> str: + def serialize(cls, o: Any) -> str: if isinstance(o, XsUri): return str(o) - raise ValueError(f'Attempt to serialize a non-XsUri: {o.__class__}') @classmethod - def deserialize(cls, o: object) -> 'XsUri': + def deserialize(cls, o: Any) -> 'XsUri': try: return XsUri(uri=str(o)) except ValueError: raise ValueError(f'XsUri string supplied ({o}) does not parse!') - def __eq__(self, other: object) -> bool: + def __eq__(self, other: Any) -> bool: if isinstance(other, XsUri): return hash(other) == hash(self) return False @@ -499,7 +491,7 @@ def __init__(self, *, type: ExternalReferenceType, url: XsUri, comment: Optional self.type = type self.hashes = hashes or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def url(self) -> XsUri: """ @@ -528,7 +520,7 @@ def comment(self) -> Optional[str]: def comment(self, comment: Optional[str]) -> None: self._comment = comment - @property # type: ignore[misc] + @property @serializable.xml_attribute() def type(self) -> ExternalReferenceType: """ @@ -546,11 +538,11 @@ def type(self) -> ExternalReferenceType: def type(self, type: ExternalReferenceType) -> None: self._type = type - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'hash') - def hashes(self) -> "SortedSet[HashType]": + def hashes(self) -> 'SortedSet[HashType]': """ The hashes of the external reference (if applicable). @@ -584,181 +576,6 @@ def __repr__(self) -> str: return f'' -@serializable.serializable_class -class License: - """ - This is our internal representation of `licenseType` complex type that can be used in multiple places within - a CycloneDX BOM document. - - .. note:: - See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.4/xml/#type_licenseType - """ - - def __init__(self, *, id: Optional[str] = None, name: Optional[str] = None, - text: Optional[AttachedText] = None, url: Optional[XsUri] = None) -> None: - if not id and not name: - raise MutuallyExclusivePropertiesException('Either `id` or `name` MUST be supplied') - if id and name: - warnings.warn( - 'Both `id` and `name` have been supplied - `name` will be ignored!', - RuntimeWarning - ) - self.id = id - if not id: - self.name = name - else: - self.name = None - self.text = text - self.url = url - - @property - def id(self) -> Optional[str]: - """ - A valid SPDX license ID - - Returns: - `str` or `None` - """ - return self._id - - @id.setter - def id(self, id: Optional[str]) -> None: - self._id = id - - @property - def name(self) -> Optional[str]: - """ - If SPDX does not define the license used, this field may be used to provide the license name. - - Returns: - `str` or `None` - """ - return self._name - - @name.setter - def name(self, name: Optional[str]) -> None: - self._name = name - - @property - def text(self) -> Optional[AttachedText]: - """ - Specifies the optional full text of the attachment - - Returns: - `AttachedText` else `None` - """ - return self._text - - @text.setter - def text(self, text: Optional[AttachedText]) -> None: - self._text = text - - @property - def url(self) -> Optional[XsUri]: - """ - The URL to the attachment file. If the attachment is a license or BOM, an externalReference should also be - specified for completeness. - - Returns: - `XsUri` or `None` - """ - return self._url - - @url.setter - def url(self, url: Optional[XsUri]) -> None: - self._url = url - - def __eq__(self, other: object) -> bool: - if isinstance(other, License): - return hash(other) == hash(self) - return False - - def __lt__(self, other: Any) -> bool: - if isinstance(other, License): - return ComparableTuple((self.id, self.name)) < ComparableTuple((other.id, other.name)) - return NotImplemented - - def __hash__(self) -> int: - return hash((self.id, self.name, self.text, self.url)) - - def __repr__(self) -> str: - return f'' - - -@serializable.serializable_class -class LicenseChoice: - """ - This is our internal representation of `licenseChoiceType` complex type that can be used in multiple places within - a CycloneDX BOM document. - - .. note:: - See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.4/xml/#type_licenseChoiceType - """ - - def __init__(self, *, license: Optional[License] = None, expression: Optional[str] = None) -> None: - if not license and not expression: - raise NoPropertiesProvidedException( - 'One of `license` or `expression` must be supplied - neither supplied' - ) - if license and expression: - warnings.warn( - 'Both `license` and `expression` have been supplied - `license` will take precedence', - RuntimeWarning - ) - self.license = license - if not license: - self.expression = expression - else: - self.expression = None - - @property - def license(self) -> Optional[License]: - """ - License definition - - Returns: - `License` or `None` - """ - return self._license - - @license.setter - def license(self, license: Optional[License]) -> None: - self._license = license - - @property - def expression(self) -> Optional[str]: - """ - A valid SPDX license expression (not enforced). - - Refer to https://spdx.org/specifications for syntax requirements. - - Returns: - `str` or `None` - """ - return self._expression - - @expression.setter - def expression(self, expression: Optional[str]) -> None: - self._expression = expression - - def __eq__(self, other: object) -> bool: - if isinstance(other, LicenseChoice): - return hash(other) == hash(self) - return False - - def __lt__(self, other: Any) -> bool: - if isinstance(other, LicenseChoice): - return ComparableTuple((self.license, self.expression)) < ComparableTuple( - (other.license, other.expression)) - return NotImplemented - - def __hash__(self) -> int: - return hash((self.license, self.expression)) - - def __repr__(self) -> str: - return f'' - - @serializable.serializable_class class Property: """ @@ -775,7 +592,7 @@ def __init__(self, *, name: str, value: str) -> None: self.name = name self.value = value - @property # type: ignore[misc] + @property @serializable.xml_attribute() def name(self) -> str: """ @@ -792,7 +609,7 @@ def name(self) -> str: def name(self, name: str) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_name('.') def value(self) -> str: """ @@ -842,7 +659,7 @@ def __init__(self, *, content: str, content_type: Optional[str] = None, self.content_type = content_type or NoteText.DEFAULT_CONTENT_TYPE self.encoding = encoding - @property # type: ignore[misc] + @property @serializable.xml_name('.') def content(self) -> str: """ @@ -857,7 +674,7 @@ def content(self) -> str: def content(self, content: str) -> None: self._content = content - @property # type: ignore[misc] + @property @serializable.xml_attribute() @serializable.xml_name('content-type') def content_type(self) -> Optional[str]: @@ -875,7 +692,7 @@ def content_type(self) -> Optional[str]: def content_type(self, content_type: str) -> None: self._content_type = content_type - @property # type: ignore[misc] + @property @serializable.xml_attribute() def encoding(self) -> Optional[Encoding]: """ @@ -940,7 +757,7 @@ def text(self) -> NoteText: def text(self, text: NoteText) -> None: self._text = text - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def locale(self) -> Optional[str]: """ @@ -962,9 +779,9 @@ def locale(self, locale: Optional[str]) -> None: if not re.search(Note._LOCALE_TYPE_REGEX, locale): self._locale = None raise InvalidLocaleTypeException( - f"Supplied locale '{locale}' is not a valid locale. " - f"Locale string should be formatted as the ISO-639 (or higher) language code and optional " - f"ISO-3166 (or higher) country code. according to ISO-639 format. Examples include: 'en', 'en-US'." + f'Supplied locale {locale!r} is not a valid locale.' + ' Locale string should be formatted as the ISO-639 (or higher) language code and optional' + " ISO-3166 (or higher) country code. according to ISO-639 format. Examples include: 'en', 'en-US'." ) def __eq__(self, other: object) -> bool: @@ -1003,7 +820,7 @@ def __init__(self, *, name: Optional[str] = None, phone: Optional[str] = None, e self.email = email self.phone = phone - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def name(self) -> Optional[str]: """ @@ -1018,7 +835,7 @@ def name(self) -> Optional[str]: def name(self, name: Optional[str]) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def email(self) -> Optional[str]: """ @@ -1033,7 +850,7 @@ def email(self) -> Optional[str]: def email(self, email: Optional[str]) -> None: self._email = email - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def phone(self) -> Optional[str]: """ @@ -1086,7 +903,7 @@ def __init__(self, *, name: Optional[str] = None, urls: Optional[Iterable[XsUri] self.urls = urls or [] # type: ignore self.contacts = contacts or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def name(self) -> Optional[str]: """ @@ -1101,11 +918,11 @@ def name(self) -> Optional[str]: def name(self, name: Optional[str]) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.json_name('url') @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'url') @serializable.xml_sequence(2) - def urls(self) -> "SortedSet[XsUri]": + def urls(self) -> 'SortedSet[XsUri]': """ Get a list of URLs of the organization. Multiple URLs are allowed. @@ -1118,11 +935,11 @@ def urls(self) -> "SortedSet[XsUri]": def urls(self, urls: Iterable[XsUri]) -> None: self._urls = SortedSet(urls) - @property # type: ignore[misc] + @property @serializable.json_name('contact') @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'contact') @serializable.xml_sequence(3) - def contacts(self) -> "SortedSet[OrganizationalContact]": + def contacts(self) -> 'SortedSet[OrganizationalContact]': """ Get a list of contact person at the organization. Multiple contacts are allowed. @@ -1172,7 +989,7 @@ def __init__(self, *, vendor: Optional[str] = None, name: Optional[str] = None, self.hashes = hashes or [] # type: ignore self.external_references = external_references or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def vendor(self) -> Optional[str]: """ @@ -1187,7 +1004,7 @@ def vendor(self) -> Optional[str]: def vendor(self, vendor: Optional[str]) -> None: self._vendor = vendor - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def name(self) -> Optional[str]: """ @@ -1202,7 +1019,7 @@ def name(self) -> Optional[str]: def name(self, name: Optional[str]) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def version(self) -> Optional[str]: """ @@ -1217,10 +1034,10 @@ def version(self) -> Optional[str]: def version(self, version: Optional[str]) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'hash') @serializable.xml_sequence(4) - def hashes(self) -> "SortedSet[HashType]": + def hashes(self) -> 'SortedSet[HashType]': """ The hashes of the tool (if applicable). @@ -1233,11 +1050,11 @@ def hashes(self) -> "SortedSet[HashType]": def hashes(self, hashes: Iterable[HashType]) -> None: self._hashes = SortedSet(hashes) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference') @serializable.xml_sequence(5) - def external_references(self) -> "SortedSet[ExternalReference]": + def external_references(self) -> 'SortedSet[ExternalReference]': """ External References provide a way to document systems, sites, and information that may be relevant but which are not included with the BOM. @@ -1289,7 +1106,7 @@ def __init__(self, *, timestamp: Optional[datetime] = None, name: Optional[str] self.name = name self.email = email - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) def timestamp(self) -> Optional[datetime]: """ @@ -1362,7 +1179,7 @@ class Copyright: def __init__(self, *, text: str) -> None: self.text = text - @property # type: ignore[misc] + @property @serializable.xml_name('.') def text(self) -> str: """ diff --git a/cyclonedx/model/bom.py b/cyclonedx/model/bom.py index 25ed9e4e..f1e642db 100644 --- a/cyclonedx/model/bom.py +++ b/cyclonedx/model/bom.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,17 +14,18 @@ # # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. + + import warnings from datetime import datetime -from typing import TYPE_CHECKING, Iterable, Optional, Set +from itertools import chain +from typing import TYPE_CHECKING, Iterable, Optional, Set, Union from uuid import UUID, uuid4 import serializable from sortedcontainers import SortedSet -from cyclonedx.serialization import UrnUuidHelper - -from ..exception.model import UnknownComponentDependencyException +from ..exception.model import LicenseExpressionAlongWithOthersException, UnknownComponentDependencyException from ..parser import BaseParser from ..schema.schema import ( SchemaVersion1Dot0, @@ -35,23 +34,16 @@ SchemaVersion1Dot3, SchemaVersion1Dot4, ) -from . import ( - ExternalReference, - LicenseChoice, - OrganizationalContact, - OrganizationalEntity, - Property, - ThisTool, - Tool, - get_now_utc, -) +from ..serialization import LicenseRepositoryHelper, UrnUuidHelper +from . import ExternalReference, OrganizationalContact, OrganizationalEntity, Property, ThisTool, Tool, get_now_utc from .bom_ref import BomRef from .component import Component from .dependency import Dependable, Dependency +from .license import License, LicenseExpression, LicenseRepository from .service import Service from .vulnerability import Vulnerability -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: no cover from packageurl import PackageURL @@ -68,7 +60,7 @@ def __init__(self, *, tools: Optional[Iterable[Tool]] = None, authors: Optional[Iterable[OrganizationalContact]] = None, component: Optional[Component] = None, manufacture: Optional[OrganizationalEntity] = None, supplier: Optional[OrganizationalEntity] = None, - licenses: Optional[Iterable[LicenseChoice]] = None, + licenses: Optional[Iterable[License]] = None, properties: Optional[Iterable[Property]] = None, timestamp: Optional[datetime] = None) -> None: self.timestamp = timestamp or get_now_utc() @@ -83,7 +75,7 @@ def __init__(self, *, tools: Optional[Iterable[Tool]] = None, if not tools: self.tools.add(ThisTool) - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) @serializable.xml_sequence(1) def timestamp(self) -> datetime: @@ -99,10 +91,10 @@ def timestamp(self) -> datetime: def timestamp(self, timestamp: datetime) -> None: self._timestamp = timestamp - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'tool') @serializable.xml_sequence(2) - def tools(self) -> "SortedSet[Tool]": + def tools(self) -> 'SortedSet[Tool]': """ Tools used to create this BOM. @@ -115,10 +107,10 @@ def tools(self) -> "SortedSet[Tool]": def tools(self, tools: Iterable[Tool]) -> None: self._tools = SortedSet(tools) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'author') @serializable.xml_sequence(3) - def authors(self) -> "SortedSet[OrganizationalContact]": + def authors(self) -> 'SortedSet[OrganizationalContact]': """ The person(s) who created the BOM. @@ -135,7 +127,7 @@ def authors(self) -> "SortedSet[OrganizationalContact]": def authors(self, authors: Iterable[OrganizationalContact]) -> None: self._authors = SortedSet(authors) - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def component(self) -> Optional[Component]: """ @@ -160,7 +152,7 @@ def component(self, component: Component) -> None: """ self._component = component - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def manufacture(self) -> Optional[OrganizationalEntity]: """ @@ -175,7 +167,7 @@ def manufacture(self) -> Optional[OrganizationalEntity]: def manufacture(self, manufacture: Optional[OrganizationalEntity]) -> None: self._manufacture = manufacture - @property # type: ignore[misc] + @property @serializable.xml_sequence(6) def supplier(self) -> Optional[OrganizationalEntity]: """ @@ -192,12 +184,12 @@ def supplier(self) -> Optional[OrganizationalEntity]: def supplier(self, supplier: Optional[OrganizationalEntity]) -> None: self._supplier = supplier - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) - @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'licenses') + @serializable.type_mapping(LicenseRepositoryHelper) @serializable.xml_sequence(7) - def licenses(self) -> "SortedSet[LicenseChoice]": + def licenses(self) -> LicenseRepository: """ A optional list of statements about how this BOM is licensed. @@ -207,15 +199,15 @@ def licenses(self) -> "SortedSet[LicenseChoice]": return self._licenses @licenses.setter - def licenses(self, licenses: Iterable[LicenseChoice]) -> None: - self._licenses = SortedSet(licenses) + def licenses(self, licenses: Iterable[License]) -> None: + self._licenses = LicenseRepository(licenses) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property') @serializable.xml_sequence(8) - def properties(self) -> "SortedSet[Property]": + def properties(self) -> 'SortedSet[Property]': """ Provides the ability to document properties in a key/value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. @@ -247,8 +239,7 @@ def __repr__(self) -> str: return f'' -@serializable.serializable_class( - ignore_during_deserialization=['$schema', 'bom_format', 'spec_version']) # type: ignore[misc] +@serializable.serializable_class(ignore_during_deserialization=['$schema', 'bom_format', 'spec_version']) class Bom: """ This is our internal representation of a bill-of-materials (BOM). @@ -297,7 +288,7 @@ def __init__(self, *, components: Optional[Iterable[Component]] = None, self.version = version self.dependencies = SortedSet(dependencies) or SortedSet() - @property # type: ignore[misc] + @property @serializable.type_mapping(UrnUuidHelper) @serializable.view(SchemaVersion1Dot1) @serializable.view(SchemaVersion1Dot2) @@ -318,7 +309,7 @@ def serial_number(self) -> UUID: def serial_number(self, serial_number: UUID) -> None: self._serial_number = serial_number - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @@ -339,12 +330,12 @@ def metadata(self) -> BomMetaData: def metadata(self, metadata: BomMetaData) -> None: self._metadata = metadata - @property # type: ignore[misc] + @property @serializable.include_none(SchemaVersion1Dot0) @serializable.include_none(SchemaVersion1Dot1) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component') @serializable.xml_sequence(2) - def components(self) -> "SortedSet[Component]": + def components(self) -> 'SortedSet[Component]': """ Get all the Components currently in this Bom. @@ -357,7 +348,7 @@ def components(self) -> "SortedSet[Component]": def components(self, components: Iterable[Component]) -> None: self._components = SortedSet(components) - def get_component_by_purl(self, purl: Optional["PackageURL"]) -> Optional[Component]: + def get_component_by_purl(self, purl: Optional['PackageURL']) -> Optional[Component]: """ Get a Component already in the Bom by its PURL @@ -397,13 +388,13 @@ def has_component(self, component: Component) -> bool: """ return component in self.components - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'service') @serializable.xml_sequence(3) - def services(self) -> "SortedSet[Service]": + def services(self) -> 'SortedSet[Service]': """ Get all the Services currently in this Bom. @@ -416,14 +407,14 @@ def services(self) -> "SortedSet[Service]": def services(self, services: Iterable[Service]) -> None: self._services = SortedSet(services) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot1) @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference') @serializable.xml_sequence(4) - def external_references(self) -> "SortedSet[ExternalReference]": + def external_references(self) -> 'SortedSet[ExternalReference]': """ Provides the ability to document external references related to the BOM or to the project the BOM describes. @@ -447,7 +438,7 @@ def _get_all_components(self) -> Set[Component]: return components - def get_vulnerabilities_for_bom_ref(self, bom_ref: BomRef) -> "SortedSet[Vulnerability]": + def get_vulnerabilities_for_bom_ref(self, bom_ref: BomRef) -> 'SortedSet[Vulnerability]': """ Get all known Vulnerabilities that affect the supplied bom_ref. @@ -474,11 +465,11 @@ def has_vulnerabilities(self) -> bool: """ return bool(self.vulnerabilities) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'vulnerability') @serializable.xml_sequence(8) - def vulnerabilities(self) -> "SortedSet[Vulnerability]": + def vulnerabilities(self) -> 'SortedSet[Vulnerability]': """ Get all the Vulnerabilities in this BOM. @@ -491,7 +482,7 @@ def vulnerabilities(self) -> "SortedSet[Vulnerability]": def vulnerabilities(self, vulnerabilities: Iterable[Vulnerability]) -> None: self._vulnerabilities = SortedSet(vulnerabilities) - @property # type: ignore[misc] + @property @serializable.xml_attribute() def version(self) -> int: return self._version @@ -500,13 +491,13 @@ def version(self) -> int: def version(self, version: int) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'dependency') @serializable.xml_sequence(5) - def dependencies(self) -> "SortedSet[Dependency]": + def dependencies(self) -> 'SortedSet[Dependency]': return self._dependencies @dependencies.setter @@ -554,7 +545,9 @@ def validate(self) -> bool: # 1. Make sure dependencies are all in this Bom. all_bom_refs = set(map(lambda c: c.bom_ref, self._get_all_components())) | set( map(lambda s: s.bom_ref, self.services)) - all_dependency_bom_refs = set().union(*(d.dependencies_as_bom_refs() for d in self.dependencies)) + all_dependency_bom_refs = set(chain((d.ref for d in self.dependencies), + chain.from_iterable( + d.dependencies_as_bom_refs() for d in self.dependencies))) dependency_diff = all_dependency_bom_refs - all_bom_refs if len(dependency_diff) > 0: @@ -571,9 +564,22 @@ def validate(self) -> bool: f'The Component this BOM is describing {self.metadata.component.purl} has no defined dependencies ' f'which means the Dependency Graph is incomplete - you should add direct dependencies to this ' f'"root" Component to complete the Dependency Graph data.', - UserWarning + category=UserWarning, stacklevel=1 ) + # 3. If a LicenseExpression is set, then there must be no other license. + # see https://github.com/CycloneDX/specification/pull/205 + elem: Union[BomMetaData, Component, Service] + for elem in chain( # type: ignore[assignment] + [self.metadata], + self.metadata.component.get_all_nested_components(include_self=True) if self.metadata.component else [], + chain.from_iterable(c.get_all_nested_components(include_self=True) for c in self.components), + self.services + ): + if len(elem.licenses) > 1 and any(isinstance(li, LicenseExpression) for li in elem.licenses): + raise LicenseExpressionAlongWithOthersException( + f'Found LicenseExpression along with others licenses in: {elem!r}') + return True def __eq__(self, other: object) -> bool: diff --git a/cyclonedx/model/bom_ref.py b/cyclonedx/model/bom_ref.py index 79dad0a3..bd35f1ff 100644 --- a/cyclonedx/model/bom_ref.py +++ b/cyclonedx/model/bom_ref.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cyclonedx/model/component.py b/cyclonedx/model/component.py index 4833db13..5aefa706 100644 --- a/cyclonedx/model/component.py +++ b/cyclonedx/model/component.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,7 +19,6 @@ from enum import Enum from os.path import exists from typing import Any, Iterable, Optional, Set, Union -from uuid import uuid4 # See https://github.com/package-url/packageurl-python/issues/65 import serializable @@ -36,7 +33,7 @@ SchemaVersion1Dot3, SchemaVersion1Dot4, ) -from ..serialization import BomRefHelper, PackageUrl +from ..serialization import BomRefHelper, LicenseRepositoryHelper, PackageUrl from . import ( AttachedText, ComparableTuple, @@ -45,7 +42,6 @@ HashAlgorithm, HashType, IdentifiableAction, - LicenseChoice, OrganizationalEntity, Property, XsUri, @@ -54,6 +50,7 @@ from .bom_ref import BomRef from .dependency import Dependable from .issue import IssueType +from .license import License, LicenseExpression, LicenseRepository from .release_note import ReleaseNotes @@ -80,7 +77,7 @@ def __init__(self, *, uid: Optional[str] = None, url: Optional[XsUri] = None, self.committer = committer self.message = message - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def uid(self) -> Optional[str]: """ @@ -96,7 +93,7 @@ def uid(self) -> Optional[str]: def uid(self, uid: Optional[str]) -> None: self._uid = uid - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def url(self) -> Optional[XsUri]: """ @@ -111,7 +108,7 @@ def url(self) -> Optional[XsUri]: def url(self, url: Optional[XsUri]) -> None: self._url = url - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def author(self) -> Optional[IdentifiableAction]: """ @@ -126,7 +123,7 @@ def author(self) -> Optional[IdentifiableAction]: def author(self, author: Optional[IdentifiableAction]) -> None: self._author = author - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def committer(self) -> Optional[IdentifiableAction]: """ @@ -141,7 +138,7 @@ def committer(self) -> Optional[IdentifiableAction]: def committer(self, committer: Optional[IdentifiableAction]) -> None: self._committer = committer - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def message(self) -> Optional[str]: """ @@ -185,7 +182,7 @@ class ComponentEvidence: See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.4/xml/#type_componentEvidenceType """ - def __init__(self, *, licenses: Optional[Iterable[LicenseChoice]] = None, + def __init__(self, *, licenses: Optional[Iterable[License]] = None, copyright: Optional[Iterable[Copyright]] = None) -> None: if not licenses and not copyright: raise NoPropertiesProvidedException( @@ -195,9 +192,9 @@ def __init__(self, *, licenses: Optional[Iterable[LicenseChoice]] = None, self.licenses = licenses or [] # type: ignore self.copyright = copyright or [] # type: ignore - @property # type: ignore[misc] - @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'license') - def licenses(self) -> "SortedSet[LicenseChoice]": + @property + @serializable.type_mapping(LicenseRepositoryHelper) + def licenses(self) -> LicenseRepository: """ Optional list of licenses obtained during analysis. @@ -207,12 +204,12 @@ def licenses(self) -> "SortedSet[LicenseChoice]": return self._licenses @licenses.setter - def licenses(self, licenses: Iterable[LicenseChoice]) -> None: - self._licenses = SortedSet(licenses) + def licenses(self, licenses: Iterable[License]) -> None: + self._licenses = LicenseRepository(licenses) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'text') - def copyright(self) -> "SortedSet[Copyright]": + def copyright(self) -> 'SortedSet[Copyright]': """ Optional list of copyright statements. @@ -356,7 +353,7 @@ def __init__(self, *, type: PatchClassification, diff: Optional[Diff] = None, self.diff = diff self.resolves = resolves or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_attribute() def type(self) -> PatchClassification: """ @@ -389,9 +386,9 @@ def diff(self) -> Optional[Diff]: def diff(self, diff: Optional[Diff]) -> None: self._diff = diff - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'issue') - def resolves(self) -> "SortedSet[IssueType]": + def resolves(self) -> 'SortedSet[IssueType]': """ Optional list of issues resolved by this patch. @@ -453,7 +450,7 @@ def __init__(self, *, ancestors: Optional[Iterable['Component']] = None, self.patches = patches or [] # type: ignore self.notes = notes - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component') @serializable.xml_sequence(1) def ancestors(self) -> "SortedSet['Component']": @@ -475,7 +472,7 @@ def ancestors(self) -> "SortedSet['Component']": def ancestors(self, ancestors: Iterable['Component']) -> None: self._ancestors = SortedSet(ancestors) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component') @serializable.xml_sequence(2) def descendants(self) -> "SortedSet['Component']": @@ -492,7 +489,7 @@ def descendants(self) -> "SortedSet['Component']": def descendants(self, descendants: Iterable['Component']) -> None: self._descendants = SortedSet(descendants) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component') @serializable.xml_sequence(3) def variants(self) -> "SortedSet['Component']": @@ -510,10 +507,10 @@ def variants(self) -> "SortedSet['Component']": def variants(self, variants: Iterable['Component']) -> None: self._variants = SortedSet(variants) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'commit') @serializable.xml_sequence(4) - def commits(self) -> "SortedSet[Commit]": + def commits(self) -> 'SortedSet[Commit]': """ A list of zero or more commits which provide a trail describing how the component deviates from an ancestor, descendant, or variant. @@ -527,13 +524,13 @@ def commits(self) -> "SortedSet[Commit]": def commits(self, commits: Iterable[Commit]) -> None: self._commits = SortedSet(commits) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'patch') @serializable.xml_sequence(5) - def patches(self) -> "SortedSet[Patch]": + def patches(self) -> 'SortedSet[Patch]': """ A list of zero or more patches describing how the component deviates from an ancestor, descendant, or variant. Patches may be complimentary to commits or may be used in place of commits. @@ -547,7 +544,7 @@ def patches(self) -> "SortedSet[Patch]": def patches(self, patches: Iterable[Patch]) -> None: self._patches = SortedSet(patches) - @property # type: ignore[misc] + @property @serializable.xml_sequence(6) def notes(self) -> Optional[str]: """ @@ -597,7 +594,7 @@ def __init__(self, *, tag_id: str, name: str, version: Optional[str] = None, self.text = text self.url = url - @property # type: ignore[misc] + @property @serializable.xml_attribute() def tag_id(self) -> str: """ @@ -612,7 +609,7 @@ def tag_id(self) -> str: def tag_id(self, tag_id: str) -> None: self._tag_id = tag_id - @property # type: ignore[misc] + @property @serializable.xml_attribute() def name(self) -> str: """ @@ -627,7 +624,7 @@ def name(self) -> str: def name(self, name: str) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_attribute() def version(self) -> Optional[str]: """ @@ -642,7 +639,7 @@ def version(self) -> Optional[str]: def version(self, version: Optional[str]) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.xml_attribute() def tag_version(self) -> Optional[int]: """ @@ -657,7 +654,7 @@ def tag_version(self) -> Optional[int]: def tag_version(self, tag_version: Optional[int]) -> None: self._tag_version = tag_version - @property # type: ignore[misc] + @property @serializable.xml_attribute() def patch(self) -> Optional[bool]: """ @@ -736,18 +733,18 @@ def for_file(absolute_file_path: str, path_for_bom: Optional[str]) -> 'Component `Component` representing the supplied file """ if not exists(absolute_file_path): - raise FileExistsError('Supplied file path \'{}\' does not exist'.format(absolute_file_path)) + raise FileExistsError(f'Supplied file path {absolute_file_path!r} does not exist') sha1_hash: str = sha1sum(filename=absolute_file_path) return Component( name=path_for_bom if path_for_bom else absolute_file_path, - version='0.0.0-{}'.format(sha1_hash[0:12]), + version=f'0.0.0-{sha1_hash[0:12]}', hashes=[ HashType(alg=HashAlgorithm.SHA_1, content=sha1_hash) ], type=ComponentType.FILE, purl=PackageURL( type='generic', name=path_for_bom if path_for_bom else absolute_file_path, - version='0.0.0-{}'.format(sha1_hash[0:12]) + version=f'0.0.0-{sha1_hash[0:12]}' ) ) @@ -756,7 +753,7 @@ def __init__(self, *, name: str, type: ComponentType = ComponentType.LIBRARY, supplier: Optional[OrganizationalEntity] = None, author: Optional[str] = None, publisher: Optional[str] = None, group: Optional[str] = None, version: Optional[str] = None, description: Optional[str] = None, scope: Optional[ComponentScope] = None, - hashes: Optional[Iterable[HashType]] = None, licenses: Optional[Iterable[LicenseChoice]] = None, + hashes: Optional[Iterable[HashType]] = None, licenses: Optional[Iterable[License]] = None, copyright: Optional[str] = None, purl: Optional[PackageURL] = None, external_references: Optional[Iterable[ExternalReference]] = None, properties: Optional[Iterable[Property]] = None, release_notes: Optional[ReleaseNotes] = None, @@ -771,7 +768,7 @@ def __init__(self, *, name: str, type: ComponentType = ComponentType.LIBRARY, if isinstance(bom_ref, BomRef): self._bom_ref = bom_ref else: - self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else str(uuid4())) + self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else None) self.supplier = supplier self.author = author self.publisher = publisher @@ -798,22 +795,21 @@ def __init__(self, *, name: str, type: ComponentType = ComponentType.LIBRARY, if namespace: warnings.warn( '`namespace` is deprecated and has been replaced with `group` to align with the CycloneDX standard', - DeprecationWarning + category=DeprecationWarning, stacklevel=1 ) if not group: self.group = namespace if license_str: warnings.warn( - '`license_str` is deprecated and has been replaced with `licenses` to align with the CycloneDX ' - 'standard', DeprecationWarning + '`license_str` is deprecated and has been' + ' replaced with `licenses` to align with the CycloneDX standard', + category=DeprecationWarning, stacklevel=1 ) if not licenses: - self.licenses = [LicenseChoice(expression=license_str)] # type: ignore + self.licenses = LicenseRepository([LicenseExpression(license_str)]) - self.__dependencies: "SortedSet[BomRef]" = SortedSet() - - @property # type: ignore[misc] + @property @serializable.xml_attribute() def type(self) -> ComponentType: """ @@ -846,7 +842,7 @@ def mime_type(self) -> Optional[str]: def mime_type(self, mime_type: Optional[str]) -> None: self._mime_type = mime_type - @property # type: ignore[misc] + @property @serializable.json_name('bom-ref') @serializable.type_mapping(BomRefHelper) @serializable.view(SchemaVersion1Dot1) @@ -867,7 +863,7 @@ def bom_ref(self) -> BomRef: """ return self._bom_ref - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @@ -886,7 +882,7 @@ def supplier(self) -> Optional[OrganizationalEntity]: def supplier(self, supplier: Optional[OrganizationalEntity]) -> None: self._supplier = supplier - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @@ -904,7 +900,7 @@ def author(self) -> Optional[str]: def author(self, author: Optional[str]) -> None: self._author = author - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def publisher(self) -> Optional[str]: """ @@ -919,7 +915,7 @@ def publisher(self) -> Optional[str]: def publisher(self, publisher: Optional[str]) -> None: self._publisher = publisher - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def group(self) -> Optional[str]: """ @@ -938,7 +934,7 @@ def group(self) -> Optional[str]: def group(self, group: Optional[str]) -> None: self._group = group - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def name(self) -> str: """ @@ -957,11 +953,11 @@ def name(self) -> str: def name(self, name: str) -> None: self._name = name - @property # type: ignore[misc] - @serializable.include_none(SchemaVersion1Dot0, "") - @serializable.include_none(SchemaVersion1Dot1, "") - @serializable.include_none(SchemaVersion1Dot2, "") - @serializable.include_none(SchemaVersion1Dot3, "") + @property + @serializable.include_none(SchemaVersion1Dot0, '') + @serializable.include_none(SchemaVersion1Dot1, '') + @serializable.include_none(SchemaVersion1Dot2, '') + @serializable.include_none(SchemaVersion1Dot3, '') @serializable.xml_sequence(6) def version(self) -> Optional[str]: """ @@ -979,7 +975,7 @@ def version(self) -> Optional[str]: def version(self, version: Optional[str]) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.xml_sequence(7) def description(self) -> Optional[str]: """ @@ -994,7 +990,7 @@ def description(self) -> Optional[str]: def description(self, description: Optional[str]) -> None: self._description = description - @property # type: ignore[misc] + @property @serializable.xml_sequence(8) def scope(self) -> Optional[ComponentScope]: """ @@ -1011,10 +1007,10 @@ def scope(self) -> Optional[ComponentScope]: def scope(self, scope: Optional[ComponentScope]) -> None: self._scope = scope - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'hash') @serializable.xml_sequence(9) - def hashes(self) -> "SortedSet[HashType]": + def hashes(self) -> 'SortedSet[HashType]': """ Optional list of hashes that help specify the integrity of this Component. @@ -1027,14 +1023,14 @@ def hashes(self) -> "SortedSet[HashType]": def hashes(self, hashes: Iterable[HashType]) -> None: self._hashes = SortedSet(hashes) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot1) @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) - @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'licenses') + @serializable.type_mapping(LicenseRepositoryHelper) @serializable.xml_sequence(10) - def licenses(self) -> "SortedSet[LicenseChoice]": + def licenses(self) -> LicenseRepository: """ A optional list of statements about how this Component is licensed. @@ -1044,10 +1040,10 @@ def licenses(self) -> "SortedSet[LicenseChoice]": return self._licenses @licenses.setter - def licenses(self, licenses: Iterable[LicenseChoice]) -> None: - self._licenses = SortedSet(licenses) + def licenses(self, licenses: Iterable[License]) -> None: + self._licenses = LicenseRepository(licenses) - @property # type: ignore[misc] + @property @serializable.xml_sequence(11) def copyright(self) -> Optional[str]: """ @@ -1063,7 +1059,7 @@ def copyright(self) -> Optional[str]: def copyright(self, copyright: Optional[str]) -> None: self._copyright = copyright - @property # type: ignore[misc] + @property @serializable.xml_sequence(12) def cpe(self) -> Optional[str]: """ @@ -1079,7 +1075,7 @@ def cpe(self) -> Optional[str]: def cpe(self, cpe: Optional[str]) -> None: self._cpe = cpe - @property # type: ignore[misc] + @property @serializable.type_mapping(PackageUrl) @serializable.xml_sequence(13) def purl(self) -> Optional[PackageURL]: @@ -1098,7 +1094,7 @@ def purl(self) -> Optional[PackageURL]: def purl(self, purl: Optional[PackageURL]) -> None: self._purl = purl - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @@ -1116,7 +1112,7 @@ def swid(self) -> Optional[Swid]: def swid(self, swid: Optional[Swid]) -> None: self._swid = swid - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot0) @serializable.xml_sequence(18) def modified(self) -> bool: @@ -1126,7 +1122,7 @@ def modified(self) -> bool: def modified(self, modified: bool) -> None: self._modified = modified - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot1) @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @@ -1146,14 +1142,14 @@ def pedigree(self) -> Optional[Pedigree]: def pedigree(self, pedigree: Optional[Pedigree]) -> None: self._pedigree = pedigree - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot1) @serializable.view(SchemaVersion1Dot2) @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference') @serializable.xml_sequence(17) - def external_references(self) -> "SortedSet[ExternalReference]": + def external_references(self) -> 'SortedSet[ExternalReference]': """ Provides the ability to document external references related to the component or to the project the component describes. @@ -1167,12 +1163,12 @@ def external_references(self) -> "SortedSet[ExternalReference]": def external_references(self, external_references: Iterable[ExternalReference]) -> None: self._external_references = SortedSet(external_references) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property') @serializable.xml_sequence(18) - def properties(self) -> "SortedSet[Property]": + def properties(self) -> 'SortedSet[Property]': """ Provides the ability to document properties in a key/value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. @@ -1186,7 +1182,7 @@ def properties(self) -> "SortedSet[Property]": def properties(self, properties: Iterable[Property]) -> None: self._properties = SortedSet(properties) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component') @serializable.xml_sequence(19) def components(self) -> "SortedSet['Component']": @@ -1204,7 +1200,7 @@ def components(self) -> "SortedSet['Component']": def components(self, components: Iterable['Component']) -> None: self._components = SortedSet(components) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_sequence(20) @@ -1221,7 +1217,7 @@ def evidence(self) -> Optional[ComponentEvidence]: def evidence(self, evidence: Optional[ComponentEvidence]) -> None: self._evidence = evidence - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot4) @serializable.xml_sequence(21) def release_notes(self) -> Optional[ReleaseNotes]: @@ -1237,7 +1233,7 @@ def release_notes(self) -> Optional[ReleaseNotes]: def release_notes(self, release_notes: Optional[ReleaseNotes]) -> None: self._release_notes = release_notes - def get_all_nested_components(self, include_self: bool = False) -> Set["Component"]: + def get_all_nested_components(self, include_self: bool = False) -> Set['Component']: components = set() if include_self: components.add(self) @@ -1284,5 +1280,6 @@ def get_namespace(self) -> Optional[str]: Returns: Declared namespace of this Component as `str` if declared, else `None`. """ - warnings.warn('`Component.get_namespace()` is deprecated - use `Component.group`', DeprecationWarning) + warnings.warn('`Component.get_namespace()` is deprecated - use `Component.group`', + category=DeprecationWarning, stacklevel=1) return self._group diff --git a/cyclonedx/model/dependency.py b/cyclonedx/model/dependency.py index 14105237..51c13d93 100644 --- a/cyclonedx/model/dependency.py +++ b/cyclonedx/model/dependency.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,15 +30,15 @@ class DependencyDependencies(serializable.BaseHelper): # type: ignore @classmethod - def serialize(cls, o: object) -> List[str]: + def serialize(cls, o: Any) -> List[str]: if isinstance(o, SortedSet): return list(map(lambda i: str(i.ref), o)) raise ValueError(f'Attempt to serialize a non-Dependency: {o.__class__}') @classmethod - def deserialize(cls, o: object) -> Set["Dependency"]: - dependencies: Set["Dependency"] = set() + def deserialize(cls, o: Any) -> Set['Dependency']: + dependencies: Set['Dependency'] = set() if isinstance(o, list): for v in o: dependencies.add(Dependency(ref=BomRef(value=v))) @@ -56,11 +54,11 @@ class Dependency: See https://cyclonedx.org/docs/1.4/xml/#type_dependencyType """ - def __init__(self, ref: BomRef, dependencies: Optional[Iterable["Dependency"]] = None) -> None: + def __init__(self, ref: BomRef, dependencies: Optional[Iterable['Dependency']] = None) -> None: self.ref = ref self.dependencies = SortedSet(dependencies or []) - @property # type: ignore[misc] + @property @serializable.type_mapping(BomRefHelper) @serializable.xml_attribute() def ref(self) -> BomRef: @@ -70,15 +68,15 @@ def ref(self) -> BomRef: def ref(self, ref: BomRef) -> None: self._ref = ref - @property # type: ignore[misc] + @property @serializable.json_name('dependsOn') @serializable.type_mapping(DependencyDependencies) @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'dependency') - def dependencies(self) -> "SortedSet[Dependency]": + def dependencies(self) -> 'SortedSet[Dependency]': return self._dependencies @dependencies.setter - def dependencies(self, dependencies: Iterable["Dependency"]) -> None: + def dependencies(self, dependencies: Iterable['Dependency']) -> None: self._dependencies = SortedSet(dependencies) def dependencies_as_bom_refs(self) -> Set[BomRef]: @@ -110,4 +108,4 @@ class Dependable(ABC): @property @abstractmethod def bom_ref(self) -> BomRef: - pass + ... diff --git a/cyclonedx/model/impact_analysis.py b/cyclonedx/model/impact_analysis.py index 830912f6..16d5914b 100644 --- a/cyclonedx/model/impact_analysis.py +++ b/cyclonedx/model/impact_analysis.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cyclonedx/model/issue.py b/cyclonedx/model/issue.py index 554f2772..03709b4f 100644 --- a/cyclonedx/model/issue.py +++ b/cyclonedx/model/issue.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -120,7 +118,7 @@ def __init__(self, *, type: IssueClassification, id: Optional[str] = None, name: self.source = source self.references = references or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_attribute() def type(self) -> IssueClassification: """ @@ -135,7 +133,7 @@ def type(self) -> IssueClassification: def type(self, type: IssueClassification) -> None: self._type = type - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def id(self) -> Optional[str]: """ @@ -150,7 +148,7 @@ def id(self) -> Optional[str]: def id(self, id: Optional[str]) -> None: self._id = id - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def name(self) -> Optional[str]: """ @@ -165,7 +163,7 @@ def name(self) -> Optional[str]: def name(self, name: Optional[str]) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def description(self) -> Optional[str]: """ @@ -180,7 +178,7 @@ def description(self) -> Optional[str]: def description(self, description: Optional[str]) -> None: self._description = description - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def source(self) -> Optional[IssueTypeSource]: """ @@ -195,10 +193,10 @@ def source(self) -> Optional[IssueTypeSource]: def source(self, source: Optional[IssueTypeSource]) -> None: self._source = source - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'url') @serializable.xml_sequence(5) - def references(self) -> "SortedSet[XsUri]": + def references(self) -> 'SortedSet[XsUri]': """ Any reference URLs related to this issue. diff --git a/cyclonedx/model/license.py b/cyclonedx/model/license.py new file mode 100644 index 00000000..f091f698 --- /dev/null +++ b/cyclonedx/model/license.py @@ -0,0 +1,224 @@ +# encoding: utf-8 + +# 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. + +import warnings +from typing import TYPE_CHECKING, Any, Optional, Union + +import serializable +from sortedcontainers import SortedSet + +from ..exception.model import MutuallyExclusivePropertiesException +from . import AttachedText, ComparableTuple, XsUri + +""" +License related things +""" + + +@serializable.serializable_class(name='license') +class DisjunctiveLicense: + """ + This is our internal representation of `licenseType` complex type that can be used in multiple places within + a CycloneDX BOM document. + + .. note:: + See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.4/xml/#type_licenseType + """ + + def __init__(self, *, id: Optional[str] = None, name: Optional[str] = None, + text: Optional[AttachedText] = None, url: Optional[XsUri] = None) -> None: + if not id and not name: + raise MutuallyExclusivePropertiesException('Either `id` or `name` MUST be supplied') + if id and name: + warnings.warn( + 'Both `id` and `name` have been supplied - `name` will be ignored!', + category=RuntimeWarning, stacklevel=1 + ) + self._id = id + self._name = name if not id else None + self._text = text + self._url = url + + @property + @serializable.xml_sequence(1) + def id(self) -> Optional[str]: + """ + A valid SPDX license ID + + Returns: + `str` or `None` + """ + return self._id + + @id.setter + def id(self, id: Optional[str]) -> None: + self._id = id + if id is not None: + self._name = None + + @property + @serializable.xml_sequence(1) + def name(self) -> Optional[str]: + """ + If SPDX does not define the license used, this field may be used to provide the license name. + + Returns: + `str` or `None` + """ + return self._name + + @name.setter + def name(self, name: Optional[str]) -> None: + self._name = name + if name is not None: + self._id = None + + @property + @serializable.xml_sequence(2) + def text(self) -> Optional[AttachedText]: + """ + Specifies the optional full text of the attachment + + Returns: + `AttachedText` else `None` + """ + return self._text + + @text.setter + def text(self, text: Optional[AttachedText]) -> None: + self._text = text + + @property + @serializable.xml_sequence(3) + def url(self) -> Optional[XsUri]: + """ + The URL to the attachment file. If the attachment is a license or BOM, an externalReference should also be + specified for completeness. + + Returns: + `XsUri` or `None` + """ + return self._url + + @url.setter + def url(self, url: Optional[XsUri]) -> None: + self._url = url + + def __eq__(self, other: object) -> bool: + if isinstance(other, DisjunctiveLicense): + return hash(other) == hash(self) + return False + + def __lt__(self, other: Any) -> bool: + if isinstance(other, DisjunctiveLicense): + return ComparableTuple((self._id, self._name)) < ComparableTuple((other._id, other._name)) + if isinstance(other, LicenseExpression): + return False # self after any LicenseExpression + return NotImplemented + + def __hash__(self) -> int: + return hash((self._id, self._name, self._text, self._url)) + + def __repr__(self) -> str: + return f'' + + +@serializable.serializable_class(name='expression') +class LicenseExpression: + """ + This is our internal representation of `licenseType`'s expression type that can be used in multiple places within + a CycloneDX BOM document. + + .. note:: + See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.4/xml/#type_licenseType + """ + + def __init__(self, value: str) -> None: + self._value = value + + @property + @serializable.xml_name('.') + @serializable.json_name('expression') + def value(self) -> str: + """ + Value of this LicenseExpression. + + Returns: + `str` + """ + return self._value + + @value.setter + def value(self, value: str) -> None: + self._value = value + + def __hash__(self) -> int: + return hash(self._value) + + def __eq__(self, other: object) -> bool: + if isinstance(other, LicenseExpression): + return self._value == other._value + return False + + def __lt__(self, other: Any) -> bool: + if isinstance(other, LicenseExpression): + return self._value < other._value + if isinstance(other, DisjunctiveLicense): + return True # self before any DisjunctiveLicense + return NotImplemented + + def __repr__(self) -> str: + return f'' + + +License = Union[LicenseExpression, DisjunctiveLicense] +"""TypeAlias for a union of supported license models. + +- :class:`LicenseExpression` +- :class:`DisjunctiveLicense` +""" + +if TYPE_CHECKING: # pragma: no cover + # workaround for https://github.com/python/mypy/issues/5264 + # this code path is taken when static code analysis or documentation tools runs through. + class LicenseRepository(SortedSet[License]): + """Collection of :class:`License`. + + This is a `set`, not a `list`. Order MUST NOT matter here. + If you wanted a certain order, then you should also express whether the items are concat by `AND` or `OR`. + If you wanted to do so, you should use :class:`LicenseExpression`. + + As a model, this MUST accept multiple :class:`LicenseExpression` along with + multiple :class:`DisjunctiveLicense`, as this was an accepted in CycloneDX JSON before v1.5. + So for modeling purposes, this is supported. + Denormalizers/deserializers will be thankful. + The normalization/serialization process SHOULD take care of these facts and do what is needed. + """ +else: + class LicenseRepository(SortedSet): + """Collection of :class:`License`. + + This is a `set`, not a `list`. Order MUST NOT matter here. + If you wanted a certain order, then you should also express whether the items are concat by `AND` or `OR`. + If you wanted to do so, you should use :class:`LicenseExpression`. + + As a model, this MUST accept multiple :class:`LicenseExpression` along with + multiple :class:`DisjunctiveLicense`, as this was an accepted in CycloneDX JSON before v1.5. + So for modeling purposes, this is supported. + Denormalizers/deserializers will be thankful. + The normalization/serialization process SHOULD take care of these facts and do what is needed. + """ diff --git a/cyclonedx/model/release_note.py b/cyclonedx/model/release_note.py index eb942381..371c20a3 100644 --- a/cyclonedx/model/release_note.py +++ b/cyclonedx/model/release_note.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -53,7 +51,7 @@ def __init__(self, *, type: str, title: Optional[str] = None, featured_image: Op self.notes = notes or [] # type: ignore self.properties = properties or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def type(self) -> str: """ @@ -79,7 +77,7 @@ def type(self) -> str: def type(self, type: str) -> None: self._type = type - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def title(self) -> Optional[str]: """ @@ -91,7 +89,7 @@ def title(self) -> Optional[str]: def title(self, title: Optional[str]) -> None: self._title = title - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def featured_image(self) -> Optional[XsUri]: """ @@ -103,7 +101,7 @@ def featured_image(self) -> Optional[XsUri]: def featured_image(self, featured_image: Optional[XsUri]) -> None: self._featured_image = featured_image - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def social_image(self) -> Optional[XsUri]: """ @@ -115,7 +113,7 @@ def social_image(self) -> Optional[XsUri]: def social_image(self, social_image: Optional[XsUri]) -> None: self._social_image = social_image - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def description(self) -> Optional[str]: """ @@ -127,7 +125,7 @@ def description(self) -> Optional[str]: def description(self, description: Optional[str]) -> None: self._description = description - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) @serializable.xml_sequence(6) def timestamp(self) -> Optional[datetime]: @@ -140,10 +138,10 @@ def timestamp(self) -> Optional[datetime]: def timestamp(self, timestamp: Optional[datetime]) -> None: self._timestamp = timestamp - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'alias') @serializable.xml_sequence(7) - def aliases(self) -> "SortedSet[str]": + def aliases(self) -> 'SortedSet[str]': """ One or more alternate names the release may be referred to. This may include unofficial terms used by development and marketing teams (e.g. code names). @@ -157,10 +155,10 @@ def aliases(self) -> "SortedSet[str]": def aliases(self, aliases: Iterable[str]) -> None: self._aliases = SortedSet(aliases) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'tag') @serializable.xml_sequence(8) - def tags(self) -> "SortedSet[str]": + def tags(self) -> 'SortedSet[str]': """ One or more tags that may aid in search or retrieval of the release note. @@ -173,10 +171,10 @@ def tags(self) -> "SortedSet[str]": def tags(self, tags: Iterable[str]) -> None: self._tags = SortedSet(tags) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'issue') @serializable.xml_sequence(9) - def resolves(self) -> "SortedSet[IssueType]": + def resolves(self) -> 'SortedSet[IssueType]': """ A collection of issues that have been resolved. @@ -189,10 +187,10 @@ def resolves(self) -> "SortedSet[IssueType]": def resolves(self, resolves: Iterable[IssueType]) -> None: self._resolves = SortedSet(resolves) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'note') @serializable.xml_sequence(10) - def notes(self) -> "SortedSet[Note]": + def notes(self) -> 'SortedSet[Note]': """ Zero or more release notes containing the locale and content. Multiple note elements may be specified to support release notes in a wide variety of languages. @@ -206,10 +204,10 @@ def notes(self) -> "SortedSet[Note]": def notes(self, notes: Iterable[Note]) -> None: self._notes = SortedSet(notes) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property') @serializable.xml_sequence(11) - def properties(self) -> "SortedSet[Property]": + def properties(self) -> 'SortedSet[Property]': """ Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike diff --git a/cyclonedx/model/service.py b/cyclonedx/model/service.py index e951c31a..708e874b 100644 --- a/cyclonedx/model/service.py +++ b/cyclonedx/model/service.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -16,25 +14,17 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. from typing import Any, Iterable, Optional, Union -from uuid import uuid4 import serializable from sortedcontainers import SortedSet -from cyclonedx.serialization import BomRefHelper +from cyclonedx.serialization import BomRefHelper, LicenseRepositoryHelper from ..schema.schema import SchemaVersion1Dot3, SchemaVersion1Dot4 -from . import ( - ComparableTuple, - DataClassification, - ExternalReference, - LicenseChoice, - OrganizationalEntity, - Property, - XsUri, -) +from . import ComparableTuple, DataClassification, ExternalReference, OrganizationalEntity, Property, XsUri from .bom_ref import BomRef from .dependency import Dependable +from .license import License, LicenseRepository from .release_note import ReleaseNotes """ @@ -59,16 +49,16 @@ def __init__(self, *, name: str, bom_ref: Optional[Union[str, BomRef]] = None, group: Optional[str] = None, version: Optional[str] = None, description: Optional[str] = None, endpoints: Optional[Iterable[XsUri]] = None, authenticated: Optional[bool] = None, x_trust_boundary: Optional[bool] = None, data: Optional[Iterable[DataClassification]] = None, - licenses: Optional[Iterable[LicenseChoice]] = None, + licenses: Optional[Iterable[License]] = None, external_references: Optional[Iterable[ExternalReference]] = None, properties: Optional[Iterable[Property]] = None, services: Optional[Iterable['Service']] = None, release_notes: Optional[ReleaseNotes] = None, ) -> None: - if type(bom_ref) == BomRef: + if isinstance(bom_ref, BomRef): self._bom_ref = bom_ref else: - self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else str(uuid4())) + self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else None) self.provider = provider self.group = group self.name = name @@ -84,7 +74,7 @@ def __init__(self, *, name: str, bom_ref: Optional[Union[str, BomRef]] = None, self.release_notes = release_notes self.properties = properties or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.json_name('bom-ref') @serializable.type_mapping(BomRefHelper) @serializable.xml_attribute() @@ -101,7 +91,7 @@ def bom_ref(self) -> BomRef: """ return self._bom_ref - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def provider(self) -> Optional[OrganizationalEntity]: """ @@ -116,7 +106,7 @@ def provider(self) -> Optional[OrganizationalEntity]: def provider(self, provider: Optional[OrganizationalEntity]) -> None: self._provider = provider - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def group(self) -> Optional[str]: """ @@ -132,7 +122,7 @@ def group(self) -> Optional[str]: def group(self, group: Optional[str]) -> None: self._group = group - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def name(self) -> str: """ @@ -147,7 +137,7 @@ def name(self) -> str: def name(self, name: str) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def version(self) -> Optional[str]: """ @@ -162,7 +152,7 @@ def version(self) -> Optional[str]: def version(self, version: Optional[str]) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def description(self) -> Optional[str]: """ @@ -177,10 +167,10 @@ def description(self) -> Optional[str]: def description(self, description: Optional[str]) -> None: self._description = description - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'endpoint') @serializable.xml_sequence(6) - def endpoints(self) -> "SortedSet[XsUri]": + def endpoints(self) -> 'SortedSet[XsUri]': """ A list of endpoints URI's this service provides. @@ -193,7 +183,7 @@ def endpoints(self) -> "SortedSet[XsUri]": def endpoints(self, endpoints: Iterable[XsUri]) -> None: self._endpoints = SortedSet(endpoints) - @property # type: ignore[misc] + @property @serializable.xml_sequence(7) def authenticated(self) -> Optional[bool]: """ @@ -211,7 +201,7 @@ def authenticated(self) -> Optional[bool]: def authenticated(self, authenticated: Optional[bool]) -> None: self._authenticated = authenticated - @property # type: ignore[misc] + @property @serializable.json_name('x-trust-boundary') @serializable.xml_name('x-trust-boundary') @serializable.xml_sequence(8) @@ -231,10 +221,10 @@ def x_trust_boundary(self) -> Optional[bool]: def x_trust_boundary(self, x_trust_boundary: Optional[bool]) -> None: self._x_trust_boundary = x_trust_boundary - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'classification') @serializable.xml_sequence(9) - def data(self) -> "SortedSet[DataClassification]": + def data(self) -> 'SortedSet[DataClassification]': """ Specifies the data classification. @@ -247,10 +237,10 @@ def data(self) -> "SortedSet[DataClassification]": def data(self, data: Iterable[DataClassification]) -> None: self._data = SortedSet(data) - @property # type: ignore[misc] - @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'licenses') + @property + @serializable.type_mapping(LicenseRepositoryHelper) @serializable.xml_sequence(10) - def licenses(self) -> "SortedSet[LicenseChoice]": + def licenses(self) -> LicenseRepository: """ A optional list of statements about how this Service is licensed. @@ -260,13 +250,13 @@ def licenses(self) -> "SortedSet[LicenseChoice]": return self._licenses @licenses.setter - def licenses(self, licenses: Iterable[LicenseChoice]) -> None: - self._licenses = SortedSet(licenses) + def licenses(self, licenses: Iterable[License]) -> None: + self._licenses = LicenseRepository(licenses) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference') @serializable.xml_sequence(11) - def external_references(self) -> "SortedSet[ExternalReference]": + def external_references(self) -> 'SortedSet[ExternalReference]': """ Provides the ability to document external references related to the Service. @@ -279,7 +269,7 @@ def external_references(self) -> "SortedSet[ExternalReference]": def external_references(self, external_references: Iterable[ExternalReference]) -> None: self._external_references = SortedSet(external_references) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'service') @serializable.xml_sequence(13) def services(self) -> "SortedSet['Service']": @@ -299,7 +289,7 @@ def services(self) -> "SortedSet['Service']": def services(self, services: Iterable['Service']) -> None: self._services = SortedSet(services) - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot4) @serializable.xml_sequence(14) def release_notes(self) -> Optional[ReleaseNotes]: @@ -315,12 +305,12 @@ def release_notes(self) -> Optional[ReleaseNotes]: def release_notes(self, release_notes: Optional[ReleaseNotes]) -> None: self._release_notes = release_notes - @property # type: ignore[misc] + @property @serializable.view(SchemaVersion1Dot3) @serializable.view(SchemaVersion1Dot4) @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property') @serializable.xml_sequence(12) - def properties(self) -> "SortedSet[Property]": + def properties(self) -> 'SortedSet[Property]': """ Provides the ability to document properties in a key/value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. diff --git a/cyclonedx/model/vulnerability.py b/cyclonedx/model/vulnerability.py index 66f6cbb9..b17fc117 100644 --- a/cyclonedx/model/vulnerability.py +++ b/cyclonedx/model/vulnerability.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +21,6 @@ from decimal import Decimal from enum import Enum from typing import Any, Iterable, Optional, Tuple, Union -from uuid import uuid4 import serializable from sortedcontainers import SortedSet @@ -77,7 +74,7 @@ def __init__(self, *, version: Optional[str] = None, range: Optional[str] = None self.range = range self.status = status - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def version(self) -> Optional[str]: """ @@ -89,7 +86,7 @@ def version(self) -> Optional[str]: def version(self, version: Optional[str]) -> None: self._version = version - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def range(self) -> Optional[str]: """ @@ -106,12 +103,12 @@ def range(self) -> Optional[str]: def range(self, range: Optional[str]) -> None: self._range = range - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def status(self) -> Optional[ImpactAnalysisAffectedStatus]: """ The vulnerability status for the version or range of versions. - """"" + """ return self._status @status.setter @@ -154,7 +151,7 @@ def __init__(self, *, ref: str, versions: Optional[Iterable[BomTargetVersionRang self.ref = ref self.versions = versions or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def ref(self) -> str: """ @@ -166,10 +163,10 @@ def ref(self) -> str: def ref(self, ref: str) -> None: self._ref = ref - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'version') @serializable.xml_sequence(2) - def versions(self) -> "SortedSet[BomTargetVersionRange]": + def versions(self) -> 'SortedSet[BomTargetVersionRange]': """ Zero or more individual versions or range of versions. @@ -222,7 +219,7 @@ def __init__(self, *, state: Optional[ImpactAnalysisState] = None, self.responses = responses or [] # type: ignore self.detail = detail - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def state(self) -> Optional[ImpactAnalysisState]: """ @@ -237,7 +234,7 @@ def state(self) -> Optional[ImpactAnalysisState]: def state(self, state: Optional[ImpactAnalysisState]) -> None: self._state = state - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def justification(self) -> Optional[ImpactAnalysisJustification]: """ @@ -252,11 +249,11 @@ def justification(self) -> Optional[ImpactAnalysisJustification]: def justification(self, justification: Optional[ImpactAnalysisJustification]) -> None: self._justification = justification - @property # type: ignore[misc] + @property @serializable.json_name('response') @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'response') @serializable.xml_sequence(3) - def responses(self) -> "SortedSet[ImpactAnalysisResponse]": + def responses(self) -> 'SortedSet[ImpactAnalysisResponse]': """ A list of responses to the vulnerability by the manufacturer, supplier, or project responsible for the affected component or service. More than one response is allowed. Responses are strongly encouraged for @@ -271,7 +268,7 @@ def responses(self) -> "SortedSet[ImpactAnalysisResponse]": def responses(self, responses: Iterable[ImpactAnalysisResponse]) -> None: self._responses = SortedSet(responses) - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def detail(self) -> Optional[str]: """ @@ -313,7 +310,7 @@ def __init__(self, *, url: XsUri, title: Optional[str] = None) -> None: self.title = title self.url = url - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def title(self) -> Optional[str]: """ @@ -325,7 +322,7 @@ def title(self) -> Optional[str]: def title(self, title: Optional[str]) -> None: self._title = title - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def url(self) -> XsUri: """ @@ -373,7 +370,7 @@ def __init__(self, *, name: Optional[str] = None, url: Optional[XsUri] = None) - self.name = name self.url = url - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def name(self) -> Optional[str]: """ @@ -385,7 +382,7 @@ def name(self) -> Optional[str]: def name(self, name: Optional[str]) -> None: self._name = name - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def url(self) -> Optional[XsUri]: """ @@ -436,7 +433,7 @@ def __init__(self, *, id: Optional[str] = None, source: Optional[VulnerabilitySo self.id = id self.source = source - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def id(self) -> Optional[str]: """ @@ -448,7 +445,7 @@ def id(self) -> Optional[str]: def id(self, id: Optional[str]) -> None: self._id = id - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def source(self) -> Optional[VulnerabilitySource]: """ @@ -563,7 +560,7 @@ class VulnerabilitySeverity(str, Enum): UNKNOWN = 'unknown' @staticmethod - def get_from_cvss_scores(scores: Union[Tuple[float], float, None]) -> 'VulnerabilitySeverity': + def get_from_cvss_scores(scores: Union[Tuple[float, ...], float, None]) -> 'VulnerabilitySeverity': """ Derives the Severity of a Vulnerability from it's declared CVSS scores. @@ -634,17 +631,18 @@ def __init__(self, *, source: Optional[VulnerabilitySource] = None, score: Optio self.justification = justification if score_base: - warnings.warn('`score_base` is deprecated - use `score`', DeprecationWarning) + warnings.warn('`score_base` is deprecated - use `score`', + category=DeprecationWarning, stacklevel=1) if score: warnings.warn('Both `score` and `score_base` supplied - the deprecated `score_base` will be discarded', - DeprecationWarning) + category=DeprecationWarning, stacklevel=1) else: self.score = Decimal(score_base) if vector and method: self.vector = method.get_localised_vector(vector=vector) - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def source(self) -> Optional[VulnerabilitySource]: """ @@ -656,7 +654,7 @@ def source(self) -> Optional[VulnerabilitySource]: def source(self, source: Optional[VulnerabilitySource]) -> None: self._source = source - @property # type: ignore[misc] + @property @serializable.string_format('.1f') @serializable.xml_sequence(2) def score(self) -> Optional[Decimal]: @@ -669,7 +667,7 @@ def score(self) -> Optional[Decimal]: def score(self, score: Optional[Decimal]) -> None: self._score = score - @property # type: ignore[misc] + @property @serializable.xml_sequence(3) def severity(self) -> Optional[VulnerabilitySeverity]: """ @@ -681,7 +679,7 @@ def severity(self) -> Optional[VulnerabilitySeverity]: def severity(self, severity: Optional[VulnerabilitySeverity]) -> None: self._severity = severity - @property # type: ignore[misc] + @property @serializable.xml_sequence(4) def method(self) -> Optional[VulnerabilityScoreSource]: """ @@ -693,7 +691,7 @@ def method(self) -> Optional[VulnerabilityScoreSource]: def method(self, score_source: Optional[VulnerabilityScoreSource]) -> None: self._method = score_source - @property # type: ignore[misc] + @property @serializable.xml_sequence(5) def vector(self) -> Optional[str]: """ @@ -705,7 +703,7 @@ def vector(self) -> Optional[str]: def vector(self, vector: Optional[str]) -> None: self._vector = vector - @property # type: ignore[misc] + @property @serializable.xml_sequence(6) def justification(self) -> Optional[str]: """ @@ -761,10 +759,10 @@ def __init__(self, *, organizations: Optional[Iterable[OrganizationalEntity]] = self.organizations = organizations or [] # type: ignore self.individuals = individuals or [] # type: ignore - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'organization') @serializable.xml_sequence(1) - def organizations(self) -> "SortedSet[OrganizationalEntity]": + def organizations(self) -> 'SortedSet[OrganizationalEntity]': """ The organizations credited with vulnerability discovery. @@ -777,10 +775,10 @@ def organizations(self) -> "SortedSet[OrganizationalEntity]": def organizations(self, organizations: Iterable[OrganizationalEntity]) -> None: self._organizations = SortedSet(organizations) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'individual') @serializable.xml_sequence(2) - def individuals(self) -> "SortedSet[OrganizationalContact]": + def individuals(self) -> 'SortedSet[OrganizationalContact]': """ The individuals, not associated with organizations, that are credited with vulnerability discovery. @@ -836,10 +834,10 @@ def __init__(self, *, bom_ref: Optional[Union[str, BomRef]] = None, id: Optional # Deprecated Parameters kept for backwards compatibility source_name: Optional[str] = None, source_url: Optional[str] = None, recommendations: Optional[Iterable[str]] = None) -> None: - if type(bom_ref) == BomRef: + if isinstance(bom_ref, BomRef): self._bom_ref = bom_ref else: - self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else str(uuid4())) + self._bom_ref = BomRef(value=str(bom_ref) if bom_ref else None) self.id = id self.source = source self.references = references or [] # type: ignore @@ -859,16 +857,18 @@ def __init__(self, *, bom_ref: Optional[Union[str, BomRef]] = None, id: Optional self.properties = properties or [] # type: ignore if source_name or source_url: - warnings.warn('`source_name` and `source_url` are deprecated - use `source`', DeprecationWarning) + warnings.warn('`source_name` and `source_url` are deprecated - use `source`', + category=DeprecationWarning, stacklevel=1) if not source: self.source = VulnerabilitySource(name=source_name, url=XsUri(source_url) if source_url else None) if recommendations: - warnings.warn('`recommendations` is deprecated - use `recommendation`', DeprecationWarning) + warnings.warn('`recommendations` is deprecated - use `recommendation`', + category=DeprecationWarning, stacklevel=1) if not recommendation: self.recommendation = next(iter(recommendations)) - @property # type: ignore[misc] + @property @serializable.json_name('bom-ref') @serializable.type_mapping(BomRefHelper) @serializable.xml_attribute() @@ -884,7 +884,7 @@ def bom_ref(self) -> BomRef: """ return self._bom_ref - @property # type: ignore[misc] + @property @serializable.xml_sequence(1) def id(self) -> Optional[str]: """ @@ -899,7 +899,7 @@ def id(self) -> Optional[str]: def id(self, id: Optional[str]) -> None: self._id = id - @property # type: ignore[misc] + @property @serializable.xml_sequence(2) def source(self) -> Optional[VulnerabilitySource]: """ @@ -914,10 +914,10 @@ def source(self) -> Optional[VulnerabilitySource]: def source(self, source: Optional[VulnerabilitySource]) -> None: self._source = source - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference') @serializable.xml_sequence(3) - def references(self) -> "SortedSet[VulnerabilityReference]": + def references(self) -> 'SortedSet[VulnerabilityReference]': """ Zero or more pointers to vulnerabilities that are the equivalent of the vulnerability specified. Often times, the same vulnerability may exist in multiple sources of vulnerability intelligence, but have different @@ -933,10 +933,10 @@ def references(self) -> "SortedSet[VulnerabilityReference]": def references(self, references: Iterable[VulnerabilityReference]) -> None: self._references = SortedSet(references) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'rating') @serializable.xml_sequence(4) - def ratings(self) -> "SortedSet[VulnerabilityRating]": + def ratings(self) -> 'SortedSet[VulnerabilityRating]': """ List of vulnerability ratings. @@ -949,10 +949,10 @@ def ratings(self) -> "SortedSet[VulnerabilityRating]": def ratings(self, ratings: Iterable[VulnerabilityRating]) -> None: self._ratings = SortedSet(ratings) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'cwe') @serializable.xml_sequence(5) - def cwes(self) -> "SortedSet[int]": + def cwes(self) -> 'SortedSet[int]': """ A list of CWE (Common Weakness Enumeration) identifiers. @@ -968,7 +968,7 @@ def cwes(self) -> "SortedSet[int]": def cwes(self, cwes: Iterable[int]) -> None: self._cwes = SortedSet(cwes) - @property # type: ignore[misc] + @property @serializable.xml_sequence(6) def description(self) -> Optional[str]: """ @@ -983,7 +983,7 @@ def description(self) -> Optional[str]: def description(self, description: Optional[str]) -> None: self._description = description - @property # type: ignore[misc] + @property @serializable.xml_sequence(7) def detail(self) -> Optional[str]: """ @@ -999,7 +999,7 @@ def detail(self) -> Optional[str]: def detail(self, detail: Optional[str]) -> None: self._detail = detail - @property # type: ignore[misc] + @property @serializable.xml_sequence(8) def recommendation(self) -> Optional[str]: """ @@ -1014,10 +1014,10 @@ def recommendation(self) -> Optional[str]: def recommendation(self, recommendation: Optional[str]) -> None: self._recommendation = recommendation - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'advisory') @serializable.xml_sequence(9) - def advisories(self) -> "SortedSet[VulnerabilityAdvisory]": + def advisories(self) -> 'SortedSet[VulnerabilityAdvisory]': """ Advisories relating to the Vulnerability. @@ -1030,7 +1030,7 @@ def advisories(self) -> "SortedSet[VulnerabilityAdvisory]": def advisories(self, advisories: Iterable[VulnerabilityAdvisory]) -> None: self._advisories = SortedSet(advisories) - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) @serializable.xml_sequence(10) def created(self) -> Optional[datetime]: @@ -1046,7 +1046,7 @@ def created(self) -> Optional[datetime]: def created(self, created: Optional[datetime]) -> None: self._created = created - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) @serializable.xml_sequence(11) def published(self) -> Optional[datetime]: @@ -1062,7 +1062,7 @@ def published(self) -> Optional[datetime]: def published(self, published: Optional[datetime]) -> None: self._published = published - @property # type: ignore[misc] + @property @serializable.type_mapping(serializable.helpers.XsdDateTime) @serializable.xml_sequence(12) def updated(self) -> Optional[datetime]: @@ -1078,7 +1078,7 @@ def updated(self) -> Optional[datetime]: def updated(self, updated: Optional[datetime]) -> None: self._updated = updated - @property # type: ignore[misc] + @property @serializable.xml_sequence(13) def credits(self) -> Optional[VulnerabilityCredits]: """ @@ -1093,10 +1093,10 @@ def credits(self) -> Optional[VulnerabilityCredits]: def credits(self, credits: Optional[VulnerabilityCredits]) -> None: self._credits = credits - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'tool') @serializable.xml_sequence(14) - def tools(self) -> "SortedSet[Tool]": + def tools(self) -> 'SortedSet[Tool]': """ The tool(s) used to identify, confirm, or score the vulnerability. @@ -1109,7 +1109,7 @@ def tools(self) -> "SortedSet[Tool]": def tools(self, tools: Iterable[Tool]) -> None: self._tools = SortedSet(tools) - @property # type: ignore[misc] + @property @serializable.xml_sequence(15) def analysis(self) -> Optional[VulnerabilityAnalysis]: """ @@ -1124,10 +1124,10 @@ def analysis(self) -> Optional[VulnerabilityAnalysis]: def analysis(self, analysis: Optional[VulnerabilityAnalysis]) -> None: self._analysis = analysis - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'target') @serializable.xml_sequence(16) - def affects(self) -> "SortedSet[BomTarget]": + def affects(self) -> 'SortedSet[BomTarget]': """ The components or services that are affected by the vulnerability. @@ -1140,10 +1140,10 @@ def affects(self) -> "SortedSet[BomTarget]": def affects(self, affects_targets: Iterable[BomTarget]) -> None: self._affects = SortedSet(affects_targets) - @property # type: ignore[misc] + @property @serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property') @serializable.xml_sequence(17) - def properties(self) -> "SortedSet[Property]": + def properties(self) -> 'SortedSet[Property]': """ Provides the ability to document properties in a key/value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. diff --git a/cyclonedx/output/__init__.py b/cyclonedx/output/__init__.py index 2f8658fa..f8245743 100644 --- a/cyclonedx/output/__init__.py +++ b/cyclonedx/output/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,40 +11,45 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Set of classes and methods for outputting our libraries internal Bom model to CycloneDX documents in varying formats and according to different versions of the CycloneDX schema standard. """ -import importlib import os +import warnings from abc import ABC, abstractmethod -from typing import Iterable, Union, cast +from typing import TYPE_CHECKING, Any, Literal, Mapping, Optional, Type, Union, overload -from ..model.bom import Bom -from ..model.component import Component from ..schema import OutputFormat, SchemaVersion +if TYPE_CHECKING: # pragma: no cover + from ..model.bom import Bom + from .json import Json as JsonOutputter + from .xml import Xml as XmlOutputter + LATEST_SUPPORTED_SCHEMA_VERSION = SchemaVersion.V1_4 class BaseOutput(ABC): - def __init__(self, bom: Bom, **kwargs: int) -> None: + def __init__(self, bom: 'Bom', **kwargs: int) -> None: super().__init__(**kwargs) self._bom = bom self._generated: bool = False - def _chained_components(self, container: Union[Bom, Component]) -> Iterable[Component]: - for component in container.components: - yield component - yield from self._chained_components(component) - @property @abstractmethod def schema_version(self) -> SchemaVersion: - pass + ... + + @property + @abstractmethod + def output_format(self) -> OutputFormat: + ... @property def generated(self) -> bool: @@ -56,53 +59,88 @@ def generated(self) -> bool: def generated(self, generated: bool) -> None: self._generated = generated - def get_bom(self) -> Bom: + def get_bom(self) -> 'Bom': return self._bom - def set_bom(self, bom: Bom) -> None: + def set_bom(self, bom: 'Bom') -> None: self._bom = bom @abstractmethod def generate(self, force_regeneration: bool = False) -> None: - pass + ... @abstractmethod - def output_as_string(self) -> str: - pass - - def output_to_file(self, filename: str, allow_overwrite: bool = False) -> None: + def output_as_string(self, *, + indent: Optional[Union[int, str]] = None, + **kwargs: Any) -> str: + ... + + def output_to_file(self, filename: str, allow_overwrite: bool = False, *, + indent: Optional[Union[int, str]] = None, + **kwargs: Any) -> None: # Check directory writable output_filename = os.path.realpath(filename) output_directory = os.path.dirname(output_filename) - if not os.access(output_directory, os.W_OK): raise PermissionError(output_directory) - if os.path.exists(output_filename) and not allow_overwrite: raise FileExistsError(output_filename) - with open(output_filename, mode='wb') as f_out: - f_out.write(self.output_as_string().encode('utf-8')) + f_out.write(self.output_as_string(indent=indent).encode('utf-8')) - f_out.close() +@overload +def make_outputter(bom: 'Bom', output_format: Literal[OutputFormat.JSON], + schema_version: SchemaVersion) -> 'JsonOutputter': + ... -def get_instance(bom: Bom, output_format: OutputFormat = OutputFormat.XML, - schema_version: SchemaVersion = LATEST_SUPPORTED_SCHEMA_VERSION) -> BaseOutput: + +@overload +def make_outputter(bom: 'Bom', output_format: Literal[OutputFormat.XML], + schema_version: SchemaVersion) -> 'XmlOutputter': + ... + + +@overload +def make_outputter(bom: 'Bom', output_format: OutputFormat, + schema_version: SchemaVersion) -> Union['XmlOutputter', 'JsonOutputter']: + ... + + +def make_outputter(bom: 'Bom', output_format: OutputFormat, schema_version: SchemaVersion) -> BaseOutput: """ Helper method to quickly get the correct output class/formatter. Pass in your BOM and optionally an output format and schema version (defaults to XML and latest schema version). + + Raises error when no instance could be made. + :param bom: Bom :param output_format: OutputFormat :param schema_version: SchemaVersion - :return: + :return: BaseOutput """ - try: - module = importlib.import_module(f"cyclonedx.output.{output_format.value.lower()}") - output_klass = getattr(module, f"{output_format.value}{schema_version.value}") - except (ImportError, AttributeError) as e: - raise ValueError(f"Unknown format {output_format.value.lower()!r}: {e}") from None - - return cast(BaseOutput, output_klass(bom=bom)) + if TYPE_CHECKING: # pragma: no cover + BY_SCHEMA_VERSION: Mapping[SchemaVersion, Type[BaseOutput]] # noqa:N806 + if OutputFormat.JSON is output_format: + from .json import BY_SCHEMA_VERSION + elif OutputFormat.XML is output_format: + from .xml import BY_SCHEMA_VERSION + else: + raise ValueError(f'Unexpected output_format: {output_format!r}') + + klass = BY_SCHEMA_VERSION.get(schema_version, None) + if klass is None: + raise ValueError(f'Unknown {output_format.name}/schema_version: {schema_version!r}') + return klass(bom) + + +def get_instance(bom: 'Bom', output_format: OutputFormat = OutputFormat.XML, + schema_version: SchemaVersion = LATEST_SUPPORTED_SCHEMA_VERSION) -> BaseOutput: + """DEPRECATED. use :func:`make_outputter` instead!""" + warnings.warn( + 'function `get_instance()` is deprecated, use `make_outputter()` instead.', + category=DeprecationWarning, stacklevel=1 + ) + return make_outputter(bom, output_format, schema_version) diff --git a/cyclonedx/output/json.py b/cyclonedx/output/json.py index 75bc030b..2fadb30e 100644 --- a/cyclonedx/output/json.py +++ b/cyclonedx/output/json.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,13 +15,12 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -import json from abc import abstractmethod -from typing import Optional +from json import dumps as json_dumps, loads as json_loads +from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, Type, Union from ..exception.output import FormatNotSupportedException -from ..model.bom import Bom -from ..schema import SchemaVersion +from ..schema import OutputFormat, SchemaVersion from ..schema.schema import ( SCHEMA_VERSIONS, BaseSchemaVersion, @@ -35,19 +32,28 @@ ) from . import BaseOutput +if TYPE_CHECKING: # pragma: no cover + from ..model.bom import Bom + class Json(BaseOutput, BaseSchemaVersion): - def __init__(self, bom: Bom) -> None: + def __init__(self, bom: 'Bom') -> None: super().__init__(bom=bom) - self._json_output: str = '' + self._bom_json: Dict[str, Any] = dict() @property def schema_version(self) -> SchemaVersion: return self.schema_version_enum + @property + def output_format(self) -> Literal[OutputFormat.JSON]: + return OutputFormat.JSON + def generate(self, force_regeneration: bool = False) -> None: - # New Way + if self.generated and not force_regeneration: + return + schema_uri: Optional[str] = self._get_schema_uri() if not schema_uri: raise FormatNotSupportedException( @@ -58,27 +64,22 @@ def generate(self, force_regeneration: bool = False) -> None: 'bomFormat': 'CycloneDX', 'specVersion': self.schema_version.to_version() } - _view = SCHEMA_VERSIONS.get(self.get_schema_version()) - if self.generated and force_regeneration: - self.get_bom().validate() - bom_json = json.loads(self.get_bom().as_json(view_=_view)) # type: ignore - bom_json.update(_json_core) - self._json_output = json.dumps(bom_json) - self.generated = True - return - elif self.generated: - return - else: - self.get_bom().validate() - bom_json = json.loads(self.get_bom().as_json(view_=_view)) # type: ignore - bom_json.update(_json_core) - self._json_output = json.dumps(bom_json) - self.generated = True - return - - def output_as_string(self) -> str: + _view = SCHEMA_VERSIONS.get(self.schema_version_enum) + bom = self.get_bom() + bom.validate() + bom_json: Dict[str, Any] = json_loads( + bom.as_json( # type:ignore[attr-defined] + view_=_view)) + bom_json.update(_json_core) + self._bom_json = bom_json + self.generated = True + + def output_as_string(self, *, + indent: Optional[Union[int, str]] = None, + **kwargs: Any) -> str: self.generate() - return self._json_output + return json_dumps(self._bom_json, + indent=indent) @abstractmethod def _get_schema_uri(self) -> Optional[str]: @@ -87,29 +88,38 @@ def _get_schema_uri(self) -> Optional[str]: class JsonV1Dot0(Json, SchemaVersion1Dot0): - def _get_schema_uri(self) -> Optional[str]: + def _get_schema_uri(self) -> None: return None class JsonV1Dot1(Json, SchemaVersion1Dot1): - def _get_schema_uri(self) -> Optional[str]: + def _get_schema_uri(self) -> None: return None class JsonV1Dot2(Json, SchemaVersion1Dot2): - def _get_schema_uri(self) -> Optional[str]: + def _get_schema_uri(self) -> str: return 'http://cyclonedx.org/schema/bom-1.2b.schema.json' class JsonV1Dot3(Json, SchemaVersion1Dot3): - def _get_schema_uri(self) -> Optional[str]: + def _get_schema_uri(self) -> str: return 'http://cyclonedx.org/schema/bom-1.3a.schema.json' class JsonV1Dot4(Json, SchemaVersion1Dot4): - def _get_schema_uri(self) -> Optional[str]: + def _get_schema_uri(self) -> str: return 'http://cyclonedx.org/schema/bom-1.4.schema.json' + + +BY_SCHEMA_VERSION: Dict[SchemaVersion, Type[Json]] = { + SchemaVersion.V1_4: JsonV1Dot4, + SchemaVersion.V1_3: JsonV1Dot3, + SchemaVersion.V1_2: JsonV1Dot2, + SchemaVersion.V1_1: JsonV1Dot1, + SchemaVersion.V1_0: JsonV1Dot0, +} diff --git a/cyclonedx/output/xml.py b/cyclonedx/output/xml.py index e85219fa..1f598113 100644 --- a/cyclonedx/output/xml.py +++ b/cyclonedx/output/xml.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,12 +15,12 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from typing import Optional -from xml.etree import ElementTree -from ..exception.output import BomGenerationErrorException -from ..model.bom import Bom -from ..schema import SchemaVersion +from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, Type, Union +from xml.dom.minidom import parseString as dom_parseString # nosec B408 +from xml.etree.ElementTree import Element as XmlElement, tostring as xml_dumps # nosec B405 + +from ..schema import OutputFormat, SchemaVersion from ..schema.schema import ( SCHEMA_VERSIONS, BaseSchemaVersion, @@ -34,44 +32,59 @@ ) from . import BaseOutput +if TYPE_CHECKING: # pragma: no cover + from ..model.bom import Bom -class Xml(BaseOutput, BaseSchemaVersion): - XML_VERSION_DECLARATION: str = '' - def __init__(self, bom: Bom) -> None: +class Xml(BaseSchemaVersion, BaseOutput): + def __init__(self, bom: 'Bom') -> None: super().__init__(bom=bom) - self._root_bom_element: Optional[ElementTree.Element] = None + self._bom_xml: str = '' @property def schema_version(self) -> SchemaVersion: return self.schema_version_enum + @property + def output_format(self) -> Literal[OutputFormat.XML]: + return OutputFormat.XML + def generate(self, force_regeneration: bool = False) -> None: - # New way - _view = SCHEMA_VERSIONS.get(self.get_schema_version()) - if self.generated and force_regeneration: - self.get_bom().validate() - self._root_bom_element = self.get_bom().as_xml( # type: ignore - view_=_view, as_string=False, xmlns=self.get_target_namespace() - ) - self.generated = True - return - elif self.generated: - return - else: - self.get_bom().validate() - self._root_bom_element = self.get_bom().as_xml( # type: ignore - view_=_view, as_string=False, xmlns=self.get_target_namespace() - ) - self.generated = True + if self.generated and not force_regeneration: return - def output_as_string(self) -> str: + _view = SCHEMA_VERSIONS[self.schema_version_enum] + bom = self.get_bom() + bom.validate() + xmlns = self.get_target_namespace() + self._bom_xml = '\n' + xml_dumps( + bom.as_xml( # type:ignore[attr-defined] + _view, as_string=False, xmlns=xmlns), + method='xml', default_namespace=xmlns, encoding='unicode', + # `xml-declaration` is inconsistent/bugged in py38, especially on Windows it will print a non-UTF8 codepage. + # Furthermore, it might add an encoding of "utf-8" which is redundant default value of XML. + # -> so we write the declaration manually, as long as py38 is supported. + xml_declaration=False) + + self.generated = True + + @staticmethod + def __make_indent(v: Optional[Union[int, str]]) -> str: + if isinstance(v, int): + return ' ' * v + if isinstance(v, str): + return v + return '' + + def output_as_string(self, *, + indent: Optional[Union[int, str]] = None, + **kwargs: Any) -> str: self.generate() - if self.generated and self._root_bom_element is not None: - return str(Xml.XML_VERSION_DECLARATION + ElementTree.tostring(self._root_bom_element, encoding='unicode')) - - raise BomGenerationErrorException('There was no Root XML Element after BOM generation.') + return self._bom_xml if indent is None else dom_parseString( # nosecc B318 + self._bom_xml).toprettyxml( + indent=self.__make_indent(indent) + # do not set `encoding` - this would convert result to binary, not string + ) def get_target_namespace(self) -> str: return f'http://cyclonedx.org/schema/bom/{self.get_schema_version()}' @@ -79,8 +92,8 @@ def get_target_namespace(self) -> str: class XmlV1Dot0(Xml, SchemaVersion1Dot0): - def _create_bom_element(self) -> ElementTree.Element: - return ElementTree.Element('bom', {'xmlns': self.get_target_namespace(), 'version': '1'}) + def _create_bom_element(self) -> XmlElement: + return XmlElement('bom', {'xmlns': self.get_target_namespace(), 'version': '1'}) class XmlV1Dot1(Xml, SchemaVersion1Dot1): @@ -97,3 +110,12 @@ class XmlV1Dot3(Xml, SchemaVersion1Dot3): class XmlV1Dot4(Xml, SchemaVersion1Dot4): pass + + +BY_SCHEMA_VERSION: Dict[SchemaVersion, Type[Xml]] = { + SchemaVersion.V1_4: XmlV1Dot4, + SchemaVersion.V1_3: XmlV1Dot3, + SchemaVersion.V1_2: XmlV1Dot2, + SchemaVersion.V1_1: XmlV1Dot1, + SchemaVersion.V1_0: XmlV1Dot0, +} diff --git a/cyclonedx/parser/__init__.py b/cyclonedx/parser/__init__.py index 1589f3cd..06990d47 100644 --- a/cyclonedx/parser/__init__.py +++ b/cyclonedx/parser/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,6 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Set of classes and methods which allow for quick creation of a Bom instance from your environment or Python project. @@ -40,7 +40,7 @@ def get_warning_message(self) -> str: return self._warning def __repr__(self) -> str: - return f'' + return f'' class BaseParser: diff --git a/cyclonedx/schema/__init__.py b/cyclonedx/schema/__init__.py index 9741a8e8..f0e38b05 100644 --- a/cyclonedx/schema/__init__.py +++ b/cyclonedx/schema/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,27 +11,92 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + + +from enum import Enum, auto, unique +from typing import Any, Type, TypeVar + + +@unique +class OutputFormat(Enum): + """Output formats. + + Cases are hashable. + + Do not rely on the actual/literal values, just use enum cases, like so: + my_of = OutputFormat.XML + """ + + JSON = auto() + XML = auto() + + def __hash__(self) -> int: + return hash(self.name) + + def __eq__(self, other: Any) -> bool: + return self is other -from enum import Enum +_SV = TypeVar('_SV', bound='SchemaVersion') -class OutputFormat(str, Enum): - JSON: str = 'Json' - XML: str = 'Xml' +@unique +class SchemaVersion(Enum): + """ + Schema version. -class SchemaVersion(str, Enum): - V1_0: str = 'V1Dot0' - V1_1: str = 'V1Dot1' - V1_2: str = 'V1Dot2' - V1_3: str = 'V1Dot3' - V1_4: str = 'V1Dot4' + Cases are hashable. + Cases are comparable(!=,>=,>,==,<,<=) + + Do not rely on the actual/literal values, just use enum cases, like so: + my_sv = SchemaVersion.V1_3 + """ + + V1_4 = (1, 4) + V1_3 = (1, 3) + V1_2 = (1, 2) + V1_1 = (1, 1) + V1_0 = (1, 0) + + @classmethod + def from_version(cls: Type[_SV], version: str) -> _SV: + """Return instance based of a version string - e.g. `1.4`""" + return cls(tuple(map(int, version.split('.')))[:2]) def to_version(self) -> str: - """ - Return as a version string - e.g. `1.4` + """Return as a version string - e.g. `1.4`""" + return '.'.join(map(str, self.value)) + + def __ne__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value != other.value + return NotImplemented # pragma: no cover + + def __lt__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value < other.value + return NotImplemented # pragma: no cover + + def __le__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value <= other.value + return NotImplemented # pragma: no cover + + def __eq__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value == other.value + return NotImplemented # pragma: no cover + + def __ge__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value >= other.value + return NotImplemented # pragma: no cover + + def __gt__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.value > other.value + return NotImplemented # pragma: no cover - Returns: - `str` version - """ - return f'{self.value[1]}.{self.value[5]}' + def __hash__(self) -> int: + return hash(self.name) diff --git a/cyclonedx/schema/_res/.editorconfig b/cyclonedx/schema/_res/.editorconfig new file mode 100644 index 00000000..6fe0e5e4 --- /dev/null +++ b/cyclonedx/schema/_res/.editorconfig @@ -0,0 +1,10 @@ + +# fix settings for files that are copied over, to keep them as is +[*.SNAPSHOT.xsd] +indent_size = 4 +indent_style = space +trim_trailing_whitespace = false +[*.SNAPSHOT.schema.json] +indent_size = 2 +indent_style = space +trim_trailing_whitespace = false \ No newline at end of file diff --git a/cyclonedx/schema/_res/.gitattributes b/cyclonedx/schema/_res/.gitattributes new file mode 100644 index 00000000..41a9eb42 --- /dev/null +++ b/cyclonedx/schema/_res/.gitattributes @@ -0,0 +1,6 @@ +# snapshots are vendored for offline use +*.SNAPSHOT.* linguist-vendored + +# specs are vendored for offline use +*.xsd linguist-vendored +*.schema.json linguist-vendored diff --git a/cyclonedx/schema/_res/README.md b/cyclonedx/schema/_res/README.md new file mode 100644 index 00000000..d7df0698 --- /dev/null +++ b/cyclonedx/schema/_res/README.md @@ -0,0 +1,30 @@ +# Resources: Schema files + +some schema for offline use as download via [script](../../../tools/schema-downloader.py). +original sources: + +Currently using version +[fd4d383658196992364e5d62568a48c431ace515](https://github.com/CycloneDX/specification/commit/fd4d383658196992364e5d62568a48c431ace515) + +| file | note | +|------|------| +| [`bom-1.0.SNAPSHOT.xsd`](bom-1.0.SNAPSHOT.xsd) | applied changes: 1 | +| [`bom-1.1.SNAPSHOT.xsd`](bom-1.1.SNAPSHOT.xsd) | applied changes: 1 | +| [`bom-1.2.SNAPSHOT.xsd`](bom-1.2.SNAPSHOT.xsd) | applied changes: 1 | +| [`bom-1.3.SNAPSHOT.xsd`](bom-1.3.SNAPSHOT.xsd) | applied changes: 1 | +| [`bom-1.4.SNAPSHOT.xsd`](bom-1.4.SNAPSHOT.xsd) | applied changes: 1 | +| [`bom-1.2.SNAPSHOT.schema.json`](bom-1.2.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 | +| [`bom-1.3.SNAPSHOT.schema.json`](bom-1.3.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 | +| [`bom-1.4.SNAPSHOT.schema.json`](bom-1.4.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 | +| [`bom-1.2-strict.SNAPSHOT.schema.json`](bom-1.2-strict.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 | +| [`bom-1.3-strict.SNAPSHOT.schema.json`](bom-1.3-strict.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 | +| [`spdx.SNAPSHOT.xsd`](spdx.SNAPSHOT.xsd) | | +| [`spdx.SNAPSHOT.schema.json`](spdx.SNAPSHOT.schema.json) | | +| [`jsf-0.82.SNAPSHOT.schema.json`](jsf-0.82.SNAPSHOT.schema.json) | | + +changes: +1. `https?://cyclonedx.org/schema/spdx` was replaced with `spdx.SNAPSHOT.xsd` +2. `spdx.schema.json` was replaced with `spdx.SNAPSHOT.schema.json` +3. `jsf-0.82.schema.json` was replaced with `jsf-0.82.SNAPSHOT.schema.json` +4. `properties.$schema.enum` was fixed to match `$id` +5. `required.version` removed, as it is actually optional with default value diff --git a/cyclonedx/schema/_res/__init__.py b/cyclonedx/schema/_res/__init__.py new file mode 100644 index 00000000..2a672d03 --- /dev/null +++ b/cyclonedx/schema/_res/__init__.py @@ -0,0 +1,61 @@ +# 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. + + +""" +Content in here is internal, not for public use. +Breaking changes without notice may happen. +""" + + +from os.path import dirname, join +from typing import Dict, Optional + +from .. import SchemaVersion + +__DIR = dirname(__file__) + +BOM_XML: Dict[SchemaVersion, Optional[str]] = { + SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.xsd'), + SchemaVersion.V1_3: join(__DIR, 'bom-1.3.SNAPSHOT.xsd'), + SchemaVersion.V1_2: join(__DIR, 'bom-1.2.SNAPSHOT.xsd'), + SchemaVersion.V1_1: join(__DIR, 'bom-1.1.SNAPSHOT.xsd'), + SchemaVersion.V1_0: join(__DIR, 'bom-1.0.SNAPSHOT.xsd'), +} + +BOM_JSON: Dict[SchemaVersion, Optional[str]] = { + SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.schema.json'), + SchemaVersion.V1_3: join(__DIR, 'bom-1.3.SNAPSHOT.schema.json'), + SchemaVersion.V1_2: join(__DIR, 'bom-1.2.SNAPSHOT.schema.json'), + # <= v1.1 is not defined in JSON + SchemaVersion.V1_1: None, + SchemaVersion.V1_0: None, +} + +BOM_JSON_STRICT: Dict[SchemaVersion, Optional[str]] = { + # >= v1.4 is already strict - no special file here + SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.schema.json'), + # <= 1.3 need special files + SchemaVersion.V1_3: join(__DIR, 'bom-1.3-strict.SNAPSHOT.schema.json'), + SchemaVersion.V1_2: join(__DIR, 'bom-1.2-strict.SNAPSHOT.schema.json'), + # <= v1.1 is not defined in JSON + SchemaVersion.V1_1: None, + SchemaVersion.V1_0: None, +} + +SPDX_JSON = join(__DIR, 'spdx.SNAPSHOT.schema.json') +SPDX_XML = join(__DIR, 'spdx.SNAPSHOT.xsd') + +JSF = join(__DIR, 'jsf-0.82.SNAPSHOT.schema.json') diff --git a/cyclonedx/schema/bom-1.0.xsd b/cyclonedx/schema/_res/bom-1.0.SNAPSHOT.xsd similarity index 99% rename from cyclonedx/schema/bom-1.0.xsd rename to cyclonedx/schema/_res/bom-1.0.SNAPSHOT.xsd index 815ed9ee..64d0e33f 100644 --- a/cyclonedx/schema/bom-1.0.xsd +++ b/cyclonedx/schema/_res/bom-1.0.SNAPSHOT.xsd @@ -7,9 +7,9 @@ targetNamespace="http://cyclonedx.org/schema/bom/1.0" vc:minVersion="1.0" vc:maxVersion="1.1" - version="1.0"> + version="1.0.1"> - + diff --git a/cyclonedx/schema/bom-1.1.xsd b/cyclonedx/schema/_res/bom-1.1.SNAPSHOT.xsd similarity index 99% rename from cyclonedx/schema/bom-1.1.xsd rename to cyclonedx/schema/_res/bom-1.1.SNAPSHOT.xsd index 1e7bc1e0..f21e9907 100644 --- a/cyclonedx/schema/bom-1.1.xsd +++ b/cyclonedx/schema/_res/bom-1.1.SNAPSHOT.xsd @@ -24,7 +24,7 @@ limitations under the License. vc:maxVersion="1.1" version="1.1"> - + @@ -38,6 +38,13 @@ limitations under the License. + + + Identifier-DataType for interlinked elements. + + + + @@ -201,7 +208,7 @@ limitations under the License. - + An optional identifier which can be used to reference the component elsewhere in the BOM. diff --git a/cyclonedx/schema/bom-1.2b.schema.json b/cyclonedx/schema/_res/bom-1.2-strict.SNAPSHOT.schema.json similarity index 98% rename from cyclonedx/schema/bom-1.2b.schema.json rename to cyclonedx/schema/_res/bom-1.2-strict.SNAPSHOT.schema.json index be21fb16..682cf739 100644 --- a/cyclonedx/schema/bom-1.2b.schema.json +++ b/cyclonedx/schema/_res/bom-1.2-strict.SNAPSHOT.schema.json @@ -6,15 +6,14 @@ "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", "required": [ "bomFormat", - "specVersion", - "version" + "specVersion" ], "additionalProperties": false, "properties": { "$schema": { "type": "string", "enum": [ - "http://cyclonedx.org/schema/bom-1.2a.schema.json" + "http://cyclonedx.org/schema/bom-1.2b.schema.json" ] }, "bomFormat": { @@ -87,6 +86,10 @@ } }, "definitions": { + "refType": { + "$comment": "Identifier-DataType for interlinked elements.", + "type": "string" + }, "metadata": { "type": "object", "title": "BOM Metadata Object", @@ -261,7 +264,7 @@ "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" }, "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique.", "default": "", @@ -595,7 +598,7 @@ "additionalProperties": false, "properties": { "id": { - "$ref": "spdx.schema.json", + "$ref": "spdx.SNAPSHOT.schema.json", "title": "License ID (SPDX)", "description": "A valid SPDX license ID", "examples": ["Apache-2.0"] @@ -859,8 +862,7 @@ "additionalProperties": false, "properties": { "ref": { - "type": "string", - "format": "string", + "$ref": "#/definitions/refType", "title": "Reference", "description": "References a component by the components bom-ref attribute" }, @@ -868,7 +870,7 @@ "type": "array", "uniqueItems": true, "items": { - "type": "string" + "$ref": "#/definitions/refType" }, "title": "Depends On", "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." @@ -884,7 +886,7 @@ "additionalProperties": false, "properties": { "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique.", "default": "", diff --git a/cyclonedx/schema/bom-1.2.schema.json b/cyclonedx/schema/_res/bom-1.2.SNAPSHOT.schema.json similarity index 98% rename from cyclonedx/schema/bom-1.2.schema.json rename to cyclonedx/schema/_res/bom-1.2.SNAPSHOT.schema.json index 2e44d942..d23f683b 100644 --- a/cyclonedx/schema/bom-1.2.schema.json +++ b/cyclonedx/schema/_res/bom-1.2.SNAPSHOT.schema.json @@ -1,13 +1,12 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://cyclonedx.org/schema/bom-1.2a.schema.json", + "$id": "http://cyclonedx.org/schema/bom-1.2b.schema.json", "type": "object", "title": "CycloneDX Software Bill-of-Material Specification", "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", "required": [ "bomFormat", - "specVersion", - "version" + "specVersion" ], "properties": { "bomFormat": { @@ -80,6 +79,10 @@ } }, "definitions": { + "refType": { + "$comment": "Identifier-DataType for interlinked elements.", + "type": "string" + }, "metadata": { "type": "object", "title": "BOM Metadata Object", @@ -143,7 +146,7 @@ "description": "The date and time (timestamp) when the document was created." }, "hashes": { - "$id": "#/properties/hashes", + "$id": "#/definitions/tool/properties/hashes", "type": "array", "items": {"$ref": "#/definitions/hash"}, "title": "Hashes", @@ -249,7 +252,7 @@ "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" }, "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique.", "default": "", @@ -432,7 +435,7 @@ "title": "External References" }, "components": { - "$id": "#/properties/components", + "$id": "#/definitions/component/properties/components", "type": "array", "items": {"$ref": "#/definitions/component"}, "uniqueItems": true, @@ -577,7 +580,7 @@ ], "properties": { "id": { - "$ref": "spdx.schema.json", + "$ref": "spdx.SNAPSHOT.schema.json", "title": "License ID (SPDX)", "description": "A valid SPDX license ID", "examples": ["Apache-2.0"] @@ -833,7 +836,7 @@ ], "properties": { "ref": { - "type": "string", + "$ref": "#/definitions/refType", "format": "string", "title": "Reference", "description": "References a component by the components bom-ref attribute" @@ -842,7 +845,7 @@ "type": "array", "uniqueItems": true, "items": { - "type": "string" + "$ref": "#/definitions/refType" }, "title": "Depends On", "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." @@ -857,7 +860,7 @@ ], "properties": { "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique.", "default": "", @@ -957,7 +960,7 @@ "title": "External References" }, "services": { - "$id": "#/properties/services", + "$id": "#/definitions/service/properties/services", "type": "array", "items": {"$ref": "#/definitions/service"}, "uniqueItems": true, diff --git a/cyclonedx/schema/bom-1.2.xsd b/cyclonedx/schema/_res/bom-1.2.SNAPSHOT.xsd similarity index 99% rename from cyclonedx/schema/bom-1.2.xsd rename to cyclonedx/schema/_res/bom-1.2.SNAPSHOT.xsd index 2eb7e486..763e6ee6 100644 --- a/cyclonedx/schema/bom-1.2.xsd +++ b/cyclonedx/schema/_res/bom-1.2.SNAPSHOT.xsd @@ -24,7 +24,7 @@ limitations under the License. vc:maxVersion="1.1" version="1.2.1"> - + @@ -38,6 +38,13 @@ limitations under the License. + + + Identifier-DataType for interlinked elements. + + + + @@ -395,7 +402,7 @@ limitations under the License. - + An optional identifier which can be used to reference the component elsewhere in the BOM. @@ -1144,7 +1151,7 @@ limitations under the License. - + References a component or service by the its bom-ref attribute @@ -1302,7 +1309,7 @@ limitations under the License. - + An optional identifier which can be used to reference the service elsewhere in the BOM. @@ -1415,4 +1422,4 @@ limitations under the License. - \ No newline at end of file + diff --git a/cyclonedx/schema/bom-1.3a.schema.json b/cyclonedx/schema/_res/bom-1.3-strict.SNAPSHOT.schema.json similarity index 98% rename from cyclonedx/schema/bom-1.3a.schema.json rename to cyclonedx/schema/_res/bom-1.3-strict.SNAPSHOT.schema.json index 41b0b945..a1142620 100644 --- a/cyclonedx/schema/bom-1.3a.schema.json +++ b/cyclonedx/schema/_res/bom-1.3-strict.SNAPSHOT.schema.json @@ -6,15 +6,14 @@ "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", "required": [ "bomFormat", - "specVersion", - "version" + "specVersion" ], "additionalProperties": false, "properties": { "$schema": { "type": "string", "enum": [ - "http://cyclonedx.org/schema/bom-1.3.schema.json" + "http://cyclonedx.org/schema/bom-1.3a.schema.json" ] }, "bomFormat": { @@ -94,6 +93,10 @@ } }, "definitions": { + "refType": { + "$comment": "Identifier-DataType for interlinked elements.", + "type": "string" + }, "metadata": { "type": "object", "title": "BOM Metadata Object", @@ -267,7 +270,7 @@ "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" }, "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique." }, @@ -563,7 +566,7 @@ "additionalProperties": false, "properties": { "id": { - "$ref": "spdx.schema.json", + "$ref": "spdx.SNAPSHOT.schema.json", "title": "License ID (SPDX)", "description": "A valid SPDX license ID", "examples": ["Apache-2.0"] @@ -852,7 +855,7 @@ "additionalProperties": false, "properties": { "ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "Reference", "description": "References a component by the components bom-ref attribute" }, @@ -860,7 +863,7 @@ "type": "array", "uniqueItems": true, "items": { - "type": "string" + "$ref": "#/definitions/refType" }, "title": "Depends On", "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." @@ -876,7 +879,7 @@ "additionalProperties": false, "properties": { "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique." }, diff --git a/cyclonedx/schema/bom-1.3.schema.json b/cyclonedx/schema/_res/bom-1.3.SNAPSHOT.schema.json similarity index 98% rename from cyclonedx/schema/bom-1.3.schema.json rename to cyclonedx/schema/_res/bom-1.3.SNAPSHOT.schema.json index fdec9736..a269ebd7 100644 --- a/cyclonedx/schema/bom-1.3.schema.json +++ b/cyclonedx/schema/_res/bom-1.3.SNAPSHOT.schema.json @@ -1,13 +1,12 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://cyclonedx.org/schema/bom-1.3.schema.json", + "$id": "http://cyclonedx.org/schema/bom-1.3a.schema.json", "type": "object", "title": "CycloneDX Software Bill-of-Material Specification", "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", "required": [ "bomFormat", - "specVersion", - "version" + "specVersion" ], "properties": { "bomFormat": { @@ -87,6 +86,10 @@ } }, "definitions": { + "refType": { + "$comment": "Identifier-DataType for interlinked elements.", + "type": "string" + }, "metadata": { "type": "object", "title": "BOM Metadata Object", @@ -158,7 +161,7 @@ "description": "The date and time (timestamp) when the document was created." }, "hashes": { - "$id": "#/properties/hashes", + "$id": "#/definitions/tool/properties/hashes", "type": "array", "items": {"$ref": "#/definitions/hash"}, "title": "Hashes", @@ -255,7 +258,7 @@ "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" }, "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique." }, @@ -395,7 +398,7 @@ "title": "External References" }, "components": { - "$id": "#/properties/components", + "$id": "#/definitions/component/properties/components", "type": "array", "items": {"$ref": "#/definitions/component"}, "uniqueItems": true, @@ -546,7 +549,7 @@ ], "properties": { "id": { - "$ref": "spdx.schema.json", + "$ref": "spdx.SNAPSHOT.schema.json", "title": "License ID (SPDX)", "description": "A valid SPDX license ID", "examples": ["Apache-2.0"] @@ -809,7 +812,7 @@ ] }, "hashes": { - "$id": "#/properties/hashes", + "$id": "#/definitions/externalReference/properties/hashes", "type": "array", "items": {"$ref": "#/definitions/hash"}, "title": "Hashes", @@ -826,7 +829,7 @@ ], "properties": { "ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "Reference", "description": "References a component by the components bom-ref attribute" }, @@ -834,7 +837,7 @@ "type": "array", "uniqueItems": true, "items": { - "type": "string" + "$ref": "#/definitions/refType" }, "title": "Depends On", "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." @@ -849,7 +852,7 @@ ], "properties": { "bom-ref": { - "type": "string", + "$ref": "#/definitions/refType", "title": "BOM Reference", "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique." }, @@ -918,7 +921,7 @@ "title": "External References" }, "services": { - "$id": "#/properties/services", + "$id": "#/definitions/service/properties/services", "type": "array", "items": {"$ref": "#/definitions/service"}, "uniqueItems": true, diff --git a/cyclonedx/schema/bom-1.3.xsd b/cyclonedx/schema/_res/bom-1.3.SNAPSHOT.xsd similarity index 99% rename from cyclonedx/schema/bom-1.3.xsd rename to cyclonedx/schema/_res/bom-1.3.SNAPSHOT.xsd index 904d6369..150de444 100644 --- a/cyclonedx/schema/bom-1.3.xsd +++ b/cyclonedx/schema/_res/bom-1.3.SNAPSHOT.xsd @@ -24,7 +24,7 @@ limitations under the License. vc:maxVersion="1.1" version="1.3.1"> - + @@ -35,6 +35,13 @@ limitations under the License. + + + Identifier-DataType for interlinked elements. + + + + @@ -400,7 +407,7 @@ limitations under the License. - + An optional identifier which can be used to reference the component elsewhere in the BOM. @@ -555,7 +562,9 @@ limitations under the License. A hardware device such as a processor, or chip-set. A hardware device containing firmware should include a component for the physical hardware itself, and another component of type 'firmware' or 'operating-system' (whichever is relevant), describing - information about the software running on the device. + information about the software running on the device. + See also the list of known device properties: https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/device.md + @@ -1156,7 +1165,7 @@ limitations under the License. - + References a component or service by the its bom-ref attribute @@ -1309,7 +1318,7 @@ limitations under the License. - + An optional identifier which can be used to reference the service elsewhere in the BOM. @@ -1502,7 +1511,7 @@ limitations under the License. - + References a component or service by the its bom-ref attribute @@ -1628,4 +1637,4 @@ limitations under the License. - \ No newline at end of file + diff --git a/cyclonedx/schema/bom-1.4.schema.json b/cyclonedx/schema/_res/bom-1.4.SNAPSHOT.schema.json similarity index 98% rename from cyclonedx/schema/bom-1.4.schema.json rename to cyclonedx/schema/_res/bom-1.4.SNAPSHOT.schema.json index 85684d76..1a885810 100644 --- a/cyclonedx/schema/bom-1.4.schema.json +++ b/cyclonedx/schema/_res/bom-1.4.SNAPSHOT.schema.json @@ -6,8 +6,7 @@ "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", "required": [ "bomFormat", - "specVersion", - "version" + "specVersion" ], "additionalProperties": false, "properties": { @@ -282,7 +281,7 @@ "file" ], "title": "Component Type", - "description": "Specifies the type of component. For software components, classify as application if no more specific appropriate classification is available or cannot be determined for the component. Types include:\n\n* __application__ = A software application. Refer to [https://en.wikipedia.org/wiki/Application_software](https://en.wikipedia.org/wiki/Application_software) for information about applications.\n* __framework__ = A software framework. Refer to [https://en.wikipedia.org/wiki/Software_framework](https://en.wikipedia.org/wiki/Software_framework) for information on how frameworks vary slightly from libraries.\n* __library__ = A software library. Refer to [https://en.wikipedia.org/wiki/Library_(computing)](https://en.wikipedia.org/wiki/Library_(computing))\n for information about libraries. All third-party and open source reusable components will likely be a library. If the library also has key features of a framework, then it should be classified as a framework. If not, or is unknown, then specifying library is RECOMMENDED.\n* __container__ = A packaging and/or runtime format, not specific to any particular technology, which isolates software inside the container from software outside of a container through virtualization technology. Refer to [https://en.wikipedia.org/wiki/OS-level_virtualization](https://en.wikipedia.org/wiki/OS-level_virtualization)\n* __operating-system__ = A software operating system without regard to deployment model (i.e. installed on physical hardware, virtual machine, image, etc) Refer to [https://en.wikipedia.org/wiki/Operating_system](https://en.wikipedia.org/wiki/Operating_system)\n* __device__ = A hardware device such as a processor, or chip-set. A hardware device containing firmware SHOULD include a component for the physical hardware itself, and another component of type 'firmware' or 'operating-system' (whichever is relevant), describing information about the software running on the device.\n* __firmware__ = A special type of software that provides low-level control over a devices hardware. Refer to [https://en.wikipedia.org/wiki/Firmware](https://en.wikipedia.org/wiki/Firmware)\n* __file__ = A computer file. Refer to [https://en.wikipedia.org/wiki/Computer_file](https://en.wikipedia.org/wiki/Computer_file) for information about files.", + "description": "Specifies the type of component. For software components, classify as application if no more specific appropriate classification is available or cannot be determined for the component. Types include:\n\n* __application__ = A software application. Refer to [https://en.wikipedia.org/wiki/Application_software](https://en.wikipedia.org/wiki/Application_software) for information about applications.\n* __framework__ = A software framework. Refer to [https://en.wikipedia.org/wiki/Software_framework](https://en.wikipedia.org/wiki/Software_framework) for information on how frameworks vary slightly from libraries.\n* __library__ = A software library. Refer to [https://en.wikipedia.org/wiki/Library_(computing)](https://en.wikipedia.org/wiki/Library_(computing))\n for information about libraries. All third-party and open source reusable components will likely be a library. If the library also has key features of a framework, then it should be classified as a framework. If not, or is unknown, then specifying library is RECOMMENDED.\n* __container__ = A packaging and/or runtime format, not specific to any particular technology, which isolates software inside the container from software outside of a container through virtualization technology. Refer to [https://en.wikipedia.org/wiki/OS-level_virtualization](https://en.wikipedia.org/wiki/OS-level_virtualization)\n* __operating-system__ = A software operating system without regard to deployment model (i.e. installed on physical hardware, virtual machine, image, etc) Refer to [https://en.wikipedia.org/wiki/Operating_system](https://en.wikipedia.org/wiki/Operating_system)\n* __device__ = A hardware device such as a processor, or chip-set. A hardware device containing firmware SHOULD include a component for the physical hardware itself, and another component of type 'firmware' or 'operating-system' (whichever is relevant), describing information about the software running on the device.\n See also the list of [known device properties](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/device.md).\n* __firmware__ = A special type of software that provides low-level control over a devices hardware. Refer to [https://en.wikipedia.org/wiki/Firmware](https://en.wikipedia.org/wiki/Firmware)\n* __file__ = A computer file. Refer to [https://en.wikipedia.org/wiki/Computer_file](https://en.wikipedia.org/wiki/Computer_file) for information about files.", "examples": ["library"] }, "mime-type": { @@ -611,7 +610,7 @@ "additionalProperties": false, "properties": { "id": { - "$ref": "spdx.schema.json", + "$ref": "spdx.SNAPSHOT.schema.json", "title": "License ID (SPDX)", "description": "A valid SPDX license ID", "examples": ["Apache-2.0"] @@ -1488,7 +1487,7 @@ "type": "array", "title": "CWEs", "description": "List of Common Weaknesses Enumerations (CWEs) codes that describes this vulnerability. For example 399 (of https://cwe.mitre.org/data/definitions/399.html)", - "examples": ["399"], + "examples": [399], "additionalItems": false, "items": { "$ref": "#/definitions/cwe" @@ -1641,7 +1640,7 @@ }, "range": { "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst", - "$ref": "#/definitions/version" + "$ref": "#/definitions/range" }, "status": { "description": "The vulnerability status for the version or range of versions.", @@ -1689,9 +1688,9 @@ "maxLength": 1024 }, "signature": { - "$ref": "jsf-0.82.schema.json#/definitions/signature", + "$ref": "jsf-0.82.SNAPSHOT.schema.json#/definitions/signature", "title": "Signature", "description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)." } } -} \ No newline at end of file +} diff --git a/cyclonedx/schema/bom-1.4.xsd b/cyclonedx/schema/_res/bom-1.4.SNAPSHOT.xsd similarity index 99% rename from cyclonedx/schema/bom-1.4.xsd rename to cyclonedx/schema/_res/bom-1.4.SNAPSHOT.xsd index 9cf8af24..4b3b250d 100644 --- a/cyclonedx/schema/bom-1.4.xsd +++ b/cyclonedx/schema/_res/bom-1.4.SNAPSHOT.xsd @@ -24,7 +24,7 @@ limitations under the License. vc:maxVersion="1.1" version="1.4.2"> - + @@ -577,7 +577,9 @@ limitations under the License. A hardware device such as a processor, or chip-set. A hardware device containing firmware SHOULD include a component for the physical hardware itself, and another component of type 'firmware' or 'operating-system' (whichever is relevant), describing - information about the software running on the device. + information about the software running on the device. + See also the list of known device properties: https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/device.md + @@ -1969,7 +1971,7 @@ limitations under the License. - + References a component or service by the objects bom-ref. @@ -2414,4 +2416,4 @@ limitations under the License. - \ No newline at end of file + diff --git a/cyclonedx/schema/_res/jsf-0.82.SNAPSHOT.schema.json b/cyclonedx/schema/_res/jsf-0.82.SNAPSHOT.schema.json new file mode 100644 index 00000000..f46bfb1e --- /dev/null +++ b/cyclonedx/schema/_res/jsf-0.82.SNAPSHOT.schema.json @@ -0,0 +1,240 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://cyclonedx.org/schema/jsf-0.82.schema.json", + "type": "object", + "title": "JSON Signature Format (JSF) standard", + "$comment" : "JSON Signature Format schema is published under the terms of the Apache License 2.0. JSF was developed by Anders Rundgren (anders.rundgren.net@gmail.com) as a part of the OpenKeyStore project. This schema supports the entirely of the JSF standard excluding 'extensions'.", + "definitions": { + "signature": { + "type": "object", + "title": "Signature", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "signers": { + "type": "array", + "title": "Signature", + "description": "Unique top level property for Multiple Signatures. (multisignature)", + "items": {"$ref": "#/definitions/signer"} + } + } + }, + { + "additionalProperties": false, + "properties": { + "chain": { + "type": "array", + "title": "Signature", + "description": "Unique top level property for Signature Chains. (signaturechain)", + "items": {"$ref": "#/definitions/signer"} + } + } + }, + { + "title": "Signature", + "description": "Unique top level property for simple signatures. (signaturecore)", + "$ref": "#/definitions/signer" + } + ] + }, + "signer": { + "type": "object", + "title": "Signature", + "required": [ + "algorithm", + "value" + ], + "additionalProperties": false, + "properties": { + "algorithm": { + "oneOf": [ + { + "type": "string", + "title": "Algorithm", + "description": "Signature algorithm. The currently recognized JWA [RFC7518] and RFC8037 [RFC8037] asymmetric key algorithms. Note: Unlike RFC8037 [RFC8037] JSF requires explicit Ed* algorithm names instead of \"EdDSA\".", + "enum": [ + "RS256", + "RS384", + "RS512", + "PS256", + "PS384", + "PS512", + "ES256", + "ES384", + "ES512", + "Ed25519", + "Ed448", + "HS256", + "HS384", + "HS512" + ] + }, + { + "type": "string", + "title": "Algorithm", + "description": "Signature algorithm. Note: If proprietary signature algorithms are added, they must be expressed as URIs.", + "format": "uri" + } + ] + }, + "keyId": { + "type": "string", + "title": "Key ID", + "description": "Optional. Application specific string identifying the signature key." + }, + "publicKey": { + "title": "Public key", + "description": "Optional. Public key object.", + "$ref": "#/definitions/publicKey" + }, + "certificatePath": { + "type": "array", + "title": "Certificate path", + "description": "Optional. Sorted array of X.509 [RFC5280] certificates, where the first element must contain the signature certificate. The certificate path must be contiguous but is not required to be complete.", + "items": { + "type": "string" + } + }, + "excludes": { + "type": "array", + "title": "Excludes", + "description": "Optional. Array holding the names of one or more application level properties that must be excluded from the signature process. Note that the \"excludes\" property itself, must also be excluded from the signature process. Since both the \"excludes\" property and the associated data it points to are unsigned, a conforming JSF implementation must provide options for specifying which properties to accept.", + "items": { + "type": "string" + } + }, + "value": { + "type": "string", + "title": "Signature", + "description": "The signature data. Note that the binary representation must follow the JWA [RFC7518] specifications." + } + } + }, + "keyType": { + "type": "string", + "title": "Key type", + "description": "Key type indicator.", + "enum": [ + "EC", + "OKP", + "RSA" + ] + }, + "publicKey": { + "title": "Public key", + "description": "Optional. Public key object.", + "type": "object", + "required": [ + "kty" + ], + "additionalProperties": true, + "properties": { + "kty": { + "$ref": "#/definitions/keyType" + } + }, + "allOf": [ + { + "if": { + "properties": { "kty": { "const": "EC" } } + }, + "then": { + "required": [ + "kty", + "crv", + "x", + "y" + ], + "additionalProperties": false, + "properties": { + "kty": { + "$ref": "#/definitions/keyType" + }, + "crv": { + "type": "string", + "title": "Curve name", + "description": "EC curve name.", + "enum": [ + "P-256", + "P-384", + "P-521" + ] + }, + "x": { + "type": "string", + "title": "Coordinate", + "description": "EC curve point X. The length of this field must be the full size of a coordinate for the curve specified in the \"crv\" parameter. For example, if the value of \"crv\" is \"P-521\", the decoded argument must be 66 bytes." + }, + "y": { + "type": "string", + "title": "Coordinate", + "description": "EC curve point Y. The length of this field must be the full size of a coordinate for the curve specified in the \"crv\" parameter. For example, if the value of \"crv\" is \"P-256\", the decoded argument must be 32 bytes." + } + } + } + }, + { + "if": { + "properties": { "kty": { "const": "OKP" } } + }, + "then": { + "required": [ + "kty", + "crv", + "x" + ], + "additionalProperties": false, + "properties": { + "kty": { + "$ref": "#/definitions/keyType" + }, + "crv": { + "type": "string", + "title": "Curve name", + "description": "EdDSA curve name.", + "enum": [ + "Ed25519", + "Ed448" + ] + }, + "x": { + "type": "string", + "title": "Coordinate", + "description": "EdDSA curve point X. The length of this field must be the full size of a coordinate for the curve specified in the \"crv\" parameter. For example, if the value of \"crv\" is \"Ed25519\", the decoded argument must be 32 bytes." + } + } + } + }, + { + "if": { + "properties": { "kty": { "const": "RSA" } } + }, + "then": { + "required": [ + "kty", + "n", + "e" + ], + "additionalProperties": false, + "properties": { + "kty": { + "$ref": "#/definitions/keyType" + }, + "n": { + "type": "string", + "title": "Modulus", + "description": "RSA modulus." + }, + "e": { + "type": "string", + "title": "Exponent", + "description": "RSA exponent." + } + } + } + } + ] + } + } +} diff --git a/cyclonedx/schema/spdx.schema.json b/cyclonedx/schema/_res/spdx.SNAPSHOT.schema.json similarity index 84% rename from cyclonedx/schema/spdx.schema.json rename to cyclonedx/schema/_res/spdx.SNAPSHOT.schema.json index 26013fa6..f04d013c 100644 --- a/cyclonedx/schema/spdx.schema.json +++ b/cyclonedx/schema/_res/spdx.SNAPSHOT.schema.json @@ -1,538 +1,621 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://cyclonedx.org/schema/spdx.schema.json", - "$comment": "v1.0-3.17", + "$comment": "v1.0-3.21", "type": "string", "enum": [ - "CC-BY-NC-ND-2.0", - "SGI-B-2.0", - "LPPL-1.3c", - "NIST-PD-fallback", - "libtiff", - "XSkat", - "PDDL-1.0", - "KiCad-libraries-exception", - "CC-BY-NC-SA-1.0", - "GFDL-1.1-no-invariants-only", - "Xerox", - "LPPL-1.1", - "VOSTROM", - "UCL-1.0", - "ADSL", - "OSL-2.0", + "0BSD", "AAL", - "FDK-AAC", - "W3C-20150513", + "Abstyles", + "AdaCore-doc", + "Adobe-2006", + "Adobe-Glyph", + "ADSL", "AFL-1.1", - "W3C", - "Sleepycat", - "CECILL-1.1", - "mpich2", - "SISSL", - "NLOD-1.0", - "ANTLR-PD", - "GPL-3.0-only", - "gnuplot", - "NLOD-2.0", - "BSD-3-Clause-Open-MPI", - "LiLiQ-P-1.1", - "BSD-3-Clause-Clear", - "FSFUL", - "CC-BY-NC-SA-2.0-UK", - "CERN-OHL-S-2.0", - "Spencer-94", - "CERN-OHL-1.2", - "GFDL-1.1-or-later", + "AFL-1.2", + "AFL-2.0", + "AFL-2.1", + "AFL-3.0", + "Afmparse", + "AGPL-1.0", + "AGPL-1.0-only", "AGPL-1.0-or-later", - "Wsuipa", + "AGPL-3.0", + "AGPL-3.0-only", + "AGPL-3.0-or-later", + "Aladdin", + "AMDPLPA", "AML", - "BSD-2-Clause", - "DSDP", - "CC-BY-2.5", - "MIT-CMU", - "Beerware", - "Sendmail", - "TU-Berlin-1.0", - "CNRI-Jython", - "mplus", - "CPOL-1.02", - "BSD-3-Clause-No-Nuclear-License-2014", - "ISC", - "CC-BY-SA-4.0", - "Eurosym", - "LGPL-3.0-only", - "OLDAP-1.3", - "GFDL-1.1-invariants-or-later", - "Glulxe", - "SimPL-2.0", - "CDLA-Permissive-2.0", - "GPL-2.0-with-font-exception", - "OGL-UK-2.0", - "CC-BY-SA-3.0-DE", - "CC-BY-ND-1.0", - "GFDL-1.1", - "CC-BY-4.0", - "OpenSSL", - "TU-Berlin-2.0", - "DOC", - "GFDL-1.2-no-invariants-or-later", - "QPL-1.0", - "OLDAP-2.8", - "OML", - "OLDAP-2.7", - "NIST-PD", - "Bitstream-Vera", - "GFDL-1.2-or-later", - "OFL-1.1-RFN", - "Bahyph", - "Barr", - "COIL-1.0", - "GFDL-1.3", - "CECILL-B", - "JPNIC", - "Zed", - "ICU", - "CC-BY-NC-SA-2.5", - "CC-BY-ND-3.0-DE", - "bzip2-1.0.5", - "SPL-1.0", - "YPL-1.0", - "OSET-PL-2.1", - "Noweb", - "RPSL-1.0", - "BSD-3-Clause-LBNL", - "CDLA-Sharing-1.0", - "CECILL-1.0", "AMPAS", + "ANTLR-PD", + "ANTLR-PD-fallback", + "Apache-1.0", + "Apache-1.1", + "Apache-2.0", "APAFML", - "CC-BY-ND-3.0", - "D-FSL-1.0", - "CC-BY-NC-3.0", - "libpng-2.0", - "PolyForm-Noncommercial-1.0.0", - "dvipdfm", - "GFDL-1.3-or-later", - "OGTSL", - "NPL-1.1", - "GPL-3.0", - "CERN-OHL-P-2.0", - "BlueOak-1.0.0", - "AGPL-3.0-or-later", - "blessing", - "ImageMagick", + "APL-1.0", + "App-s2p", + "APSL-1.0", + "APSL-1.1", + "APSL-1.2", "APSL-2.0", - "MIT-advertising", - "curl", - "CC0-1.0", - "Zimbra-1.4", - "SSPL-1.0", - "psutils", - "CC-BY-SA-2.0-UK", - "PSF-2.0", - "Net-SNMP", - "NAIST-2003", - "GFDL-1.2-invariants-or-later", - "SGI-B-1.0", - "NBPL-1.0", - "GFDL-1.2-invariants-only", - "W3C-19980720", - "OFL-1.0-no-RFN", - "NetCDF", - "TMate", - "NOSL", - "CNRI-Python-GPL-Compatible", + "Arphic-1999", + "Artistic-1.0", + "Artistic-1.0-cl8", + "Artistic-1.0-Perl", + "Artistic-2.0", + "ASWF-Digital-Assets-1.0", + "ASWF-Digital-Assets-1.1", + "Baekmuk", + "Bahyph", + "Barr", + "Beerware", + "Bitstream-Charter", + "Bitstream-Vera", + "BitTorrent-1.0", + "BitTorrent-1.1", + "blessing", + "BlueOak-1.0.0", + "Boehm-GC", + "Borceux", + "Brian-Gladman-3-Clause", "BSD-1-Clause", - "CC-BY-NC-SA-3.0-DE", + "BSD-2-Clause", + "BSD-2-Clause-FreeBSD", + "BSD-2-Clause-NetBSD", + "BSD-2-Clause-Patent", + "BSD-2-Clause-Views", + "BSD-3-Clause", + "BSD-3-Clause-Attribution", + "BSD-3-Clause-Clear", + "BSD-3-Clause-LBNL", "BSD-3-Clause-Modification", - "GLWTPL", - "GFDL-1.3-only", - "OLDAP-2.2", - "CC-BY-ND-4.0", - "CC-BY-NC-ND-3.0-DE", - "EUPL-1.0", - "Linux-OpenIB", - "LGPL-2.0-or-later", - "OSL-1.1", - "Spencer-86", - "LGPL-2.0", - "CC-PDDC", - "CC-BY-NC-ND-3.0", - "CDL-1.0", - "Elastic-2.0", - "CC-BY-2.0", "BSD-3-Clause-No-Military-License", - "IJG", - "LPPL-1.3a", - "SAX-PD", - "BitTorrent-1.0", - "OLDAP-2.0", - "Giftware", + "BSD-3-Clause-No-Nuclear-License", + "BSD-3-Clause-No-Nuclear-License-2014", + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-3-Clause-Open-MPI", + "BSD-4-Clause", + "BSD-4-Clause-Shortened", + "BSD-4-Clause-UC", + "BSD-4.3RENO", + "BSD-4.3TAHOE", + "BSD-Advertising-Acknowledgement", + "BSD-Attribution-HPND-disclaimer", + "BSD-Protection", + "BSD-Source-Code", + "BSL-1.0", + "BUSL-1.1", + "bzip2-1.0.5", + "bzip2-1.0.6", "C-UDA-1.0", - "LGPL-2.0+", - "Rdisc", - "GPL-2.0-with-classpath-exception", + "CAL-1.0", + "CAL-1.0-Combined-Work-Exception", + "Caldera", + "CATOSL-1.1", + "CC-BY-1.0", + "CC-BY-2.0", + "CC-BY-2.5", + "CC-BY-2.5-AU", + "CC-BY-3.0", + "CC-BY-3.0-AT", + "CC-BY-3.0-DE", + "CC-BY-3.0-IGO", + "CC-BY-3.0-NL", "CC-BY-3.0-US", - "CDDL-1.0", - "Xnet", - "CPL-1.0", - "LGPL-3.0-or-later", - "NASA-1.3", - "BUSL-1.1", - "etalab-2.0", - "MIT-open-group", - "OLDAP-1.4", - "GFDL-1.1-invariants-only", - "RPL-1.1", + "CC-BY-4.0", + "CC-BY-NC-1.0", + "CC-BY-NC-2.0", + "CC-BY-NC-2.5", + "CC-BY-NC-3.0", + "CC-BY-NC-3.0-DE", + "CC-BY-NC-4.0", + "CC-BY-NC-ND-1.0", + "CC-BY-NC-ND-2.0", "CC-BY-NC-ND-2.5", - "FSFULLR", - "Saxpath", - "NTP-0", - "SISSL-1.2", - "GPL-3.0-or-later", - "Apache-1.1", + "CC-BY-NC-ND-3.0", + "CC-BY-NC-ND-3.0-DE", + "CC-BY-NC-ND-3.0-IGO", + "CC-BY-NC-ND-4.0", + "CC-BY-NC-SA-1.0", + "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.0-DE", + "CC-BY-NC-SA-2.0-FR", + "CC-BY-NC-SA-2.0-UK", + "CC-BY-NC-SA-2.5", + "CC-BY-NC-SA-3.0", + "CC-BY-NC-SA-3.0-DE", + "CC-BY-NC-SA-3.0-IGO", + "CC-BY-NC-SA-4.0", + "CC-BY-ND-1.0", + "CC-BY-ND-2.0", + "CC-BY-ND-2.5", + "CC-BY-ND-3.0", + "CC-BY-ND-3.0-DE", + "CC-BY-ND-4.0", + "CC-BY-SA-1.0", + "CC-BY-SA-2.0", + "CC-BY-SA-2.0-UK", "CC-BY-SA-2.1-JP", - "AGPL-3.0-only", - "GPL-2.0-with-autoconf-exception", - "Artistic-2.0", - "App-s2p", - "Unicode-DFS-2015", - "diffmark", - "SNIA", "CC-BY-SA-2.5", - "Linux-man-pages-copyleft", - "HPND-sell-variant", - "ZPL-2.1", - "BSD-4-Clause-UC", - "LAL-1.2", - "AGPL-1.0-only", - "MIT-enna", + "CC-BY-SA-3.0", + "CC-BY-SA-3.0-AT", + "CC-BY-SA-3.0-DE", + "CC-BY-SA-3.0-IGO", + "CC-BY-SA-4.0", + "CC-PDDC", + "CC0-1.0", + "CDDL-1.0", + "CDDL-1.1", + "CDL-1.0", + "CDLA-Permissive-1.0", + "CDLA-Permissive-2.0", + "CDLA-Sharing-1.0", + "CECILL-1.0", + "CECILL-1.1", + "CECILL-2.0", + "CECILL-2.1", + "CECILL-B", + "CECILL-C", + "CERN-OHL-1.1", + "CERN-OHL-1.2", + "CERN-OHL-P-2.0", + "CERN-OHL-S-2.0", + "CERN-OHL-W-2.0", + "CFITSIO", + "checkmk", + "ClArtistic", + "Clips", + "CMU-Mach", + "CNRI-Jython", + "CNRI-Python", + "CNRI-Python-GPL-Compatible", + "COIL-1.0", + "Community-Spec-1.0", "Condor-1.1", - "Naumen", - "GFDL-1.3-no-invariants-or-later", - "RPL-1.5", - "PolyForm-Small-Business-1.0.0", - "EFL-1.0", - "MirOS", - "CC-BY-2.5-AU", - "Afmparse", - "MPL-2.0-no-copyleft-exception", - "LiLiQ-Rplus-1.1", - "AFL-1.2", - "OSL-1.0", - "GPL-1.0-only", - "APSL-1.0", - "OGL-Canada-2.0", + "copyleft-next-0.3.0", + "copyleft-next-0.3.1", + "Cornell-Lossless-JPEG", "CPAL-1.0", - "Latex2e", - "Zend-2.0", - "Unlicense", - "xpp", - "CC-BY-NC-1.0", - "GPL-3.0-with-autoconf-exception", - "CC-BY-NC-SA-3.0", - "TCP-wrappers", - "SCEA", - "SSH-short", - "CC-BY-3.0-NL", - "SchemeReport", - "CC-BY-3.0", - "MPL-2.0", - "Unicode-TOU", - "CC-BY-NC-ND-1.0", + "CPL-1.0", + "CPOL-1.02", + "Crossword", + "CrystalStacker", + "CUA-OPL-1.0", + "Cube", + "curl", + "D-FSL-1.0", + "diffmark", + "DL-DE-BY-2.0", + "DOC", + "Dotseqn", + "DRL-1.0", + "DSDP", + "dtoa", + "dvipdfm", + "ECL-1.0", + "ECL-2.0", + "eCos-2.0", + "EFL-1.0", + "EFL-2.0", + "eGenix", + "Elastic-2.0", "Entessa", - "BSD-3-Clause-No-Nuclear-License", - "SWL", - "GFDL-1.2-no-invariants-only", - "Parity-7.0.0", - "OLDAP-2.2.1", - "SGI-B-1.1", - "FTL", - "OLDAP-2.4", - "CC-BY-NC-4.0", - "bzip2-1.0.6", - "copyleft-next-0.3.0", - "MakeIndex", - "NRL", - "GFDL-1.3-invariants-or-later", - "CC-BY-NC-2.0", - "SugarCRM-1.1.3", - "AFL-2.1", - "GPL-2.0-only", - "GFDL-1.3-invariants-only", - "TORQUE-1.1", - "Ruby", - "X11", - "Borceux", - "Libpng", - "X11-distribute-modifications-variant", - "Frameworx-1.0", - "NCGL-UK-2.0", - "CECILL-2.1", - "CC-BY-3.0-AT", - "CNRI-Python", - "NCSA", - "gSOAP-1.3b", - "EUPL-1.1", - "AMDPLPA", - "Imlib2", - "CDDL-1.1", - "WTFPL", - "LPL-1.0", + "EPICS", "EPL-1.0", - "BSD-3-Clause-Attribution", - "OSL-3.0", - "RHeCos-1.1", - "PHP-3.0", - "BSD-Protection", - "CC-BY-NC-3.0-DE", - "APL-1.0", + "EPL-2.0", + "ErlPL-1.1", + "etalab-2.0", "EUDatagrid", - "GPL-1.0", - "SHL-0.5", - "CC-BY-SA-2.0", - "CC-BY-SA-3.0-AT", - "CC-BY-NC-SA-3.0-IGO", - "Adobe-2006", - "Newsletr", - "Nunit", - "Multics", - "OGL-UK-1.0", - "Vim", - "eCos-2.0", - "Zimbra-1.3", - "eGenix", - "IBM-pibs", - "BitTorrent-1.1", - "OFL-1.1-no-RFN", - "psfrag", - "CC-BY-ND-2.0", - "SHL-0.51", + "EUPL-1.0", + "EUPL-1.1", + "EUPL-1.2", + "Eurosym", + "Fair", + "FDK-AAC", + "Frameworx-1.0", "FreeBSD-DOC", - "Python-2.0", - "Mup", - "BSD-4-Clause-Shortened", - "CC-BY-NC-SA-4.0", - "HPND", - "OLDAP-2.6", - "MPL-1.1", + "FreeImage", + "FSFAP", + "FSFUL", + "FSFULLR", + "FSFULLRWD", + "FTL", + "GD", + "GFDL-1.1", + "GFDL-1.1-invariants-only", + "GFDL-1.1-invariants-or-later", + "GFDL-1.1-no-invariants-only", + "GFDL-1.1-no-invariants-or-later", + "GFDL-1.1-only", + "GFDL-1.1-or-later", + "GFDL-1.2", + "GFDL-1.2-invariants-only", + "GFDL-1.2-invariants-or-later", + "GFDL-1.2-no-invariants-only", + "GFDL-1.2-no-invariants-or-later", + "GFDL-1.2-only", + "GFDL-1.2-or-later", + "GFDL-1.3", + "GFDL-1.3-invariants-only", + "GFDL-1.3-invariants-or-later", + "GFDL-1.3-no-invariants-only", + "GFDL-1.3-no-invariants-or-later", + "GFDL-1.3-only", + "GFDL-1.3-or-later", + "Giftware", + "GL2PS", + "Glide", + "Glulxe", + "GLWTPL", + "gnuplot", + "GPL-1.0", + "GPL-1.0+", + "GPL-1.0-only", + "GPL-1.0-or-later", + "GPL-2.0", + "GPL-2.0+", + "GPL-2.0-only", + "GPL-2.0-or-later", + "GPL-2.0-with-autoconf-exception", + "GPL-2.0-with-bison-exception", + "GPL-2.0-with-classpath-exception", + "GPL-2.0-with-font-exception", "GPL-2.0-with-GCC-exception", + "GPL-3.0", + "GPL-3.0+", + "GPL-3.0-only", + "GPL-3.0-or-later", + "GPL-3.0-with-autoconf-exception", + "GPL-3.0-with-GCC-exception", + "Graphics-Gems", + "gSOAP-1.3b", "HaskellReport", - "ECL-1.0", + "Hippocratic-2.1", + "HP-1986", + "HPND", + "HPND-export-US", + "HPND-Markus-Kuhn", + "HPND-sell-variant", + "HPND-sell-variant-MIT-disclaimer", + "HTMLTIDY", + "IBM-pibs", + "ICU", + "IEC-Code-Components-EULA", + "IJG", + "IJG-short", + "ImageMagick", + "iMatix", + "Imlib2", + "Info-ZIP", + "Inner-Net-2.0", + "Intel", + "Intel-ACPI", + "Interbase-1.0", + "IPA", + "IPL-1.0", + "ISC", + "Jam", + "JasPer-2.0", + "JPL-image", + "JPNIC", + "JSON", + "Kazlib", + "Knuth-CTAN", + "LAL-1.2", + "LAL-1.3", + "Latex2e", + "Latex2e-translated-notice", + "Leptonica", + "LGPL-2.0", + "LGPL-2.0+", + "LGPL-2.0-only", + "LGPL-2.0-or-later", + "LGPL-2.1", + "LGPL-2.1+", + "LGPL-2.1-only", "LGPL-2.1-or-later", - "OFL-1.0", - "APSL-1.1", - "MITNFA", - "CECILL-2.0", - "Crossword", - "Aladdin", - "Baekmuk", - "XFree86-1.1", - "GPL-1.0-or-later", - "CERN-OHL-W-2.0", - "CC-BY-SA-1.0", - "NTP", - "PHP-3.01", - "OCLC-2.0", - "CC-BY-3.0-DE", - "CC-BY-NC-2.5", - "Zlib", - "CATOSL-1.1", + "LGPL-3.0", "LGPL-3.0+", - "CAL-1.0", - "NPL-1.0", - "SMLNJ", - "GPL-2.0+", - "OLDAP-2.5", - "JasPer-2.0", - "GPL-2.0-or-later", - "BSD-2-Clause-Patent", + "LGPL-3.0-only", + "LGPL-3.0-or-later", + "LGPLLR", + "Libpng", + "libpng-2.0", + "libselinux-1.0", + "libtiff", + "libutil-David-Nugent", + "LiLiQ-P-1.1", + "LiLiQ-R-1.1", + "LiLiQ-Rplus-1.1", + "Linux-man-pages-1-para", + "Linux-man-pages-copyleft", + "Linux-man-pages-copyleft-2-para", + "Linux-man-pages-copyleft-var", + "Linux-OpenIB", + "LOOP", + "LPL-1.0", + "LPL-1.02", + "LPPL-1.0", + "LPPL-1.1", + "LPPL-1.2", + "LPPL-1.3a", + "LPPL-1.3c", + "LZMA-SDK-9.11-to-9.20", + "LZMA-SDK-9.22", + "MakeIndex", + "Martin-Birgmeier", + "metamail", + "Minpack", + "MirOS", + "MIT", + "MIT-0", + "MIT-advertising", + "MIT-CMU", + "MIT-enna", + "MIT-feh", + "MIT-Festival", + "MIT-Modern-Variant", + "MIT-open-group", + "MIT-Wu", + "MITNFA", + "Motosoto", + "mpi-permissive", + "mpich2", + "MPL-1.0", + "MPL-1.1", + "MPL-2.0", + "MPL-2.0-no-copyleft-exception", + "mplus", + "MS-LPL", + "MS-PL", "MS-RL", - "CUA-OPL-1.0", - "IPA", + "MTLL", + "MulanPSL-1.0", + "MulanPSL-2.0", + "Multics", + "Mup", + "NAIST-2003", + "NASA-1.3", + "Naumen", + "NBPL-1.0", + "NCGL-UK-2.0", + "NCSA", + "Net-SNMP", + "NetCDF", + "Newsletr", + "NGPL", + "NICTA-1.0", + "NIST-PD", + "NIST-PD-fallback", + "NIST-Software", + "NLOD-1.0", + "NLOD-2.0", "NLPL", + "Nokia", + "NOSL", + "Noweb", + "NPL-1.0", + "NPL-1.1", + "NPOSL-3.0", + "NRL", + "NTP", + "NTP-0", + "Nunit", "O-UDA-1.0", - "MIT-Modern-Variant", - "OLDAP-1.2", - "BSD-2-Clause-FreeBSD", - "Info-ZIP", - "CC-BY-NC-SA-2.0-FR", - "0BSD", - "Unicode-DFS-2016", + "OCCT-PL", + "OCLC-2.0", + "ODbL-1.0", + "ODC-By-1.0", + "OFFIS", + "OFL-1.0", + "OFL-1.0-no-RFN", "OFL-1.0-RFN", - "Intel", - "AFL-2.0", - "GL2PS", - "TAPR-OHL-1.0", - "Apache-1.0", - "MTLL", - "Motosoto", + "OFL-1.1", + "OFL-1.1-no-RFN", + "OFL-1.1-RFN", + "OGC-1.0", + "OGDL-Taiwan-1.0", + "OGL-Canada-2.0", + "OGL-UK-1.0", + "OGL-UK-2.0", + "OGL-UK-3.0", + "OGTSL", + "OLDAP-1.1", + "OLDAP-1.2", + "OLDAP-1.3", + "OLDAP-1.4", + "OLDAP-2.0", + "OLDAP-2.0.1", + "OLDAP-2.1", + "OLDAP-2.2", + "OLDAP-2.2.1", + "OLDAP-2.2.2", + "OLDAP-2.3", + "OLDAP-2.4", + "OLDAP-2.5", + "OLDAP-2.6", + "OLDAP-2.7", + "OLDAP-2.8", + "OLFL-1.3", + "OML", + "OpenPBS-2.3", + "OpenSSL", + "OPL-1.0", + "OPL-UK-3.0", + "OPUBL-1.0", + "OSET-PL-2.1", + "OSL-1.0", + "OSL-1.1", + "OSL-2.0", + "OSL-2.1", + "OSL-3.0", + "Parity-6.0.0", + "Parity-7.0.0", + "PDDL-1.0", + "PHP-3.0", + "PHP-3.01", + "Plexus", + "PolyForm-Noncommercial-1.0.0", + "PolyForm-Small-Business-1.0.0", + "PostgreSQL", + "PSF-2.0", + "psfrag", + "psutils", + "Python-2.0", + "Python-2.0.1", + "Qhull", + "QPL-1.0", + "QPL-1.0-INRIA-2004", + "Rdisc", + "RHeCos-1.1", + "RPL-1.1", + "RPL-1.5", + "RPSL-1.0", "RSA-MD", - "Community-Spec-1.0", - "ODC-By-1.0", - "zlib-acknowledgement", - "DL-DE-BY-2.0", - "VSL-1.0", - "LiLiQ-R-1.1", - "OPL-1.0", - "GPL-3.0+", - "MulanPSL-2.0", - "APSL-1.2", - "OGDL-Taiwan-1.0", "RSCPL", - "OGC-1.0", - "EFL-2.0", - "CAL-1.0-Combined-Work-Exception", - "MS-PL", - "Plexus", + "Ruby", + "SAX-PD", + "Saxpath", + "SCEA", + "SchemeReport", + "Sendmail", "Sendmail-8.23", - "Cube", - "JSON", - "EUPL-1.2", - "Adobe-Glyph", - "FreeImage", - "Watcom-1.0", - "Jam", - "Hippocratic-2.1", - "OLDAP-2.0.1", - "CC-BY-NC-SA-2.0", - "Nokia", - "OCCT-PL", - "ErlPL-1.1", + "SGI-B-1.0", + "SGI-B-1.1", + "SGI-B-2.0", + "SGP4", + "SHL-0.5", + "SHL-0.51", + "SimPL-2.0", + "SISSL", + "SISSL-1.2", + "Sleepycat", + "SMLNJ", + "SMPPL", + "SNIA", + "snprintf", + "Spencer-86", + "Spencer-94", + "Spencer-99", + "SPL-1.0", + "SSH-OpenSSH", + "SSH-short", + "SSPL-1.0", + "StandardML-NJ", + "SugarCRM-1.1.3", + "SunPro", + "SWL", + "Symlinks", + "TAPR-OHL-1.0", + "TCL", + "TCP-wrappers", + "TermReadKey", + "TMate", + "TORQUE-1.1", "TOSL", - "OSL-2.1", - "ClArtistic", + "TPDL", + "TPL-1.0", + "TTWL", + "TU-Berlin-1.0", + "TU-Berlin-2.0", + "UCAR", + "UCL-1.0", + "Unicode-DFS-2015", + "Unicode-DFS-2016", + "Unicode-TOU", + "UnixCrypt", + "Unlicense", + "UPL-1.0", + "Vim", + "VOSTROM", + "VSL-1.0", + "W3C", + "W3C-19980720", + "W3C-20150513", + "w3m", + "Watcom-1.0", + "Widget-Workshop", + "Wsuipa", + "WTFPL", + "wxWindows", + "X11", + "X11-distribute-modifications-variant", + "Xdebug-1.03", + "Xerox", + "Xfig", + "XFree86-1.1", "xinetd", - "GPL-3.0-with-GCC-exception", - "ODbL-1.0", - "MIT", - "LGPL-2.1+", - "LGPL-2.1-only", - "CrystalStacker", - "ECL-2.0", - "LPPL-1.0", - "iMatix", - "CC-BY-NC-ND-3.0-IGO", - "BSD-Source-Code", - "Parity-6.0.0", - "TCL", - "Arphic-1999", - "CC-BY-SA-3.0", - "Caldera", - "AGPL-1.0", - "IPL-1.0", - "LAL-1.3", - "EPICS", - "NGPL", - "DRL-1.0", - "BSD-2-Clause-NetBSD", - "ZPL-1.1", - "GD", - "LPPL-1.2", - "Dotseqn", - "Spencer-99", - "OLDAP-2.3", + "xlock", + "Xnet", + "xpp", + "XSkat", + "YPL-1.0", "YPL-1.1", - "Fair", - "Qhull", - "GFDL-1.1-no-invariants-or-later", - "CECILL-C", - "MulanPSL-1.0", - "OLDAP-1.1", - "OLDAP-2.1", - "LPL-1.02", - "UPL-1.0", - "Abstyles", + "Zed", + "Zend-2.0", + "Zimbra-1.3", + "Zimbra-1.4", + "Zlib", + "zlib-acknowledgement", + "ZPL-1.1", "ZPL-2.0", - "MIT-0", - "LGPL-2.0-only", - "GFDL-1.3-no-invariants-only", - "AGPL-3.0", - "EPL-2.0", - "AFL-3.0", - "CDLA-Permissive-1.0", - "Artistic-1.0", - "CC-BY-NC-ND-4.0", - "HTMLTIDY", - "Glide", - "FSFAP", - "LGPLLR", - "OGL-UK-3.0", - "GFDL-1.2", - "SSH-OpenSSH", - "GFDL-1.1-only", - "MIT-feh", - "MPL-1.0", - "PostgreSQL", - "OLDAP-2.2.2", - "SMPPL", - "OFL-1.1", - "Leptonica", - "CERN-OHL-1.1", - "BSD-3-Clause-No-Nuclear-Warranty", - "CC-BY-ND-2.5", - "CC-BY-1.0", - "GFDL-1.2-only", - "OPUBL-1.0", - "libselinux-1.0", - "BSD-3-Clause", - "ANTLR-PD-fallback", - "copyleft-next-0.3.1", - "GPL-1.0+", - "wxWindows", - "LGPL-3.0", - "LGPL-2.1", - "StandardML-NJ", - "BSD-4-Clause", - "GPL-2.0-with-bison-exception", - "Apache-2.0", - "Artistic-1.0-cl8", - "GPL-2.0", - "Intel-ACPI", - "BSL-1.0", - "Artistic-1.0-Perl", - "BSD-2-Clause-Views", - "Interbase-1.0", - "NPOSL-3.0", - "FLTK-exception", - "Bootloader-exception", - "WxWindows-exception-3.1", - "Linux-syscall-note", - "Qt-LGPL-exception-1.1", - "LLVM-exception", - "PS-or-PDF-font-exception-20170817", - "GCC-exception-3.1", + "ZPL-2.1", + "389-exception", + "Asterisk-exception", + "Autoconf-exception-2.0", "Autoconf-exception-3.0", - "LGPL-3.0-linking-exception", - "GCC-exception-2.0", + "Autoconf-exception-generic", + "Autoconf-exception-macro", "Bison-exception-2.2", - "openvpn-openssl-exception", - "Libtool-exception", - "Autoconf-exception-2.0", + "Bootloader-exception", + "Classpath-exception-2.0", + "CLISP-exception-2.0", + "cryptsetup-OpenSSL-exception", + "DigiRule-FOSS-exception", + "eCos-exception-2.0", + "Fawkes-Runtime-exception", + "FLTK-exception", + "Font-exception-2.0", + "freertos-exception-2.0", + "GCC-exception-2.0", + "GCC-exception-3.1", + "GNAT-exception", + "gnu-javamail-exception", + "GPL-3.0-interface-exception", + "GPL-3.0-linking-exception", "GPL-3.0-linking-source-exception", "GPL-CC-1.0", - "OCaml-LGPL-linking-exception", - "Universal-FOSS-exception-1.0", + "GStreamer-exception-2005", + "GStreamer-exception-2008", "i2p-gpl-java-exception", - "CLISP-exception-2.0", + "KiCad-libraries-exception", + "LGPL-3.0-linking-exception", + "libpri-OpenH323-exception", + "Libtool-exception", + "Linux-syscall-note", + "LLGPL", + "LLVM-exception", + "LZMA-exception", + "mif-exception", + "Nokia-Qt-exception-1.1", + "OCaml-LGPL-linking-exception", "OCCT-exception-1.0", - "Qwt-exception-1.0", - "gnu-javamail-exception", - "u-boot-exception-2.0", - "freertos-exception-2.0", - "Qt-GPL-exception-1.0", "OpenJDK-assembly-exception-1.0", + "openvpn-openssl-exception", + "PS-or-PDF-font-exception-20170817", + "QPL-1.0-INRIA-2004-exception", + "Qt-GPL-exception-1.0", + "Qt-LGPL-exception-1.1", + "Qwt-exception-1.0", + "SHL-2.0", "SHL-2.1", - "mif-exception", - "Fawkes-Runtime-exception", + "SWI-exception", "Swift-exception", - "GPL-3.0-linking-exception", - "SHL-2.0", - "Classpath-exception-2.0", - "LZMA-exception", - "Font-exception-2.0", - "Nokia-Qt-exception-1.1", - "DigiRule-FOSS-exception", - "eCos-exception-2.0", - "389-exception" + "u-boot-exception-2.0", + "Universal-FOSS-exception-1.0", + "vsftpd-openssl-exception", + "WxWindows-exception-3.1", + "x11vnc-openssl-exception" ] -} \ No newline at end of file +} diff --git a/cyclonedx/schema/spdx.xsd b/cyclonedx/schema/_res/spdx.SNAPSHOT.xsd similarity index 86% rename from cyclonedx/schema/spdx.xsd rename to cyclonedx/schema/_res/spdx.SNAPSHOT.xsd index 4fb43642..5d086dbe 100644 --- a/cyclonedx/schema/spdx.xsd +++ b/cyclonedx/schema/_res/spdx.SNAPSHOT.xsd @@ -2,239 +2,234 @@ + version="1.0-3.21"> - - - Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic - - - + - SGI Free Software License B v2.0 + BSD Zero Clause License - + - LaTeX Project Public License v1.3c + Attribution Assurance License - + - NIST Public Domain Notice with license fallback + Abstyles License - + - libtiff License + AdaCore Doc License - + - XSkat License + Adobe Systems Incorporated Source Code License Agreement - + - Open Data Commons Public Domain Dedication & License 1.0 + Adobe Glyph List License - + - KiCad Libraries Exception + Amazon Digital Services License - + - Creative Commons Attribution Non Commercial Share Alike 1.0 Generic + Academic Free License v1.1 - + - GNU Free Documentation License v1.1 only - no invariants + Academic Free License v1.2 - + - Xerox License + Academic Free License v2.0 - + - LaTeX Project Public License v1.1 + Academic Free License v2.1 - + - VOSTROM Public License for Open Source + Academic Free License v3.0 - + - Upstream Compatibility License v1.0 + Afmparse License - + - Amazon Digital Services License + Affero General Public License v1.0 - + - Open Software License 2.0 + Affero General Public License v1.0 only - + - Attribution Assurance License + Affero General Public License v1.0 or later - + - Fraunhofer FDK AAC Codec Library + GNU Affero General Public License v3.0 - + - W3C Software Notice and Document License (2015-05-13) + GNU Affero General Public License v3.0 only - + - Academic Free License v1.1 + GNU Affero General Public License v3.0 or later - + - W3C Software Notice and License (2002-12-31) + Aladdin Free Public License - + - Sleepycat License + AMD's plpa_map.c License - + - CeCILL Free Software License Agreement v1.1 + Apple MIT License - + - mpich2 License + Academy of Motion Picture Arts and Sciences BSD - + - Sun Industry Standards Source License v1.1 + ANTLR Software Rights Notice - + - Norwegian Licence for Open Government Data (NLOD) 1.0 + ANTLR Software Rights Notice with license fallback - + - ANTLR Software Rights Notice + Apache License 1.0 - + - GNU General Public License v3.0 only + Apache License 1.1 - + - gnuplot License + Apache License 2.0 - + - Norwegian Licence for Open Government Data (NLOD) 2.0 + Adobe Postscript AFM License - + - BSD 3-Clause Open MPI variant + Adaptive Public License 1.0 - + - Licence Libre du Québec – Permissive version 1.1 + App::s2p License - + - BSD 3-Clause Clear License + Apple Public Source License 1.0 - + - FSF Unlimited License + Apple Public Source License 1.1 - + - Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales + Apple Public Source License 1.2 - + - CERN Open Hardware Licence Version 2 - Strongly Reciprocal + Apple Public Source License 2.0 - + - Spencer License 94 + Arphic Public License - + - CERN Open Hardware Licence v1.2 + Artistic License 1.0 - + - GNU Free Documentation License v1.1 or later + Artistic License 1.0 w/clause 8 - + - Affero General Public License v1.0 or later + Artistic License 1.0 (Perl) - + - Wsuipa License + Artistic License 2.0 - + - Apple MIT License + ASWF Digital Assets License version 1.0 - + - BSD 2-Clause "Simplified" License + ASWF Digital Assets License 1.1 - + - DSDP License + Baekmuk License - + - Creative Commons Attribution 2.5 Generic + Bahyph License - + - CMU License + Barr License @@ -242,284 +237,289 @@ Beerware License - + - Sendmail License + Bitstream Charter Font License - + - Technische Universitaet Berlin License 1.0 + Bitstream Vera Font License - + - CNRI Jython License + BitTorrent Open Source License v1.0 - + - mplus Font License + BitTorrent Open Source License v1.1 - + - Code Project Open License 1.02 + SQLite Blessing - + - BSD 3-Clause No Nuclear License 2014 + Blue Oak Model License 1.0.0 - + - ISC License + Boehm-Demers-Weiser GC License - + - Creative Commons Attribution Share Alike 4.0 International + Borceux license - + - Eurosym License + Brian Gladman 3-Clause License - + - GNU Lesser General Public License v3.0 only + BSD 1-Clause License - + - Open LDAP Public License v1.3 + BSD 2-Clause "Simplified" License - + - GNU Free Documentation License v1.1 or later - invariants + BSD 2-Clause FreeBSD License - + - Glulxe License + BSD 2-Clause NetBSD License - + - Simple Public License 2.0 + BSD-2-Clause Plus Patent License - + - Community Data License Agreement Permissive 2.0 + BSD 2-Clause with views sentence - + - GNU General Public License v2.0 w/Font exception + BSD 3-Clause "New" or "Revised" License - + - Open Government Licence v2.0 + BSD with attribution - + - Creative Commons Attribution Share Alike 3.0 Germany + BSD 3-Clause Clear License - + - Creative Commons Attribution No Derivatives 1.0 Generic + Lawrence Berkeley National Labs BSD variant license - + - GNU Free Documentation License v1.1 + BSD 3-Clause Modification - + - Creative Commons Attribution 4.0 International + BSD 3-Clause No Military License - + - OpenSSL License + BSD 3-Clause No Nuclear License - + - Technische Universitaet Berlin License 2.0 + BSD 3-Clause No Nuclear License 2014 - + - DOC License + BSD 3-Clause No Nuclear Warranty - + - GNU Free Documentation License v1.2 or later - no invariants + BSD 3-Clause Open MPI variant - + - Q Public License 1.0 + BSD 4-Clause "Original" or "Old" License - + - Open LDAP Public License v2.8 + BSD 4 Clause Shortened - + - Open Market License + BSD-4-Clause (University of California-Specific) - + - Open LDAP Public License v2.7 + BSD 4.3 RENO License - + - NIST Public Domain Notice + BSD 4.3 TAHOE License - + - Bitstream Vera Font License + BSD Advertising Acknowledgement License - + - GNU Free Documentation License v1.2 or later + BSD with Attribution and HPND disclaimer - + - SIL Open Font License 1.1 with Reserved Font Name + BSD Protection License - + - Bahyph License + BSD Source Code Attribution - + - Barr License + Boost Software License 1.0 - + - Copyfree Open Innovation License + Business Source License 1.1 - + - GNU Free Documentation License v1.3 + bzip2 and libbzip2 License v1.0.5 - + - CeCILL-B Free Software License Agreement + bzip2 and libbzip2 License v1.0.6 - + - Japan Network Information Center License + Computational Use of Data Agreement v1.0 - + - Zed License + Cryptographic Autonomy License 1.0 - + - ICU License + Cryptographic Autonomy License 1.0 (Combined Work Exception) - + - Creative Commons Attribution Non Commercial Share Alike 2.5 Generic + Caldera License - + - Creative Commons Attribution No Derivatives 3.0 Germany + Computer Associates Trusted Open Source License 1.1 - + - bzip2 and libbzip2 License v1.0.5 + Creative Commons Attribution 1.0 Generic - + - Sun Public License v1.0 + Creative Commons Attribution 2.0 Generic - + - Yahoo! Public License v1.0 + Creative Commons Attribution 2.5 Generic - + - OSET Public License version 2.1 + Creative Commons Attribution 2.5 Australia - + - Noweb License + Creative Commons Attribution 3.0 Unported - + - RealNetworks Public Source License v1.0 + Creative Commons Attribution 3.0 Austria - + - Lawrence Berkeley National Labs BSD variant license + Creative Commons Attribution 3.0 Germany - + - Community Data License Agreement Sharing 1.0 + Creative Commons Attribution 3.0 IGO - + - CeCILL Free Software License Agreement v1.0 + Creative Commons Attribution 3.0 Netherlands - + - Academy of Motion Picture Arts and Sciences BSD + Creative Commons Attribution 3.0 United States - + - Adobe Postscript AFM License + Creative Commons Attribution 4.0 International - + - Creative Commons Attribution No Derivatives 3.0 Unported + Creative Commons Attribution Non Commercial 1.0 Generic - + - Deutsche Freie Software Lizenz + Creative Commons Attribution Non Commercial 2.0 Generic + + + + + Creative Commons Attribution Non Commercial 2.5 Generic @@ -527,294 +527,679 @@ Creative Commons Attribution Non Commercial 3.0 Unported - + - PNG Reference Library version 2 + Creative Commons Attribution Non Commercial 3.0 Germany - + - PolyForm Noncommercial License 1.0.0 + Creative Commons Attribution Non Commercial 4.0 International - + - dvipdfm License + Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic - + - GNU Free Documentation License v1.3 or later + Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic - + - Open Group Test Suite License + Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic - + - Netscape Public License v1.1 + Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported - + - GNU General Public License v3.0 only + Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany - + - CERN Open Hardware Licence Version 2 - Permissive + Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO - + - Blue Oak Model License 1.0.0 + Creative Commons Attribution Non Commercial No Derivatives 4.0 International - + - GNU Affero General Public License v3.0 or later + Creative Commons Attribution Non Commercial Share Alike 1.0 Generic - + - SQLite Blessing + Creative Commons Attribution Non Commercial Share Alike 2.0 Generic - + - ImageMagick License + Creative Commons Attribution Non Commercial Share Alike 2.0 Germany - + - Apple Public Source License 2.0 + Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France - + - Enlightenment License (e16) + Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales - + - curl License + Creative Commons Attribution Non Commercial Share Alike 2.5 Generic - + - Creative Commons Zero v1.0 Universal + Creative Commons Attribution Non Commercial Share Alike 3.0 Unported - + - Zimbra Public License v1.4 + Creative Commons Attribution Non Commercial Share Alike 3.0 Germany - + - Server Side Public License, v 1 + Creative Commons Attribution Non Commercial Share Alike 3.0 IGO - + - psutils License + Creative Commons Attribution Non Commercial Share Alike 4.0 International - + - Creative Commons Attribution Share Alike 2.0 England and Wales + Creative Commons Attribution No Derivatives 1.0 Generic - + - Python Software Foundation License 2.0 + Creative Commons Attribution No Derivatives 2.0 Generic - + - Net-SNMP License + Creative Commons Attribution No Derivatives 2.5 Generic - + - Nara Institute of Science and Technology License (2003) + Creative Commons Attribution No Derivatives 3.0 Unported - + - GNU Free Documentation License v1.2 or later - invariants + Creative Commons Attribution No Derivatives 3.0 Germany - + - SGI Free Software License B v1.0 + Creative Commons Attribution No Derivatives 4.0 International - + - Net Boolean Public License v1 + Creative Commons Attribution Share Alike 1.0 Generic - + - GNU Free Documentation License v1.2 only - invariants + Creative Commons Attribution Share Alike 2.0 Generic - + - W3C Software Notice and License (1998-07-20) + Creative Commons Attribution Share Alike 2.0 England and Wales - + - SIL Open Font License 1.0 with no Reserved Font Name + Creative Commons Attribution Share Alike 2.1 Japan - + - NetCDF license + Creative Commons Attribution Share Alike 2.5 Generic - + - TMate Open Source License + Creative Commons Attribution Share Alike 3.0 Unported + + + + + Creative Commons Attribution Share Alike 3.0 Austria + + + + + Creative Commons Attribution Share Alike 3.0 Germany + + + + + Creative Commons Attribution-ShareAlike 3.0 IGO + + + + + Creative Commons Attribution Share Alike 4.0 International + + + + + Creative Commons Public Domain Dedication and Certification + + + + + Creative Commons Zero v1.0 Universal + + + + + Common Development and Distribution License 1.0 + + + + + Common Development and Distribution License 1.1 + + + + + Common Documentation License 1.0 + + + + + Community Data License Agreement Permissive 1.0 + + + + + Community Data License Agreement Permissive 2.0 + + + + + Community Data License Agreement Sharing 1.0 + + + + + CeCILL Free Software License Agreement v1.0 + + + + + CeCILL Free Software License Agreement v1.1 + + + + + CeCILL Free Software License Agreement v2.0 + + + + + CeCILL Free Software License Agreement v2.1 + + + + + CeCILL-B Free Software License Agreement + + + + + CeCILL-C Free Software License Agreement + + + + + CERN Open Hardware Licence v1.1 + + + + + CERN Open Hardware Licence v1.2 + + + + + CERN Open Hardware Licence Version 2 - Permissive + + + + + CERN Open Hardware Licence Version 2 - Strongly Reciprocal + + + + + CERN Open Hardware Licence Version 2 - Weakly Reciprocal + + + + + CFITSIO License + + + + + Checkmk License + + + + + Clarified Artistic License + + + + + Clips License + + + + + CMU Mach License + + + + + CNRI Jython License + + + + + CNRI Python License + + + + + CNRI Python Open Source GPL Compatible License Agreement + + + + + Copyfree Open Innovation License + + + + + Community Specification License 1.0 + + + + + Condor Public License v1.1 + + + + + copyleft-next 0.3.0 + + + + + copyleft-next 0.3.1 + + + + + Cornell Lossless JPEG License + + + + + Common Public Attribution License 1.0 + + + + + Common Public License 1.0 + + + + + Code Project Open License 1.02 + + + + + Crossword License + + + + + CrystalStacker License + + + + + CUA Office Public License v1.0 + + + + + Cube License + + + + + curl License + + + + + Deutsche Freie Software Lizenz + + + + + diffmark license + + + + + Data licence Germany – attribution – version 2.0 + + + + + DOC License + + + + + Dotseqn License + + + + + Detection Rule License 1.0 + + + + + DSDP License + + + + + David M. Gay dtoa License + + + + + dvipdfm License + + + + + Educational Community License v1.0 + + + + + Educational Community License v2.0 + + + + + eCos license version 2.0 + + + + + Eiffel Forum License v1.0 + + + + + Eiffel Forum License v2.0 + + + + + eGenix.com Public License 1.1.0 + + + + + Elastic License 2.0 + + + + + Entessa Public License v1.0 + + + + + EPICS Open License + + + + + Eclipse Public License 1.0 - + - Netizen Open Source License + Eclipse Public License 2.0 - + - CNRI Python Open Source GPL Compatible License Agreement + Erlang Public License v1.1 - + - BSD 1-Clause License + Etalab Open License 2.0 - + - Creative Commons Attribution Non Commercial Share Alike 3.0 Germany + EU DataGrid Software License - + - BSD 3-Clause Modification + European Union Public License 1.0 - + - Good Luck With That Public License + European Union Public License 1.1 - + - GNU Free Documentation License v1.3 only + European Union Public License 1.2 - + - Open LDAP Public License v2.2 + Eurosym License - + - Creative Commons Attribution No Derivatives 4.0 International + Fair License - + - Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany + Fraunhofer FDK AAC Codec Library - + - European Union Public License 1.0 + Frameworx Open License 1.0 - + - Linux Kernel Variant of OpenIB.org license + FreeBSD Documentation License - + - GNU Library General Public License v2 or later + FreeImage Public License v1.0 - + - Open Software License 1.1 + FSF All Permissive License - + - Spencer License 86 + FSF Unlimited License - + - GNU Library General Public License v2 only + FSF Unlimited License (with License Retention) - + - Creative Commons Public Domain Dedication and Certification + FSF Unlimited License (With License Retention and Warranty Disclaimer) - + - Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported + Freetype Project License - + - Common Documentation License 1.0 + GD License - + - Elastic License 2.0 + GNU Free Documentation License v1.1 - + - Creative Commons Attribution 2.0 Generic + GNU Free Documentation License v1.1 only - invariants - + - BSD 3-Clause No Military License + GNU Free Documentation License v1.1 or later - invariants - + - Independent JPEG Group License + GNU Free Documentation License v1.1 only - no invariants - + - LaTeX Project Public License v1.3a + GNU Free Documentation License v1.1 or later - no invariants - + - Sax Public Domain Notice + GNU Free Documentation License v1.1 only - + - BitTorrent Open Source License v1.0 + GNU Free Documentation License v1.1 or later - + - Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B) + GNU Free Documentation License v1.2 + + + + + GNU Free Documentation License v1.2 only - invariants + + + + + GNU Free Documentation License v1.2 or later - invariants + + + + + GNU Free Documentation License v1.2 only - no invariants + + + + + GNU Free Documentation License v1.2 or later - no invariants + + + + + GNU Free Documentation License v1.2 only + + + + + GNU Free Documentation License v1.2 or later + + + + + GNU Free Documentation License v1.3 + + + + + GNU Free Documentation License v1.3 only - invariants + + + + + GNU Free Documentation License v1.3 or later - invariants + + + + + GNU Free Documentation License v1.3 only - no invariants + + + + + GNU Free Documentation License v1.3 or later - no invariants + + + + + GNU Free Documentation License v1.3 only + + + + + GNU Free Documentation License v1.3 or later @@ -822,284 +1207,304 @@ Giftware License - + - Computational Use of Data Agreement v1.0 + GL2PS License - + - GNU Library General Public License v2 or later + 3dfx Glide License - + - Rdisc License + Glulxe License - + - GNU General Public License v2.0 w/Classpath exception + Good Luck With That Public License - + - Creative Commons Attribution 3.0 United States + gnuplot License - + - Common Development and Distribution License 1.0 + GNU General Public License v1.0 only - + - X.Net License + GNU General Public License v1.0 or later - + - Common Public License 1.0 + GNU General Public License v1.0 only - + - GNU Lesser General Public License v3.0 or later + GNU General Public License v1.0 or later - + - NASA Open Source Agreement 1.3 + GNU General Public License v2.0 only - + - Business Source License 1.1 + GNU General Public License v2.0 or later - + - Etalab Open License 2.0 + GNU General Public License v2.0 only - + - MIT Open Group variant + GNU General Public License v2.0 or later - + - Open LDAP Public License v1.4 + GNU General Public License v2.0 w/Autoconf exception - + - GNU Free Documentation License v1.1 only - invariants + GNU General Public License v2.0 w/Bison exception - + + + GNU General Public License v2.0 w/Classpath exception + + + + + GNU General Public License v2.0 w/Font exception + + + + + GNU General Public License v2.0 w/GCC Runtime Library exception + + + + + GNU General Public License v3.0 only + + + - Reciprocal Public License 1.1 + GNU General Public License v3.0 or later - + - Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic + GNU General Public License v3.0 only - + - FSF Unlimited License (with License Retention) + GNU General Public License v3.0 or later - + - Saxpath License + GNU General Public License v3.0 w/Autoconf exception - + - NTP No Attribution + GNU General Public License v3.0 w/GCC Runtime Library exception - + - Sun Industry Standards Source License v1.2 + Graphics Gems License - + - GNU General Public License v3.0 or later + gSOAP Public License v1.3b - + - Apache License 1.1 + Haskell Language Report License - + - Creative Commons Attribution Share Alike 2.1 Japan + Hippocratic License 2.1 - + - GNU Affero General Public License v3.0 only + Hewlett-Packard 1986 License - + - GNU General Public License v2.0 w/Autoconf exception + Historical Permission Notice and Disclaimer - + - Artistic License 2.0 + HPND with US Government export control warning - + - App::s2p License + Historical Permission Notice and Disclaimer - Markus Kuhn variant - + - Unicode License Agreement - Data Files and Software (2015) + Historical Permission Notice and Disclaimer - sell variant - + - diffmark license + HPND sell variant with MIT disclaimer - + - SNIA Public License 1.1 + HTML Tidy License - + - Creative Commons Attribution Share Alike 2.5 Generic + IBM PowerPC Initialization and Boot Software - + - Linux man-pages Copyleft + ICU License - + - Historical Permission Notice and Disclaimer - sell variant + IEC Code Components End-user licence agreement - + - Zope Public License 2.1 + Independent JPEG Group License - + - BSD-4-Clause (University of California-Specific) + Independent JPEG Group License - short - + - Licence Art Libre 1.2 + ImageMagick License - + - Affero General Public License v1.0 only + iMatix Standard Function Library Agreement - + - enna License + Imlib2 License - + - Condor Public License v1.1 + Info-ZIP License - + - Naumen Public License + Inner Net License v2.0 - + - GNU Free Documentation License v1.3 or later - no invariants + Intel Open Source License - + - Reciprocal Public License 1.5 + Intel ACPI Software License Agreement - + - PolyForm Small Business License 1.0.0 + Interbase Public License v1.0 - + - Eiffel Forum License v1.0 + IPA Font License - + - The MirOS Licence + IBM Public License v1.0 - + - Creative Commons Attribution 2.5 Australia + ISC License - + - Afmparse License + Jam License - + - Mozilla Public License 2.0 (no copyleft exception) + JasPer License - + - Licence Libre du Québec – Réciprocité forte version 1.1 + JPL Image Use Policy - + - Academic Free License v1.2 + Japan Network Information Center License - + - Open Software License 1.0 + JSON License - + - GNU General Public License v1.0 only + Kazlib License - + - Apple Public Source License 1.0 + Knuth CTAN License - + - Open Government Licence - Canada + Licence Art Libre 1.2 - + - Common Public Attribution License 1.0 + Licence Art Libre 1.3 @@ -1107,1515 +1512,1520 @@ Latex2e License - + - Zend License v2.0 + Latex2e with translated notice permission - + - The Unlicense + Leptonica License - + - XPP License + GNU Library General Public License v2 only - + - Creative Commons Attribution Non Commercial 1.0 Generic + GNU Library General Public License v2 or later - + - GNU General Public License v3.0 w/Autoconf exception + GNU Library General Public License v2 only - + - Creative Commons Attribution Non Commercial Share Alike 3.0 Unported + GNU Library General Public License v2 or later - + - TCP Wrappers License + GNU Lesser General Public License v2.1 only - + - SCEA Shared Source License + GNU Lesser General Public License v2.1 or later - + - SSH short notice + GNU Lesser General Public License v2.1 only - + - Creative Commons Attribution 3.0 Netherlands + GNU Lesser General Public License v2.1 or later - + - Scheme Language Report License + GNU Lesser General Public License v3.0 only - + - Creative Commons Attribution 3.0 Unported + GNU Lesser General Public License v3.0 or later - + - Mozilla Public License 2.0 + GNU Lesser General Public License v3.0 only - + - Unicode Terms of Use + GNU Lesser General Public License v3.0 or later - + - Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic + Lesser General Public License For Linguistic Resources - + - Entessa Public License v1.0 + libpng License - + - BSD 3-Clause No Nuclear License + PNG Reference Library version 2 - + - Scheme Widget Library (SWL) Software License Agreement + libselinux public domain notice - + - GNU Free Documentation License v1.2 only - no invariants + libtiff License - + - The Parity Public License 7.0.0 + libutil David Nugent License - + - Open LDAP Public License v2.2.1 + Licence Libre du Québec – Permissive version 1.1 - + - SGI Free Software License B v1.1 + Licence Libre du Québec – Réciprocité version 1.1 - + - Freetype Project License + Licence Libre du Québec – Réciprocité forte version 1.1 - + - Open LDAP Public License v2.4 + Linux man-pages - 1 paragraph - + - Creative Commons Attribution Non Commercial 4.0 International + Linux man-pages Copyleft - + - bzip2 and libbzip2 License v1.0.6 + Linux man-pages Copyleft - 2 paragraphs - + - copyleft-next 0.3.0 + Linux man-pages Copyleft Variant - + - MakeIndex License + Linux Kernel Variant of OpenIB.org license - + - NRL License + Common Lisp LOOP License - + - GNU Free Documentation License v1.3 or later - invariants + Lucent Public License Version 1.0 - + + + Lucent Public License v1.02 + + + - Creative Commons Attribution Non Commercial 2.0 Generic + LaTeX Project Public License v1.0 - + - SugarCRM Public License v1.1.3 + LaTeX Project Public License v1.1 - + - Academic Free License v2.1 + LaTeX Project Public License v1.2 - + - GNU General Public License v2.0 only + LaTeX Project Public License v1.3a - + - GNU Free Documentation License v1.3 only - invariants + LaTeX Project Public License v1.3c - + - TORQUE v2.5+ Software License v1.1 + LZMA SDK License (versions 9.11 to 9.20) - + - Ruby License + LZMA SDK License (versions 9.22 and beyond) - + - X11 License + MakeIndex License - + - Borceux license + Martin Birgmeier License - + - libpng License + metamail License - + - X11 License Distribution Modification Variant + Minpack License - + - Frameworx Open License 1.0 + The MirOS Licence - + - Non-Commercial Government Licence + MIT License - + - CeCILL Free Software License Agreement v2.1 + MIT No Attribution - + - Creative Commons Attribution 3.0 Austria + Enlightenment License (e16) - + - CNRI Python License + CMU License - + - University of Illinois/NCSA Open Source License + enna License - + - gSOAP Public License v1.3b + feh License - + - European Union Public License 1.1 + MIT Festival Variant - + - AMD's plpa_map.c License + MIT License Modern Variant - + - Imlib2 License + MIT Open Group variant - + - Common Development and Distribution License 1.1 + MIT Tom Wu Variant - + - Do What The F*ck You Want To Public License + MIT +no-false-attribs license - + - Lucent Public License Version 1.0 + Motosoto License - + - Eclipse Public License 1.0 + mpi Permissive License - + - BSD with attribution + mpich2 License - + - Open Software License 3.0 + Mozilla Public License 1.0 - + - Red Hat eCos Public License v1.1 + Mozilla Public License 1.1 - + - PHP License v3.0 + Mozilla Public License 2.0 - + - BSD Protection License + Mozilla Public License 2.0 (no copyleft exception) - + - Creative Commons Attribution Non Commercial 3.0 Germany + mplus Font License - + - Adaptive Public License 1.0 + Microsoft Limited Public License - + - EU DataGrid Software License + Microsoft Public License - + - GNU General Public License v1.0 only + Microsoft Reciprocal License - + - Solderpad Hardware License v0.5 + Matrix Template Library License - + - Creative Commons Attribution Share Alike 2.0 Generic + Mulan Permissive Software License, Version 1 - + - Creative Commons Attribution Share Alike 3.0 Austria + Mulan Permissive Software License, Version 2 - + - Creative Commons Attribution Non Commercial Share Alike 3.0 IGO + Multics License - + - Adobe Systems Incorporated Source Code License Agreement + Mup License - + - Newsletr License + Nara Institute of Science and Technology License (2003) - + - Nunit License + NASA Open Source Agreement 1.3 - + - Multics License + Naumen Public License - + - Open Government Licence v1.0 + Net Boolean Public License v1 - + - Vim License + Non-Commercial Government Licence - + - eCos license version 2.0 + University of Illinois/NCSA Open Source License - + - Zimbra Public License v1.3 + Net-SNMP License - + - eGenix.com Public License 1.1.0 + NetCDF license - + - IBM PowerPC Initialization and Boot Software + Newsletr License - + - BitTorrent Open Source License v1.1 + Nethack General Public License - + - SIL Open Font License 1.1 with no Reserved Font Name + NICTA Public Software License, Version 1.0 - + - psfrag License + NIST Public Domain Notice - + - Creative Commons Attribution No Derivatives 2.0 Generic + NIST Public Domain Notice with license fallback - + - Solderpad Hardware License, Version 0.51 + NIST Software License - + - FreeBSD Documentation License + Norwegian Licence for Open Government Data (NLOD) 1.0 - + - Python License 2.0 + Norwegian Licence for Open Government Data (NLOD) 2.0 - + - Mup License + No Limit Public License - + - BSD 4 Clause Shortened + Nokia Open Source License - + - Creative Commons Attribution Non Commercial Share Alike 4.0 International + Netizen Open Source License - + - Historical Permission Notice and Disclaimer + Noweb License - + - Open LDAP Public License v2.6 + Netscape Public License v1.0 - + - Mozilla Public License 1.1 + Netscape Public License v1.1 - + - GNU General Public License v2.0 w/GCC Runtime Library exception + Non-Profit Open Software License 3.0 - + - Haskell Language Report License + NRL License - + - Educational Community License v1.0 + NTP License - + - GNU Lesser General Public License v2.1 or later + NTP No Attribution - + - SIL Open Font License 1.0 + Nunit License - + - Apple Public Source License 1.1 + Open Use of Data Agreement v1.0 - + - MIT +no-false-attribs license + Open CASCADE Technology Public License - + - CeCILL Free Software License Agreement v2.0 + OCLC Research Public License 2.0 - + - Crossword License + Open Data Commons Open Database License v1.0 - + - Aladdin Free Public License + Open Data Commons Attribution License v1.0 - + - Baekmuk License + OFFIS License - + - XFree86 License 1.1 + SIL Open Font License 1.0 - + - GNU General Public License v1.0 or later + SIL Open Font License 1.0 with no Reserved Font Name - + - CERN Open Hardware Licence Version 2 - Weakly Reciprocal + SIL Open Font License 1.0 with Reserved Font Name - + - Creative Commons Attribution Share Alike 1.0 Generic + SIL Open Font License 1.1 - + - NTP License + SIL Open Font License 1.1 with no Reserved Font Name - + - PHP License v3.01 + SIL Open Font License 1.1 with Reserved Font Name - + - OCLC Research Public License 2.0 + OGC Software License, Version 1.0 - + - Creative Commons Attribution 3.0 Germany + Taiwan Open Government Data License, version 1.0 - + - Creative Commons Attribution Non Commercial 2.5 Generic + Open Government Licence - Canada - + - zlib License + Open Government Licence v1.0 - + - Computer Associates Trusted Open Source License 1.1 + Open Government Licence v2.0 - + - GNU Lesser General Public License v3.0 or later + Open Government Licence v3.0 - + - Cryptographic Autonomy License 1.0 + Open Group Test Suite License - + - Netscape Public License v1.0 + Open LDAP Public License v1.1 - + - Standard ML of New Jersey License + Open LDAP Public License v1.2 - + - GNU General Public License v2.0 or later + Open LDAP Public License v1.3 - + - Open LDAP Public License v2.5 + Open LDAP Public License v1.4 - + - JasPer License + Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B) - + - GNU General Public License v2.0 or later + Open LDAP Public License v2.0.1 - + - BSD-2-Clause Plus Patent License + Open LDAP Public License v2.1 - + - Microsoft Reciprocal License + Open LDAP Public License v2.2 - + - CUA Office Public License v1.0 + Open LDAP Public License v2.2.1 - + - IPA Font License + Open LDAP Public License 2.2.2 - + - No Limit Public License + Open LDAP Public License v2.3 - + - Open Use of Data Agreement v1.0 + Open LDAP Public License v2.4 - + - MIT License Modern Variant + Open LDAP Public License v2.5 - + - Open LDAP Public License v1.2 + Open LDAP Public License v2.6 - + - BSD 2-Clause FreeBSD License + Open LDAP Public License v2.7 - + - Info-ZIP License + Open LDAP Public License v2.8 - + - Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France + Open Logistics Foundation License Version 1.3 - + - BSD Zero Clause License + Open Market License - + - Unicode License Agreement - Data Files and Software (2016) + OpenPBS v2.3 Software License - + - SIL Open Font License 1.0 with Reserved Font Name + OpenSSL License - + - Intel Open Source License + Open Public License v1.0 - + - Academic Free License v2.0 + United Kingdom Open Parliament Licence v3.0 - + - GL2PS License + Open Publication License v1.0 - + - TAPR Open Hardware License v1.0 + OSET Public License version 2.1 - + - Apache License 1.0 + Open Software License 1.0 - + - Matrix Template Library License + Open Software License 1.1 - + - Motosoto License + Open Software License 2.0 - + - RSA Message-Digest License + Open Software License 2.1 - + - Community Specification License 1.0 + Open Software License 3.0 - + - Open Data Commons Attribution License v1.0 + The Parity Public License 6.0.0 - + - zlib/libpng License with Acknowledgement + The Parity Public License 7.0.0 - + - Data licence Germany – attribution – version 2.0 + Open Data Commons Public Domain Dedication & License 1.0 - + - Vovida Software License v1.0 + PHP License v3.0 - + - Licence Libre du Québec – Réciprocité version 1.1 + PHP License v3.01 - + - Open Public License v1.0 + Plexus Classworlds License - + - GNU General Public License v3.0 or later + PolyForm Noncommercial License 1.0.0 - + - Mulan Permissive Software License, Version 2 + PolyForm Small Business License 1.0.0 - + - Apple Public Source License 1.2 + PostgreSQL License - + - Taiwan Open Government Data License, version 1.0 + Python Software Foundation License 2.0 - + - Ricoh Source Code Public License + psfrag License - + - OGC Software License, Version 1.0 + psutils License - + - Eiffel Forum License v2.0 + Python License 2.0 - + - Cryptographic Autonomy License 1.0 (Combined Work Exception) + Python License 2.0.1 - + - Microsoft Public License + Qhull License - + - Plexus Classworlds License + Q Public License 1.0 - + - Sendmail License 8.23 + Q Public License 1.0 - INRIA 2004 variant - + - Cube License + Rdisc License - + - JSON License + Red Hat eCos Public License v1.1 - + - European Union Public License 1.2 + Reciprocal Public License 1.1 - + - Adobe Glyph List License + Reciprocal Public License 1.5 - + - FreeImage Public License v1.0 + RealNetworks Public Source License v1.0 - + - Sybase Open Watcom Public License 1.0 + RSA Message-Digest License - + - Jam License + Ricoh Source Code Public License - + - Hippocratic License 2.1 + Ruby License - + - Open LDAP Public License v2.0.1 + Sax Public Domain Notice - + - Creative Commons Attribution Non Commercial Share Alike 2.0 Generic + Saxpath License - + - Nokia Open Source License + SCEA Shared Source License - + - Open CASCADE Technology Public License + Scheme Language Report License - + - Erlang Public License v1.1 + Sendmail License - + - Trusster Open Source License + Sendmail License 8.23 - + - Open Software License 2.1 + SGI Free Software License B v1.0 - + - Clarified Artistic License + SGI Free Software License B v1.1 - + - xinetd License + SGI Free Software License B v2.0 - + - GNU General Public License v3.0 w/GCC Runtime Library exception + SGP4 Permission Notice - + - Open Data Commons Open Database License v1.0 + Solderpad Hardware License v0.5 - + - MIT License + Solderpad Hardware License, Version 0.51 - + - GNU Library General Public License v2.1 or later + Simple Public License 2.0 - + - GNU Lesser General Public License v2.1 only + Sun Industry Standards Source License v1.1 - + - CrystalStacker License + Sun Industry Standards Source License v1.2 - + - Educational Community License v2.0 + Sleepycat License - + - LaTeX Project Public License v1.0 + Standard ML of New Jersey License - + - iMatix Standard Function Library Agreement + Secure Messaging Protocol Public License - + - Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO + SNIA Public License 1.1 - + - BSD Source Code Attribution + snprintf License - + - The Parity Public License 6.0.0 + Spencer License 86 - + - TCL/TK License + Spencer License 94 - + - Arphic Public License + Spencer License 99 - + - Creative Commons Attribution Share Alike 3.0 Unported + Sun Public License v1.0 - + - Caldera License + SSH OpenSSH license - + - Affero General Public License v1.0 + SSH short notice - + - IBM Public License v1.0 + Server Side Public License, v 1 - + - Licence Art Libre 1.3 + Standard ML of New Jersey License - + - EPICS Open License + SugarCRM Public License v1.1.3 - + - Nethack General Public License + SunPro License - + - Detection Rule License 1.0 + Scheme Widget Library (SWL) Software License Agreement - + - BSD 2-Clause NetBSD License + Symlinks License - + - Zope Public License 1.1 + TAPR Open Hardware License v1.0 - + - GD License + TCL/TK License - + - LaTeX Project Public License v1.2 + TCP Wrappers License - + - Dotseqn License + TermReadKey License - + - Spencer License 99 + TMate Open Source License - + - Open LDAP Public License v2.3 + TORQUE v2.5+ Software License v1.1 - + - Yahoo! Public License v1.1 + Trusster Open Source License - + - Fair License + Time::ParseDate License - + - Qhull License + THOR Public License 1.0 - + - GNU Free Documentation License v1.1 or later - no invariants + Text-Tabs+Wrap License - + - CeCILL-C Free Software License Agreement + Technische Universitaet Berlin License 1.0 - + - Mulan Permissive Software License, Version 1 + Technische Universitaet Berlin License 2.0 - + - Open LDAP Public License v1.1 + UCAR License - + - Open LDAP Public License v2.1 + Upstream Compatibility License v1.0 - + - Lucent Public License v1.02 + Unicode License Agreement - Data Files and Software (2015) - + - Universal Permissive License v1.0 + Unicode License Agreement - Data Files and Software (2016) - + - Abstyles License + Unicode Terms of Use - + - Zope Public License 2.0 + UnixCrypt License - + - MIT No Attribution + The Unlicense - + - GNU Library General Public License v2 only + Universal Permissive License v1.0 - + - GNU Free Documentation License v1.3 only - no invariants + Vim License - + - GNU Affero General Public License v3.0 + VOSTROM Public License for Open Source - + - Eclipse Public License 2.0 + Vovida Software License v1.0 - + - Academic Free License v3.0 + W3C Software Notice and License (2002-12-31) - + - Community Data License Agreement Permissive 1.0 + W3C Software Notice and License (1998-07-20) - + - Artistic License 1.0 + W3C Software Notice and Document License (2015-05-13) - + - Creative Commons Attribution Non Commercial No Derivatives 4.0 International + w3m License - + - HTML Tidy License + Sybase Open Watcom Public License 1.0 - + - 3dfx Glide License + Widget Workshop License - + - FSF All Permissive License + Wsuipa License - + - Lesser General Public License For Linguistic Resources + Do What The F*ck You Want To Public License - + - Open Government Licence v3.0 + wxWindows Library License - + - GNU Free Documentation License v1.2 + X11 License - + - SSH OpenSSH license + X11 License Distribution Modification Variant - + - GNU Free Documentation License v1.1 only + Xdebug License v 1.03 - + - feh License + Xerox License - + - Mozilla Public License 1.0 + Xfig License - + - PostgreSQL License + XFree86 License 1.1 - + - Open LDAP Public License 2.2.2 + xinetd License - + - Secure Messaging Protocol Public License + xlock License - + - SIL Open Font License 1.1 + X.Net License - + - Leptonica License + XPP License - + - CERN Open Hardware Licence v1.1 + XSkat License - + - BSD 3-Clause No Nuclear Warranty + Yahoo! Public License v1.0 - + - Creative Commons Attribution No Derivatives 2.5 Generic + Yahoo! Public License v1.1 - + - Creative Commons Attribution 1.0 Generic + Zed License - + - GNU Free Documentation License v1.2 only + Zend License v2.0 - + - Open Publication License v1.0 + Zimbra Public License v1.3 - + - libselinux public domain notice + Zimbra Public License v1.4 - + - BSD 3-Clause "New" or "Revised" License + zlib License - + - ANTLR Software Rights Notice with license fallback + zlib/libpng License with Acknowledgement - + - copyleft-next 0.3.1 + Zope Public License 1.1 - + - GNU General Public License v1.0 or later + Zope Public License 2.0 - + - wxWindows Library License + Zope Public License 2.1 - + + - GNU Lesser General Public License v3.0 only + 389 Directory Server Exception - + - GNU Lesser General Public License v2.1 only + Asterisk exception - + - Standard ML of New Jersey License + Autoconf exception 2.0 - + - BSD 4-Clause "Original" or "Old" License + Autoconf exception 3.0 - + - GNU General Public License v2.0 w/Bison exception + Autoconf generic exception - + - Apache License 2.0 + Autoconf macro exception - + - Artistic License 1.0 w/clause 8 + Bison exception 2.2 - + - GNU General Public License v2.0 only + Bootloader Distribution Exception - + - Intel ACPI Software License Agreement + Classpath exception 2.0 - + - Boost Software License 1.0 + CLISP exception 2.0 - + - Artistic License 1.0 (Perl) + cryptsetup OpenSSL exception - + - BSD 2-Clause with views sentence + DigiRule FOSS License Exception - + - Interbase Public License v1.0 + eCos exception 2.0 - + - Non-Profit Open Software License 3.0 + Fawkes Runtime Exception - FLTK exception - + - Bootloader Distribution Exception + Font exception 2.0 - + - WxWindows Library Exception 3.1 + FreeRTOS Exception 2.0 - + - Linux Syscall Note + GCC Runtime Library exception 2.0 - + - Qt LGPL exception 1.1 + GCC Runtime Library exception 3.1 - + - LLVM Exception + GNAT exception - + - PS/PDF font exception (2017-08-17) + GNU JavaMail exception - + - GCC Runtime Library exception 3.1 + GPL-3.0 Interface Exception - + - Autoconf exception 3.0 + GPL-3.0 Linking Exception - + - LGPL-3.0 Linking Exception + GPL-3.0 Linking Exception (with Corresponding Source) - + - GCC Runtime Library exception 2.0 + GPL Cooperation Commitment 1.0 - + - Bison exception 2.2 + GStreamer Exception (2005) - + - OpenVPN OpenSSL Exception + GStreamer Exception (2008) - + - Libtool Exception + i2p GPL+Java Exception - + - Autoconf exception 2.0 + KiCad Libraries Exception - + - GPL-3.0 Linking Exception (with Corresponding Source) + LGPL-3.0 Linking Exception - + - GPL Cooperation Commitment 1.0 + libpri OpenH323 exception - + - OCaml LGPL Linking Exception + Libtool Exception - + - Universal FOSS Exception, Version 1.0 + Linux Syscall Note - + - i2p GPL+Java Exception + LLGPL Preamble - + - CLISP exception 2.0 + LLVM Exception - + - Open CASCADE Exception 1.0 + LZMA exception - + - Qwt exception 1.0 + Macros and Inline Functions Exception - + - GNU JavaMail exception + Nokia Qt LGPL exception 1.1 - + - U-Boot exception 2.0 + OCaml LGPL Linking Exception - + - FreeRTOS Exception 2.0 + Open CASCADE Exception 1.0 - + - Qt GPL exception 1.0 + OpenJDK Assembly exception 1.0 - + - OpenJDK Assembly exception 1.0 + OpenVPN OpenSSL Exception - + - Solderpad Hardware License v2.1 + PS/PDF font exception (2017-08-17) - + - Macros and Inline Functions Exception + INRIA QPL 1.0 2004 variant exception - + - Fawkes Runtime Exception + Qt GPL exception 1.0 - + - Swift Exception + Qt LGPL exception 1.1 - + - GPL-3.0 Linking Exception + Qwt exception 1.0 @@ -2623,39 +3033,44 @@ Solderpad Hardware License v2.0 - + - Classpath exception 2.0 + Solderpad Hardware License v2.1 - + - LZMA exception + SWI exception - + - Font exception 2.0 + Swift Exception - + - Nokia Qt LGPL exception 1.1 + U-Boot exception 2.0 - + - DigiRule FOSS License Exception + Universal FOSS Exception, Version 1.0 - + - eCos exception 2.0 + vsftpd OpenSSL exception - + - 389 Directory Server Exception + WxWindows Library Exception 3.1 + + + + + x11vnc OpenSSL Exception diff --git a/cyclonedx/schema/bom-1.2-strict.schema.json b/cyclonedx/schema/bom-1.2-strict.schema.json deleted file mode 100644 index 30dad527..00000000 --- a/cyclonedx/schema/bom-1.2-strict.schema.json +++ /dev/null @@ -1,1020 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://cyclonedx.org/schema/bom-1.2a.schema.json", - "type": "object", - "title": "CycloneDX Software Bill-of-Material Specification", - "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", - "required": [ - "bomFormat", - "specVersion", - "version" - ], - "additionalProperties": false, - "properties": { - "bomFormat": { - "$id": "#/properties/bomFormat", - "type": "string", - "title": "BOM Format", - "description": "Specifies the format of the BOM. This helps to identify the file as CycloneDX since BOMs do not have a filename convention nor does JSON schema support namespaces.", - "enum": [ - "CycloneDX" - ] - }, - "specVersion": { - "$id": "#/properties/specVersion", - "type": "string", - "title": "CycloneDX Specification Version", - "description": "The version of the CycloneDX specification a BOM is written to (starting at version 1.2)", - "examples": ["1.2"] - }, - "serialNumber": { - "$id": "#/properties/serialNumber", - "type": "string", - "title": "BOM Serial Number", - "description": "Every BOM generated should have a unique serial number, even if the contents of the BOM being generated have not changed over time. The process or tool responsible for creating the BOM should create random UUID's for every BOM generated.", - "default": "", - "examples": ["urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"], - "pattern": "^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" - }, - "version": { - "$id": "#/properties/version", - "type": "integer", - "title": "BOM Version", - "description": "The version allows component publishers/authors to make changes to existing BOMs to update various aspects of the document such as description or licenses. When a system is presented with multiple BOMs for the same component, the system should use the most recent version of the BOM. The default version is '1' and should be incremented for each version of the BOM that is published. Each version of a component should have a unique BOM and if no changes are made to the BOMs, then each BOM will have a version of '1'.", - "default": 1, - "examples": [1] - }, - "metadata": { - "$id": "#/properties/metadata", - "$ref": "#/definitions/metadata", - "title": "BOM Metadata", - "description": "Provides additional information about a BOM." - }, - "components": { - "$id": "#/properties/components", - "type": "array", - "items": {"$ref": "#/definitions/component"}, - "uniqueItems": true, - "title": "Components" - }, - "services": { - "$id": "#/properties/services", - "type": "array", - "items": {"$ref": "#/definitions/service"}, - "uniqueItems": true, - "title": "Services" - }, - "externalReferences": { - "$id": "#/properties/externalReferences", - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References", - "description": "External references provide a way to document systems, sites, and information that may be relevant but which are not included with the BOM." - }, - "dependencies": { - "$id": "#/properties/dependencies", - "type": "array", - "items": {"$ref": "#/definitions/dependency"}, - "uniqueItems": true, - "title": "Dependencies", - "description": "Provides the ability to document dependency relationships." - } - }, - "definitions": { - "metadata": { - "type": "object", - "title": "BOM Metadata Object", - "additionalProperties": false, - "properties": { - "timestamp": { - "type": "string", - "format": "date-time", - "title": "Timestamp", - "description": "The date and time (timestamp) when the document was created." - }, - "tools": { - "type": "array", - "title": "Creation Tools", - "description": "The tool(s) used in the creation of the BOM.", - "items": {"$ref": "#/definitions/tool"} - }, - "authors" :{ - "type": "array", - "title": "Authors", - "description": "The person(s) who created the BOM. Authors are common in BOMs created through manual processes. BOMs created through automated means may not have authors.", - "items": {"$ref": "#/definitions/organizationalContact"} - }, - "component": { - "title": "Component", - "description": "The component that the BOM describes.", - "$ref": "#/definitions/component" - }, - "manufacture": { - "title": "Manufacture", - "description": "The organization that manufactured the component that the BOM describes.", - "$ref": "#/definitions/organizationalEntity" - }, - "supplier": { - "title": "Supplier", - "description": " The organization that supplied the component that the BOM describes. The supplier may often be the manufacture, but may also be a distributor or repackager.", - "$ref": "#/definitions/organizationalEntity" - } - } - }, - "tool": { - "type": "object", - "title": "Tool", - "description": "The tool used to create the BOM.", - "additionalProperties": false, - "properties": { - "vendor": { - "type": "string", - "format": "string", - "title": "Tool Vendor", - "description": "The date and time (timestamp) when the document was created." - }, - "name": { - "type": "string", - "format": "string", - "title": "Tool Name", - "description": "The date and time (timestamp) when the document was created." - }, - "version": { - "type": "string", - "format": "string", - "title": "Tool Version", - "description": "The date and time (timestamp) when the document was created." - }, - "hashes": { - "$id": "#/properties/hashes", - "type": "array", - "items": {"$ref": "#/definitions/hash"}, - "title": "Hashes", - "description": "The hashes of the tool (if applicable)." - } - } - }, - "organizationalEntity": { - "type": "object", - "title": "Organizational Entity Object", - "description": "", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of the organization", - "default": "", - "examples": [ - "Example Inc." - ], - "pattern": "^(.*)$" - }, - "url": { - "type": "array", - "title": "URL", - "description": "The URL of the organization. Multiple URLs are allowed.", - "default": "", - "examples": ["https://example.com"], - "pattern": "^(.*)$" - }, - "contact": { - "type": "array", - "title": "Contact", - "description": "A contact at the organization. Multiple contacts are allowed.", - "items": {"$ref": "#/definitions/organizationalContact"} - } - } - }, - "organizationalContact": { - "type": "object", - "title": "Organizational Contact Object", - "description": "", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of a contact", - "default": "", - "examples": ["Contact name"], - "pattern": "^(.*)$" - }, - "email": { - "type": "string", - "title": "Email Address", - "description": "The email address of the contact. Multiple email addresses are allowed.", - "default": "", - "examples": ["firstname.lastname@example.com"], - "pattern": "^(.*)$" - }, - "phone": { - "type": "string", - "title": "Phone", - "description": "The phone number of the contact. Multiple phone numbers are allowed.", - "default": "", - "examples": ["800-555-1212"], - "pattern": "^(.*)$" - } - } - }, - "component": { - "type": "object", - "title": "Component Object", - "required": [ - "type", - "name", - "version" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "application", - "framework", - "library", - "container", - "operating-system", - "device", - "firmware", - "file" - ], - "title": "Component Type", - "description": "Specifies the type of component. For software components, classify as application if no more specific appropriate classification is available or cannot be determined for the component.", - "default": "", - "examples": ["library"], - "pattern": "^(.*)$" - }, - "mime-type": { - "type": "string", - "title": "Mime-Type", - "description": "The optional mime-type of the component. When used on file components, the mime-type can provide additional context about the kind of file being represented such as an image, font, or executable. Some library or framework components may also have an associated mime-type.", - "default": "", - "examples": ["image/jpeg"], - "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" - }, - "bom-ref": { - "type": "string", - "title": "BOM Reference", - "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique.", - "default": "", - "pattern": "^(.*)$" - }, - "supplier": { - "title": "Component Supplier", - "description": " The organization that supplied the component. The supplier may often be the manufacture, but may also be a distributor or repackager.", - "$ref": "#/definitions/organizationalEntity" - }, - "author": { - "type": "string", - "title": "Component Author", - "description": "The person(s) or organization(s) that authored the component", - "default": "", - "examples": ["Acme Inc"], - "pattern": "^(.*)$" - }, - "publisher": { - "type": "string", - "title": "Component Publisher", - "description": "The person(s) or organization(s) that published the component", - "default": "", - "examples": ["Acme Inc"], - "pattern": "^(.*)$" - }, - "group": { - "type": "string", - "title": "Component Group", - "description": "The grouping name or identifier. This will often be a shortened, single name of the company or project that produced the component, or the source package or domain name. Whitespace and special characters should be avoided. Examples include: apache, org.apache.commons, and apache.org.", - "default": "", - "examples": ["com.acme"], - "pattern": "^(.*)$" - }, - "name": { - "type": "string", - "title": "Component Name", - "description": "The name of the component. This will often be a shortened, single name of the component. Examples: commons-lang3 and jquery", - "default": "", - "examples": ["tomcat-catalina"], - "pattern": "^(.*)$" - }, - "version": { - "type": "string", - "title": "Component Version", - "description": "The component version. The version should ideally comply with semantic versioning but is not enforced.", - "default": "", - "examples": ["9.0.14"], - "pattern": "^(.*)$" - }, - "description": { - "type": "string", - "title": "Component Description", - "description": "Specifies a description for the component", - "default": "", - "pattern": "^(.*)$" - }, - "scope": { - "type": "string", - "enum": [ - "required", - "optional", - "excluded" - ], - "title": "Component Scope", - "description": "Specifies the scope of the component. If scope is not specified, 'required' scope should be assumed by the consumer of the BOM", - "default": "required", - "pattern": "^(.*)$" - }, - "hashes": { - "type": "array", - "title": "Component Hashes", - "items": {"$ref": "#/definitions/hash"} - }, - "licenses": { - "type": "array", - "title": "Component License(s)", - "items": { - "additionalProperties": false, - "properties": { - "license": { - "$ref": "#/definitions/license" - }, - "expression": { - "type": "string", - "title": "SPDX License Expression", - "examples": [ - "Apache-2.0 AND (MIT OR GPL-2.0-only)", - "GPL-3.0-only WITH Classpath-exception-2.0" - ], - "pattern": "^(.*)$" - } - }, - "oneOf":[ - { - "required": ["license"] - }, - { - "required": ["expression"] - } - ] - } - }, - "copyright": { - "type": "string", - "title": "Component Copyright", - "description": "An optional copyright notice informing users of the underlying claims to copyright ownership in a published work.", - "examples": ["Acme Inc"], - "pattern": "^(.*)$" - }, - "cpe": { - "type": "string", - "title": "Component Common Platform Enumeration (CPE)", - "description": "DEPRECATED - DO NOT USE. This will be removed in a future version. Specifies a well-formed CPE name. See https://nvd.nist.gov/products/cpe", - "examples": ["cpe:2.3:a:acme:component_framework:-:*:*:*:*:*:*:*"], - "pattern": "^(.*)$" - }, - "purl": { - "type": "string", - "title": "Component Package URL (purl)", - "default": "", - "examples": ["pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar"], - "pattern": "^(.*)$" - }, - "swid": { - "$ref": "#/definitions/swid", - "title": "SWID Tag", - "description": "Specifies metadata and content for ISO-IEC 19770-2 Software Identification (SWID) Tags." - }, - "modified": { - "type": "boolean", - "title": "Component Modified From Original", - "description": "DEPRECATED - DO NOT USE. This will be removed in a future version. Use the pedigree element instead to supply information on exactly how the component was modified. A boolean value indicating is the component has been modified from the original. A value of true indicates the component is a derivative of the original. A value of false indicates the component has not been modified from the original." - }, - "pedigree": { - "type": "object", - "title": "Component Pedigree", - "description": "Component pedigree is a way to document complex supply chain scenarios where components are created, distributed, modified, redistributed, combined with other components, etc. Pedigree supports viewing this complex chain from the beginning, the end, or anywhere in the middle. It also provides a way to document variants where the exact relation may not be known.", - "additionalProperties": false, - "properties": { - "ancestors": { - "type": "array", - "title": "Ancestors", - "description": "Describes zero or more components in which a component is derived from. This is commonly used to describe forks from existing projects where the forked version contains a ancestor node containing the original component it was forked from. For example, Component A is the original component. Component B is the component being used and documented in the BOM. However, Component B contains a pedigree node with a single ancestor documenting Component A - the original component from which Component B is derived from.", - "items": {"$ref": "#/definitions/component"} - }, - "descendants": { - "type": "array", - "title": "Descendants", - "description": "Descendants are the exact opposite of ancestors. This provides a way to document all forks (and their forks) of an original or root component.", - "items": {"$ref": "#/definitions/component"} - }, - "variants": { - "type": "array", - "title": "Variants", - "description": "Variants describe relations where the relationship between the components are not known. For example, if Component A contains nearly identical code to Component B. They are both related, but it is unclear if one is derived from the other, or if they share a common ancestor.", - "items": {"$ref": "#/definitions/component"} - }, - "commits": { - "type": "array", - "title": "Commits", - "description": "A list of zero or more commits which provide a trail describing how the component deviates from an ancestor, descendant, or variant.", - "items": {"$ref": "#/definitions/commit"} - }, - "patches": { - "type": "array", - "title": "Patches", - "description": ">A list of zero or more patches describing how the component deviates from an ancestor, descendant, or variant. Patches may be complimentary to commits or may be used in place of commits.", - "items": {"$ref": "#/definitions/patch"} - }, - "notes": { - "type": "string", - "title": "Notes", - "description": "Notes, observations, and other non-structured commentary describing the components pedigree.", - "pattern": "^(.*)$" - } - } - }, - "externalReferences": { - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References" - }, - "components": { - "$id": "#/properties/components", - "type": "array", - "items": {"$ref": "#/definitions/component"}, - "uniqueItems": true, - "title": "Components" - } - } - }, - "swid": { - "type": "object", - "title": "SWID Tag", - "description": "Specifies metadata and content for ISO-IEC 19770-2 Software Identification (SWID) Tags.", - "required": [ - "tagId", - "name" - ], - "additionalProperties": false, - "properties": { - "tagId": { - "type": "string", - "title": "Tag ID", - "description": "Maps to the tagId of a SoftwareIdentity." - }, - "name": { - "type": "string", - "title": "Name", - "description": "Maps to the name of a SoftwareIdentity." - }, - "version": { - "type": "string", - "title": "Version", - "default": "0.0", - "description": "Maps to the version of a SoftwareIdentity." - }, - "tagVersion": { - "type": "integer", - "title": "Tag Version", - "default": 0, - "description": "Maps to the tagVersion of a SoftwareIdentity." - }, - "patch": { - "type": "boolean", - "title": "Patch", - "default": false, - "description": "Maps to the patch of a SoftwareIdentity." - }, - "text": { - "title": "Attachment text", - "description": "Specifies the metadata and content of the SWID tag.", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "URL", - "default": "The URL to the SWID file.", - "pattern": "^(.*)$" - } - } - }, - "attachment": { - "type": "object", - "title": "Attachment", - "description": "Specifies the metadata and content for an attachment.", - "required": [ - "content" - ], - "additionalProperties": false, - "properties": { - "contentType": { - "type": "string", - "title": "Content-Type", - "description": "Specifies the content type of the text. Defaults to text/plain if not specified.", - "default": "text/plain" - }, - "encoding": { - "type": "string", - "title": "Encoding", - "description": "Specifies the optional encoding the text is represented in.", - "enum": [ - "base64" - ], - "default": "", - "pattern": "^(.*)$" - }, - "content": { - "type": "string", - "title": "Attachment Text", - "description": "The attachment data" - } - } - }, - "hash": { - "type": "object", - "title": "Hash Objects", - "required": [ - "alg", - "content" - ], - "additionalProperties": false, - "properties": { - "alg": { - "$ref": "#/definitions/hash-alg" - }, - "content": { - "$ref": "#/definitions/hash-content" - } - } - }, - "hash-alg": { - "type": "string", - "enum": [ - "MD5", - "SHA-1", - "SHA-256", - "SHA-384", - "SHA-512", - "SHA3-256", - "SHA3-384", - "SHA3-512", - "BLAKE2b-256", - "BLAKE2b-384", - "BLAKE2b-512", - "BLAKE3" - ], - "title": "Hash Algorithm", - "default": "", - "pattern": "^(.*)$" - }, - "hash-content": { - "type": "string", - "title": "Hash Content (value)", - "default": "", - "examples": ["3942447fac867ae5cdb3229b658f4d48"], - "pattern": "^([a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128})$" - }, - "license": { - "type": "object", - "title": "License Object", - "oneOf": [ - { - "required": ["id"] - }, - { - "required": ["name"] - } - ], - "additionalProperties": false, - "properties": { - "id": { - "$ref": "spdx.schema.json", - "title": "License ID (SPDX)", - "description": "A valid SPDX license ID", - "examples": ["Apache-2.0"] - }, - "name": { - "type": "string", - "title": "License Name", - "description": "If SPDX does not define the license used, this field may be used to provide the license name", - "default": "", - "examples": ["Acme Software License"], - "pattern": "^(.*)$" - }, - "text": { - "title": "License text", - "description": "An optional way to include the textual content of a license.", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "License URL", - "description": "The URL to the license file. If specified, a 'license' externalReference should also be specified for completeness", - "examples": ["https://www.apache.org/licenses/LICENSE-2.0.txt"], - "pattern": "^(.*)$" - } - } - }, - "commit": { - "type": "object", - "title": "Commit", - "description": "Specifies an individual commit", - "additionalProperties": false, - "properties": { - "uid": { - "type": "string", - "title": "UID", - "description": "A unique identifier of the commit. This may be version control specific. For example, Subversion uses revision numbers whereas git uses commit hashes.", - "pattern": "^(.*)$" - }, - "url": { - "type": "string", - "title": "URL", - "description": "The URL to the commit. This URL will typically point to a commit in a version control system.", - "format": "iri-reference" - }, - "author": { - "title": "Author", - "description": "The author who created the changes in the commit", - "$ref": "#/definitions/identifiableAction" - }, - "committer": { - "title": "Committer", - "description": "The person who committed or pushed the commit", - "$ref": "#/definitions/identifiableAction" - }, - "message": { - "type": "string", - "title": "Message", - "description": "The text description of the contents of the commit", - "pattern": "^(.*)$" - } - } - }, - "patch": { - "type": "object", - "title": "Patch", - "description": "Specifies an individual patch", - "required": [ - "type" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "unofficial", - "monkey", - "backport", - "cherry-pick" - ], - "title": "Type", - "description": "Specifies the purpose for the patch including the resolution of defects, security issues, or new behavior or functionality" - }, - "diff": { - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "$ref": "#/definitions/diff" - }, - "resolves": { - "type": "array", - "items": {"$ref": "#/definitions/issue"}, - "title": "Resolves", - "description": "A collection of issues the patch resolves" - } - } - }, - "diff": { - "type": "object", - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "additionalProperties": false, - "properties": { - "text": { - "title": "Diff text", - "description": "Specifies the optional text of the diff", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "URL", - "description": "Specifies the URL to the diff", - "pattern": "^(.*)$" - } - } - }, - "issue": { - "type": "object", - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "required": [ - "type" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "defect", - "enhancement", - "security" - ], - "title": "Type", - "description": "Specifies the type of issue" - }, - "id": { - "type": "string", - "title": "ID", - "description": "The identifier of the issue assigned by the source of the issue", - "pattern": "^(.*)$" - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the issue", - "pattern": "^(.*)$" - }, - "description": { - "type": "string", - "title": "Description", - "description": "A description of the issue", - "pattern": "^(.*)$" - }, - "source": { - "type": "object", - "title": "Source", - "description": "The source of the issue where it is documented", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of the source. For example 'National Vulnerability Database', 'NVD', and 'Apache'", - "pattern": "^(.*)$" - }, - "url": { - "type": "string", - "title": "URL", - "description": "The url of the issue documentation as provided by the source", - "pattern": "^(.*)$" - } - } - }, - "references": { - "type": "array", - "title": "References", - "description": "A collection of URL's for reference. Multiple URLs are allowed.", - "default": "", - "examples": ["https://example.com"], - "pattern": "^(.*)$" - } - } - }, - "identifiableAction": { - "type": "object", - "title": "Identifiable Action", - "description": "Specifies an individual commit", - "additionalProperties": false, - "properties": { - "timestamp": { - "type": "string", - "format": "date-time", - "title": "Timestamp", - "description": "The timestamp in which the action occurred" - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the individual who performed the action", - "pattern": "^(.*)$" - }, - "email": { - "type": "string", - "format": "idn-email", - "title": "E-mail", - "description": "The email address of the individual who performed the action" - } - } - }, - "externalReference": { - "type": "object", - "title": "External Reference", - "description": "Specifies an individual external reference", - "required": [ - "url", - "type" - ], - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "title": "URL", - "description": "The URL to the external reference", - "pattern": "^(.*)$" - }, - "comment": { - "type": "string", - "title": "Comment", - "description": "An optional comment describing the external reference", - "pattern": "^(.*)$" - }, - "type": { - "type": "string", - "title": "Type", - "description": "Specifies the type of external reference. There are built-in types to describe common references. If a type does not exist for the reference being referred to, use the \"other\" type.", - "enum": [ - "vcs", - "issue-tracker", - "website", - "advisories", - "bom", - "mailing-list", - "social", - "chat", - "documentation", - "support", - "distribution", - "license", - "build-meta", - "build-system", - "other" - ] - } - } - }, - "dependency": { - "type": "object", - "title": "Dependency", - "description": "Defines the direct dependencies of a component. Components that do not have their own dependencies MUST be declared as empty elements within the graph. Components that are not represented in the dependency graph MAY have unknown dependencies. It is RECOMMENDED that implementations assume this to be opaque and not an indicator of a component being dependency-free.", - "required": [ - "ref" - ], - "additionalProperties": false, - "properties": { - "ref": { - "type": "string", - "format": "string", - "title": "Reference", - "description": "References a component by the components bom-ref attribute" - }, - "dependsOn": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - }, - "title": "Depends On", - "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." - } - } - }, - "service": { - "type": "object", - "title": "Service Object", - "required": [ - "name" - ], - "additionalProperties": false, - "properties": { - "bom-ref": { - "type": "string", - "title": "BOM Reference", - "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique.", - "default": "", - "pattern": "^(.*)$" - }, - "provider": { - "title": "Provider", - "description": "The organization that provides the service.", - "$ref": "#/definitions/organizationalEntity" - }, - "group": { - "type": "string", - "title": "Service Group", - "description": "The grouping name, namespace, or identifier. This will often be a shortened, single name of the company or project that produced the service or domain name. Whitespace and special characters should be avoided.", - "default": "", - "examples": ["com.acme"], - "pattern": "^(.*)$" - }, - "name": { - "type": "string", - "title": "Service Name", - "description": "The name of the service. This will often be a shortened, single name of the service.", - "default": "", - "examples": ["ticker-service"], - "pattern": "^(.*)$" - }, - "version": { - "type": "string", - "title": "Service Version", - "description": "The service version.", - "default": "", - "examples": ["1.0.0"], - "pattern": "^(.*)$" - }, - "description": { - "type": "string", - "title": "Service Description", - "description": "Specifies a description for the service", - "default": "", - "pattern": "^(.*)$" - }, - "endpoints": { - "type": "array", - "title": "Endpoints", - "description": "The endpoint URIs of the service. Multiple endpoints are allowed.", - "default": "", - "examples": ["https://example.com/api/v1/ticker"], - "pattern": "^(.*)$" - }, - "authenticated": { - "type": "boolean", - "title": "Authentication Required", - "description": "A boolean value indicating if the service requires authentication. A value of true indicates the service requires authentication prior to use. A value of false indicates the service does not require authentication." - }, - "x-trust-boundary": { - "type": "boolean", - "title": "Crosses Trust Boundary", - "description": "A boolean value indicating if use of the service crosses a trust zone or boundary. A value of true indicates that by using the service, a trust boundary is crossed. A value of false indicates that by using the service, a trust boundary is not crossed." - }, - "data": { - "type": "array", - "items": {"$ref": "#/definitions/dataClassification"}, - "title": "Data Classification", - "description": "Specifies the data classification." - }, - "licenses": { - "type": "array", - "title": "Component License(s)", - "items": { - "additionalProperties": false, - "properties": { - "license": { - "$ref": "#/definitions/license" - }, - "expression": { - "type": "string", - "title": "SPDX License Expression", - "examples": [ - "Apache-2.0 AND (MIT OR GPL-2.0-only)", - "GPL-3.0-only WITH Classpath-exception-2.0" - ], - "pattern": "^(.*)$" - } - }, - "oneOf":[ - { - "required": ["license"] - }, - { - "required": ["expression"] - } - ] - } - }, - "externalReferences": { - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References" - }, - "services": { - "$id": "#/properties/services", - "type": "array", - "items": {"$ref": "#/definitions/service"}, - "uniqueItems": true, - "title": "Services" - } - } - }, - "dataClassification": { - "type": "object", - "title": "Hash Objects", - "required": [ - "flow", - "classification" - ], - "additionalProperties": false, - "properties": { - "flow": { - "$ref": "#/definitions/dataFlow" - }, - "classification": { - "type": "string" - } - } - }, - "dataFlow": { - "type": "string", - "enum": [ - "inbound", - "outbound", - "bi-directional", - "unknown" - ], - "title": "Data flow direction", - "default": "", - "pattern": "^(.*)$" - } - } -} diff --git a/cyclonedx/schema/bom-1.3-strict.schema.json b/cyclonedx/schema/bom-1.3-strict.schema.json deleted file mode 100644 index 35c8c2e5..00000000 --- a/cyclonedx/schema/bom-1.3-strict.schema.json +++ /dev/null @@ -1,1085 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://cyclonedx.org/schema/bom-1.3.schema.json", - "type": "object", - "title": "CycloneDX Software Bill-of-Material Specification", - "$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.", - "required": [ - "bomFormat", - "specVersion", - "version" - ], - "additionalProperties": false, - "properties": { - "$schema": { - "type": "string", - "enum": [ - "http://cyclonedx.org/schema/bom-1.3.schema.json" - ] - }, - "bomFormat": { - "$id": "#/properties/bomFormat", - "type": "string", - "title": "BOM Format", - "description": "Specifies the format of the BOM. This helps to identify the file as CycloneDX since BOMs do not have a filename convention nor does JSON schema support namespaces.", - "enum": [ - "CycloneDX" - ] - }, - "specVersion": { - "$id": "#/properties/specVersion", - "type": "string", - "title": "CycloneDX Specification Version", - "description": "The version of the CycloneDX specification a BOM is written to (starting at version 1.2)", - "examples": ["1.3"] - }, - "serialNumber": { - "$id": "#/properties/serialNumber", - "type": "string", - "title": "BOM Serial Number", - "description": "Every BOM generated should have a unique serial number, even if the contents of the BOM being generated have not changed over time. The process or tool responsible for creating the BOM should create random UUID's for every BOM generated.", - "examples": ["urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"], - "pattern": "^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" - }, - "version": { - "$id": "#/properties/version", - "type": "integer", - "title": "BOM Version", - "description": "The version allows component publishers/authors to make changes to existing BOMs to update various aspects of the document such as description or licenses. When a system is presented with multiple BOMs for the same component, the system should use the most recent version of the BOM. The default version is '1' and should be incremented for each version of the BOM that is published. Each version of a component should have a unique BOM and if no changes are made to the BOMs, then each BOM will have a version of '1'.", - "default": 1, - "examples": [1] - }, - "metadata": { - "$id": "#/properties/metadata", - "$ref": "#/definitions/metadata", - "title": "BOM Metadata", - "description": "Provides additional information about a BOM." - }, - "components": { - "$id": "#/properties/components", - "type": "array", - "items": {"$ref": "#/definitions/component"}, - "uniqueItems": true, - "title": "Components" - }, - "services": { - "$id": "#/properties/services", - "type": "array", - "items": {"$ref": "#/definitions/service"}, - "uniqueItems": true, - "title": "Services" - }, - "externalReferences": { - "$id": "#/properties/externalReferences", - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References", - "description": "External references provide a way to document systems, sites, and information that may be relevant but which are not included with the BOM." - }, - "dependencies": { - "$id": "#/properties/dependencies", - "type": "array", - "items": {"$ref": "#/definitions/dependency"}, - "uniqueItems": true, - "title": "Dependencies", - "description": "Provides the ability to document dependency relationships." - }, - "compositions": { - "$id": "#/properties/compositions", - "type": "array", - "items": {"$ref": "#/definitions/compositions"}, - "uniqueItems": true, - "title": "Compositions", - "description": "Compositions describe constituent parts (including components, services, and dependency relationships) and their completeness." - } - }, - "definitions": { - "metadata": { - "type": "object", - "title": "BOM Metadata Object", - "additionalProperties": false, - "properties": { - "timestamp": { - "type": "string", - "format": "date-time", - "title": "Timestamp", - "description": "The date and time (timestamp) when the document was created." - }, - "tools": { - "type": "array", - "title": "Creation Tools", - "description": "The tool(s) used in the creation of the BOM.", - "items": {"$ref": "#/definitions/tool"} - }, - "authors" :{ - "type": "array", - "title": "Authors", - "description": "The person(s) who created the BOM. Authors are common in BOMs created through manual processes. BOMs created through automated means may not have authors.", - "items": {"$ref": "#/definitions/organizationalContact"} - }, - "component": { - "title": "Component", - "description": "The component that the BOM describes.", - "$ref": "#/definitions/component" - }, - "manufacture": { - "title": "Manufacture", - "description": "The organization that manufactured the component that the BOM describes.", - "$ref": "#/definitions/organizationalEntity" - }, - "supplier": { - "title": "Supplier", - "description": " The organization that supplied the component that the BOM describes. The supplier may often be the manufacturer, but may also be a distributor or repackager.", - "$ref": "#/definitions/organizationalEntity" - }, - "licenses": { - "type": "array", - "title": "BOM License(s)", - "items": {"$ref": "#/definitions/licenseChoice"} - }, - "properties": { - "type": "array", - "title": "Properties", - "description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values.", - "items": {"$ref": "#/definitions/property"} - } - } - }, - "tool": { - "type": "object", - "title": "Tool", - "description": "The tool used to create the BOM.", - "additionalProperties": false, - "properties": { - "vendor": { - "type": "string", - "title": "Tool Vendor", - "description": "The date and time (timestamp) when the document was created." - }, - "name": { - "type": "string", - "title": "Tool Name", - "description": "The date and time (timestamp) when the document was created." - }, - "version": { - "type": "string", - "title": "Tool Version", - "description": "The date and time (timestamp) when the document was created." - }, - "hashes": { - "$id": "#/properties/hashes", - "type": "array", - "items": {"$ref": "#/definitions/hash"}, - "title": "Hashes", - "description": "The hashes of the tool (if applicable)." - } - } - }, - "organizationalEntity": { - "type": "object", - "title": "Organizational Entity Object", - "description": "", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of the organization", - "examples": [ - "Example Inc." - ] - }, - "url": { - "type": "array", - "items": { - "type": "string", - "format": "iri-reference" - }, - "title": "URL", - "description": "The URL of the organization. Multiple URLs are allowed.", - "examples": ["https://example.com"] - }, - "contact": { - "type": "array", - "title": "Contact", - "description": "A contact at the organization. Multiple contacts are allowed.", - "items": {"$ref": "#/definitions/organizationalContact"} - } - } - }, - "organizationalContact": { - "type": "object", - "title": "Organizational Contact Object", - "description": "", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of a contact", - "examples": ["Contact name"] - }, - "email": { - "type": "string", - "title": "Email Address", - "description": "The email address of the contact.", - "examples": ["firstname.lastname@example.com"] - }, - "phone": { - "type": "string", - "title": "Phone", - "description": "The phone number of the contact.", - "examples": ["800-555-1212"] - } - } - }, - "component": { - "type": "object", - "title": "Component Object", - "required": [ - "type", - "name", - "version" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "application", - "framework", - "library", - "container", - "operating-system", - "device", - "firmware", - "file" - ], - "title": "Component Type", - "description": "Specifies the type of component. For software components, classify as application if no more specific appropriate classification is available or cannot be determined for the component.", - "examples": ["library"] - }, - "mime-type": { - "type": "string", - "title": "Mime-Type", - "description": "The optional mime-type of the component. When used on file components, the mime-type can provide additional context about the kind of file being represented such as an image, font, or executable. Some library or framework components may also have an associated mime-type.", - "examples": ["image/jpeg"], - "pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$" - }, - "bom-ref": { - "type": "string", - "title": "BOM Reference", - "description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique." - }, - "supplier": { - "title": "Component Supplier", - "description": " The organization that supplied the component. The supplier may often be the manufacturer, but may also be a distributor or repackager.", - "$ref": "#/definitions/organizationalEntity" - }, - "author": { - "type": "string", - "title": "Component Author", - "description": "The person(s) or organization(s) that authored the component", - "examples": ["Acme Inc"] - }, - "publisher": { - "type": "string", - "title": "Component Publisher", - "description": "The person(s) or organization(s) that published the component", - "examples": ["Acme Inc"] - }, - "group": { - "type": "string", - "title": "Component Group", - "description": "The grouping name or identifier. This will often be a shortened, single name of the company or project that produced the component, or the source package or domain name. Whitespace and special characters should be avoided. Examples include: apache, org.apache.commons, and apache.org.", - "examples": ["com.acme"] - }, - "name": { - "type": "string", - "title": "Component Name", - "description": "The name of the component. This will often be a shortened, single name of the component. Examples: commons-lang3 and jquery", - "examples": ["tomcat-catalina"] - }, - "version": { - "type": "string", - "title": "Component Version", - "description": "The component version. The version should ideally comply with semantic versioning but is not enforced.", - "examples": ["9.0.14"] - }, - "description": { - "type": "string", - "title": "Component Description", - "description": "Specifies a description for the component" - }, - "scope": { - "type": "string", - "enum": [ - "required", - "optional", - "excluded" - ], - "title": "Component Scope", - "description": "Specifies the scope of the component. If scope is not specified, 'required' scope should be assumed by the consumer of the BOM", - "default": "required" - }, - "hashes": { - "type": "array", - "title": "Component Hashes", - "items": {"$ref": "#/definitions/hash"} - }, - "licenses": { - "type": "array", - "items": {"$ref": "#/definitions/licenseChoice"}, - "title": "Component License(s)" - }, - "copyright": { - "type": "string", - "title": "Component Copyright", - "description": "An optional copyright notice informing users of the underlying claims to copyright ownership in a published work.", - "examples": ["Acme Inc"] - }, - "cpe": { - "type": "string", - "title": "Component Common Platform Enumeration (CPE)", - "description": "DEPRECATED - DO NOT USE. This will be removed in a future version. Specifies a well-formed CPE name. See https://nvd.nist.gov/products/cpe", - "examples": ["cpe:2.3:a:acme:component_framework:-:*:*:*:*:*:*:*"] - }, - "purl": { - "type": "string", - "title": "Component Package URL (purl)", - "examples": ["pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar"] - }, - "swid": { - "$ref": "#/definitions/swid", - "title": "SWID Tag", - "description": "Specifies metadata and content for ISO-IEC 19770-2 Software Identification (SWID) Tags." - }, - "modified": { - "type": "boolean", - "title": "Component Modified From Original", - "description": "DEPRECATED - DO NOT USE. This will be removed in a future version. Use the pedigree element instead to supply information on exactly how the component was modified. A boolean value indicating is the component has been modified from the original. A value of true indicates the component is a derivative of the original. A value of false indicates the component has not been modified from the original." - }, - "pedigree": { - "type": "object", - "title": "Component Pedigree", - "description": "Component pedigree is a way to document complex supply chain scenarios where components are created, distributed, modified, redistributed, combined with other components, etc. Pedigree supports viewing this complex chain from the beginning, the end, or anywhere in the middle. It also provides a way to document variants where the exact relation may not be known.", - "additionalProperties": false, - "properties": { - "ancestors": { - "type": "array", - "title": "Ancestors", - "description": "Describes zero or more components in which a component is derived from. This is commonly used to describe forks from existing projects where the forked version contains a ancestor node containing the original component it was forked from. For example, Component A is the original component. Component B is the component being used and documented in the BOM. However, Component B contains a pedigree node with a single ancestor documenting Component A - the original component from which Component B is derived from.", - "items": {"$ref": "#/definitions/component"} - }, - "descendants": { - "type": "array", - "title": "Descendants", - "description": "Descendants are the exact opposite of ancestors. This provides a way to document all forks (and their forks) of an original or root component.", - "items": {"$ref": "#/definitions/component"} - }, - "variants": { - "type": "array", - "title": "Variants", - "description": "Variants describe relations where the relationship between the components are not known. For example, if Component A contains nearly identical code to Component B. They are both related, but it is unclear if one is derived from the other, or if they share a common ancestor.", - "items": {"$ref": "#/definitions/component"} - }, - "commits": { - "type": "array", - "title": "Commits", - "description": "A list of zero or more commits which provide a trail describing how the component deviates from an ancestor, descendant, or variant.", - "items": {"$ref": "#/definitions/commit"} - }, - "patches": { - "type": "array", - "title": "Patches", - "description": ">A list of zero or more patches describing how the component deviates from an ancestor, descendant, or variant. Patches may be complimentary to commits or may be used in place of commits.", - "items": {"$ref": "#/definitions/patch"} - }, - "notes": { - "type": "string", - "title": "Notes", - "description": "Notes, observations, and other non-structured commentary describing the components pedigree." - } - } - }, - "externalReferences": { - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References" - }, - "components": { - "$id": "#/properties/components", - "type": "array", - "items": {"$ref": "#/definitions/component"}, - "uniqueItems": true, - "title": "Components" - }, - "evidence": { - "$ref": "#/definitions/componentEvidence", - "title": "Evidence", - "description": "Provides the ability to document evidence collected through various forms of extraction or analysis." - }, - "properties": { - "type": "array", - "title": "Properties", - "description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values.", - "items": {"$ref": "#/definitions/property"} - } - } - }, - "swid": { - "type": "object", - "title": "SWID Tag", - "description": "Specifies metadata and content for ISO-IEC 19770-2 Software Identification (SWID) Tags.", - "required": [ - "tagId", - "name" - ], - "additionalProperties": false, - "properties": { - "tagId": { - "type": "string", - "title": "Tag ID", - "description": "Maps to the tagId of a SoftwareIdentity." - }, - "name": { - "type": "string", - "title": "Name", - "description": "Maps to the name of a SoftwareIdentity." - }, - "version": { - "type": "string", - "title": "Version", - "default": "0.0", - "description": "Maps to the version of a SoftwareIdentity." - }, - "tagVersion": { - "type": "integer", - "title": "Tag Version", - "default": 0, - "description": "Maps to the tagVersion of a SoftwareIdentity." - }, - "patch": { - "type": "boolean", - "title": "Patch", - "default": false, - "description": "Maps to the patch of a SoftwareIdentity." - }, - "text": { - "title": "Attachment text", - "description": "Specifies the metadata and content of the SWID tag.", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "URL", - "description": "The URL to the SWID file.", - "format": "iri-reference" - } - } - }, - "attachment": { - "type": "object", - "title": "Attachment", - "description": "Specifies the metadata and content for an attachment.", - "required": [ - "content" - ], - "additionalProperties": false, - "properties": { - "contentType": { - "type": "string", - "title": "Content-Type", - "description": "Specifies the content type of the text. Defaults to text/plain if not specified.", - "default": "text/plain" - }, - "encoding": { - "type": "string", - "title": "Encoding", - "description": "Specifies the optional encoding the text is represented in.", - "enum": [ - "base64" - ] - }, - "content": { - "type": "string", - "title": "Attachment Text", - "description": "The attachment data" - } - } - }, - "hash": { - "type": "object", - "title": "Hash Objects", - "required": [ - "alg", - "content" - ], - "additionalProperties": false, - "properties": { - "alg": { - "$ref": "#/definitions/hash-alg" - }, - "content": { - "$ref": "#/definitions/hash-content" - } - } - }, - "hash-alg": { - "type": "string", - "enum": [ - "MD5", - "SHA-1", - "SHA-256", - "SHA-384", - "SHA-512", - "SHA3-256", - "SHA3-384", - "SHA3-512", - "BLAKE2b-256", - "BLAKE2b-384", - "BLAKE2b-512", - "BLAKE3" - ], - "title": "Hash Algorithm" - }, - "hash-content": { - "type": "string", - "title": "Hash Content (value)", - "examples": ["3942447fac867ae5cdb3229b658f4d48"], - "pattern": "^([a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128})$" - }, - "license": { - "type": "object", - "title": "License Object", - "oneOf": [ - { - "required": ["id"] - }, - { - "required": ["name"] - } - ], - "additionalProperties": false, - "properties": { - "id": { - "$ref": "spdx.schema.json", - "title": "License ID (SPDX)", - "description": "A valid SPDX license ID", - "examples": ["Apache-2.0"] - }, - "name": { - "type": "string", - "title": "License Name", - "description": "If SPDX does not define the license used, this field may be used to provide the license name", - "examples": ["Acme Software License"] - }, - "text": { - "title": "License text", - "description": "An optional way to include the textual content of a license.", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "License URL", - "description": "The URL to the license file. If specified, a 'license' externalReference should also be specified for completeness", - "examples": ["https://www.apache.org/licenses/LICENSE-2.0.txt"], - "format": "iri-reference" - } - } - }, - "licenseChoice": { - "type": "object", - "title": "License(s)", - "additionalProperties": false, - "properties": { - "license": { - "$ref": "#/definitions/license" - }, - "expression": { - "type": "string", - "title": "SPDX License Expression", - "examples": [ - "Apache-2.0 AND (MIT OR GPL-2.0-only)", - "GPL-3.0-only WITH Classpath-exception-2.0" - ] - } - }, - "oneOf":[ - { - "required": ["license"] - }, - { - "required": ["expression"] - } - ] - }, - "commit": { - "type": "object", - "title": "Commit", - "description": "Specifies an individual commit", - "additionalProperties": false, - "properties": { - "uid": { - "type": "string", - "title": "UID", - "description": "A unique identifier of the commit. This may be version control specific. For example, Subversion uses revision numbers whereas git uses commit hashes." - }, - "url": { - "type": "string", - "title": "URL", - "description": "The URL to the commit. This URL will typically point to a commit in a version control system.", - "format": "iri-reference" - }, - "author": { - "title": "Author", - "description": "The author who created the changes in the commit", - "$ref": "#/definitions/identifiableAction" - }, - "committer": { - "title": "Committer", - "description": "The person who committed or pushed the commit", - "$ref": "#/definitions/identifiableAction" - }, - "message": { - "type": "string", - "title": "Message", - "description": "The text description of the contents of the commit" - } - } - }, - "patch": { - "type": "object", - "title": "Patch", - "description": "Specifies an individual patch", - "required": [ - "type" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "unofficial", - "monkey", - "backport", - "cherry-pick" - ], - "title": "Type", - "description": "Specifies the purpose for the patch including the resolution of defects, security issues, or new behavior or functionality" - }, - "diff": { - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "$ref": "#/definitions/diff" - }, - "resolves": { - "type": "array", - "items": {"$ref": "#/definitions/issue"}, - "title": "Resolves", - "description": "A collection of issues the patch resolves" - } - } - }, - "diff": { - "type": "object", - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "additionalProperties": false, - "properties": { - "text": { - "title": "Diff text", - "description": "Specifies the optional text of the diff", - "$ref": "#/definitions/attachment" - }, - "url": { - "type": "string", - "title": "URL", - "description": "Specifies the URL to the diff", - "format": "iri-reference" - } - } - }, - "issue": { - "type": "object", - "title": "Diff", - "description": "The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff", - "required": [ - "type" - ], - "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "defect", - "enhancement", - "security" - ], - "title": "Type", - "description": "Specifies the type of issue" - }, - "id": { - "type": "string", - "title": "ID", - "description": "The identifier of the issue assigned by the source of the issue" - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the issue" - }, - "description": { - "type": "string", - "title": "Description", - "description": "A description of the issue" - }, - "source": { - "type": "object", - "title": "Source", - "description": "The source of the issue where it is documented", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of the source. For example 'National Vulnerability Database', 'NVD', and 'Apache'" - }, - "url": { - "type": "string", - "title": "URL", - "description": "The url of the issue documentation as provided by the source", - "format": "iri-reference" - } - } - }, - "references": { - "type": "array", - "items": { - "type": "string", - "format": "iri-reference" - }, - "title": "References", - "description": "A collection of URL's for reference. Multiple URLs are allowed.", - "examples": ["https://example.com"] - } - } - }, - "identifiableAction": { - "type": "object", - "title": "Identifiable Action", - "description": "Specifies an individual commit", - "additionalProperties": false, - "properties": { - "timestamp": { - "type": "string", - "format": "date-time", - "title": "Timestamp", - "description": "The timestamp in which the action occurred" - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the individual who performed the action" - }, - "email": { - "type": "string", - "format": "idn-email", - "title": "E-mail", - "description": "The email address of the individual who performed the action" - } - } - }, - "externalReference": { - "type": "object", - "title": "External Reference", - "description": "Specifies an individual external reference", - "required": [ - "url", - "type" - ], - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "title": "URL", - "description": "The URL to the external reference", - "format": "iri-reference" - }, - "comment": { - "type": "string", - "title": "Comment", - "description": "An optional comment describing the external reference" - }, - "type": { - "type": "string", - "title": "Type", - "description": "Specifies the type of external reference. There are built-in types to describe common references. If a type does not exist for the reference being referred to, use the \"other\" type.", - "enum": [ - "vcs", - "issue-tracker", - "website", - "advisories", - "bom", - "mailing-list", - "social", - "chat", - "documentation", - "support", - "distribution", - "license", - "build-meta", - "build-system", - "other" - ] - }, - "hashes": { - "$id": "#/properties/hashes", - "type": "array", - "items": {"$ref": "#/definitions/hash"}, - "title": "Hashes", - "description": "The hashes of the external reference (if applicable)." - } - } - }, - "dependency": { - "type": "object", - "title": "Dependency", - "description": "Defines the direct dependencies of a component. Components that do not have their own dependencies MUST be declared as empty elements within the graph. Components that are not represented in the dependency graph MAY have unknown dependencies. It is RECOMMENDED that implementations assume this to be opaque and not an indicator of a component being dependency-free.", - "required": [ - "ref" - ], - "additionalProperties": false, - "properties": { - "ref": { - "type": "string", - "title": "Reference", - "description": "References a component by the components bom-ref attribute" - }, - "dependsOn": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - }, - "title": "Depends On", - "description": "The bom-ref identifiers of the components that are dependencies of this dependency object." - } - } - }, - "service": { - "type": "object", - "title": "Service Object", - "required": [ - "name" - ], - "additionalProperties": false, - "properties": { - "bom-ref": { - "type": "string", - "title": "BOM Reference", - "description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique." - }, - "provider": { - "title": "Provider", - "description": "The organization that provides the service.", - "$ref": "#/definitions/organizationalEntity" - }, - "group": { - "type": "string", - "title": "Service Group", - "description": "The grouping name, namespace, or identifier. This will often be a shortened, single name of the company or project that produced the service or domain name. Whitespace and special characters should be avoided.", - "examples": ["com.acme"] - }, - "name": { - "type": "string", - "title": "Service Name", - "description": "The name of the service. This will often be a shortened, single name of the service.", - "examples": ["ticker-service"] - }, - "version": { - "type": "string", - "title": "Service Version", - "description": "The service version.", - "examples": ["1.0.0"] - }, - "description": { - "type": "string", - "title": "Service Description", - "description": "Specifies a description for the service" - }, - "endpoints": { - "type": "array", - "items": { - "type": "string", - "format": "iri-reference" - }, - "title": "Endpoints", - "description": "The endpoint URIs of the service. Multiple endpoints are allowed.", - "examples": ["https://example.com/api/v1/ticker"] - }, - "authenticated": { - "type": "boolean", - "title": "Authentication Required", - "description": "A boolean value indicating if the service requires authentication. A value of true indicates the service requires authentication prior to use. A value of false indicates the service does not require authentication." - }, - "x-trust-boundary": { - "type": "boolean", - "title": "Crosses Trust Boundary", - "description": "A boolean value indicating if use of the service crosses a trust zone or boundary. A value of true indicates that by using the service, a trust boundary is crossed. A value of false indicates that by using the service, a trust boundary is not crossed." - }, - "data": { - "type": "array", - "items": {"$ref": "#/definitions/dataClassification"}, - "title": "Data Classification", - "description": "Specifies the data classification." - }, - "licenses": { - "type": "array", - "items": {"$ref": "#/definitions/licenseChoice"}, - "title": "Component License(s)" - }, - "externalReferences": { - "type": "array", - "items": {"$ref": "#/definitions/externalReference"}, - "title": "External References" - }, - "services": { - "$id": "#/properties/services", - "type": "array", - "items": {"$ref": "#/definitions/service"}, - "uniqueItems": true, - "title": "Services" - }, - "properties": { - "type": "array", - "title": "Properties", - "description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values.", - "items": {"$ref": "#/definitions/property"} - } - } - }, - "dataClassification": { - "type": "object", - "title": "Hash Objects", - "required": [ - "flow", - "classification" - ], - "additionalProperties": false, - "properties": { - "flow": { - "$ref": "#/definitions/dataFlow" - }, - "classification": { - "type": "string" - } - } - }, - "dataFlow": { - "type": "string", - "enum": [ - "inbound", - "outbound", - "bi-directional", - "unknown" - ], - "title": "Data flow direction" - }, - - "copyright": { - "type": "object", - "title": "Copyright", - "required": [ - "text" - ], - "additionalProperties": false, - "properties": { - "text": { - "type": "string", - "title": "Copyright Text" - } - } - }, - - "componentEvidence": { - "type": "object", - "title": "Evidence", - "description": "Provides the ability to document evidence collected through various forms of extraction or analysis.", - "additionalProperties": false, - "properties": { - "licenses": { - "type": "array", - "items": {"$ref": "#/definitions/licenseChoice"}, - "title": "Component License(s)" - }, - "copyright": { - "type": "array", - "items": {"$ref": "#/definitions/copyright"}, - "title": "Copyright" - } - } - }, - "compositions": { - "type": "object", - "title": "Compositions", - "required": [ - "aggregate" - ], - "additionalProperties": false, - "properties": { - "aggregate": { - "$ref": "#/definitions/aggregateType", - "title": "Aggregate", - "description": "Specifies an aggregate type that describe how complete a relationship is." - }, - "assemblies": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - }, - "title": "BOM references", - "description": "The bom-ref identifiers of the components or services being described. Assemblies refer to nested relationships whereby a constituent part may include other constituent parts. References do not cascade to child parts. References are explicit for the specified constituent part only." - }, - "dependencies": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string" - }, - "title": "BOM references", - "description": "The bom-ref identifiers of the components or services being described. Dependencies refer to a relationship whereby an independent constituent part requires another independent constituent part. References do not cascade to transitive dependencies. References are explicit for the specified dependency only." - } - } - }, - "aggregateType": { - "type": "string", - "default": "not_specified", - "enum": [ - "complete", - "incomplete", - "incomplete_first_party_only", - "incomplete_third_party_only", - "unknown", - "not_specified" - ] - }, - "property": { - "type": "object", - "title": "Lightweight name-value pair", - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "The name of the property. Duplicate names are allowed, each potentially having a different value." - }, - "value": { - "type": "string", - "title": "Value", - "description": "The value of the property." - } - } - } - } -} \ No newline at end of file diff --git a/cyclonedx/schema/bom-1.3.proto b/cyclonedx/schema/bom-1.3.proto deleted file mode 100644 index 5c9926b2..00000000 --- a/cyclonedx/schema/bom-1.3.proto +++ /dev/null @@ -1,452 +0,0 @@ -syntax = "proto3"; -package cyclonedx.v1_3; -import "google/protobuf/timestamp.proto"; - -// Specifies attributes of the text -message AttachedText { - // Specifies the content type of the text. Defaults to text/plain if not specified. - optional string content_type = 1; - // Specifies the optional encoding the text is represented in - optional string encoding = 2; - // SimpleContent value of element - string value = 3; -} - -message Bom { - // The version of the CycloneDX specification a BOM is written to (starting at version 1.3) - string spec_version = 1; - // The version allows component publishers/authors to make changes to existing BOMs to update various aspects of the document such as description or licenses. When a system is presented with multiple BOMs for the same component, the system should use the most recent version of the BOM. The default version is '1' and should be incremented for each version of the BOM that is published. Each version of a component should have a unique BOM and if no changes are made to the BOMs, then each BOM will have a version of '1'. - optional int32 version = 2; - // Every BOM generated should have a unique serial number, even if the contents of the BOM being generated have not changed over time. The process or tool responsible for creating the BOM should create random UUID's for every BOM generated. - optional string serial_number = 3; - // Provides additional information about a BOM. - optional Metadata metadata = 4; - // Provides the ability to document a list of components. - repeated Component components = 5; - // Provides the ability to document a list of external services. - repeated Service services = 6; - // Provides the ability to document external references related to the BOM or to the project the BOM describes. - repeated ExternalReference external_references = 7; - // Provides the ability to document dependency relationships. - repeated Dependency dependencies = 8; - // Provides the ability to document aggregate completeness - repeated Composition compositions = 9; -} - -enum Classification { - CLASSIFICATION_NULL = 0; - // A software application. Refer to https://en.wikipedia.org/wiki/Application_software for information about applications. - CLASSIFICATION_APPLICATION = 1; - // A software framework. Refer to https://en.wikipedia.org/wiki/Software_framework for information on how frameworks vary slightly from libraries. - CLASSIFICATION_FRAMEWORK = 2; - // A software library. Refer to https://en.wikipedia.org/wiki/Library_(computing) for information about libraries. All third-party and open source reusable components will likely be a library. If the library also has key features of a framework, then it should be classified as a framework. If not, or is unknown, then specifying library is recommended. - CLASSIFICATION_LIBRARY = 3; - // A software operating system without regard to deployment model (i.e. installed on physical hardware, virtual machine, image, etc) Refer to https://en.wikipedia.org/wiki/Operating_system - CLASSIFICATION_OPERATING_SYSTEM = 4; - // A hardware device such as a processor, or chip-set. A hardware device containing firmware should include a component for the physical hardware itself, and another component of type 'firmware' or 'operating-system' (whichever is relevant), describing information about the software running on the device. - CLASSIFICATION_DEVICE = 5; - // A computer file. Refer to https://en.wikipedia.org/wiki/Computer_file for information about files. - CLASSIFICATION_FILE = 6; - // A packaging and/or runtime format, not specific to any particular technology, which isolates software inside the container from software outside of a container through virtualization technology. Refer to https://en.wikipedia.org/wiki/OS-level_virtualization - CLASSIFICATION_CONTAINER = 7; - // A special type of software that provides low-level control over a devices hardware. Refer to https://en.wikipedia.org/wiki/Firmware - CLASSIFICATION_FIRMWARE = 8; -} - -message Commit { - // A unique identifier of the commit. This may be version control specific. For example, Subversion uses revision numbers whereas git uses commit hashes. - optional string uid = 1; - // The URL to the commit. This URL will typically point to a commit in a version control system. - optional string url = 2; - // The author who created the changes in the commit - optional IdentifiableAction author = 3; - // The person who committed or pushed the commit - optional IdentifiableAction committer = 4; - // The text description of the contents of the commit - optional string message = 5; -} - -message Component { - // Specifies the type of component. For software components, classify as application if no more specific appropriate classification is available or cannot be determined for the component. - Classification type = 1; - // The optional mime-type of the component. When used on file components, the mime-type can provide additional context about the kind of file being represented such as an image, font, or executable. Some library or framework components may also have an associated mime-type. - optional string mime_type = 2; - // An optional identifier which can be used to reference the component elsewhere in the BOM. Uniqueness is enforced within all elements and children of the root-level bom element. - optional string bom_ref = 3; - // The organization that supplied the component. The supplier may often be the manufacture, but may also be a distributor or repackager. - optional OrganizationalEntity supplier = 4; - // The person(s) or organization(s) that authored the component - optional string author = 5; - // The person(s) or organization(s) that published the component - optional string publisher = 6; - // The grouping name or identifier. This will often be a shortened, single name of the company or project that produced the component, or the source package or domain name. Whitespace and special characters should be avoided. Examples include: apache, org.apache.commons, and apache.org. - optional string group = 7; - // The name of the component. This will often be a shortened, single name of the component. Examples: commons-lang3 and jquery - string name = 8; - // The component version. The version should ideally comply with semantic versioning but is not enforced. - string version = 9; - // Specifies a description for the component - optional string description = 10; - // Specifies the scope of the component. If scope is not specified, 'runtime' scope should be assumed by the consumer of the BOM - optional Scope scope = 11; - repeated Hash hashes = 12; - repeated LicenseChoice licenses = 13; - // An optional copyright notice informing users of the underlying claims to copyright ownership in a published work. - optional string copyright = 14; - // DEPRECATED - DO NOT USE. This will be removed in a future version. Specifies a well-formed CPE name. See https://nvd.nist.gov/products/cpe - optional string cpe = 15; - // Specifies the package-url (PURL). The purl, if specified, must be valid and conform to the specification defined at: https://github.com/package-url/purl-spec - optional string purl = 16; - // Specifies metadata and content for ISO-IEC 19770-2 Software Identification (SWID) Tags. - optional Swid swid = 17; - // DEPRECATED - DO NOT USE. This will be removed in a future version. Use the pedigree element instead to supply information on exactly how the component was modified. A boolean value indicating is the component has been modified from the original. A value of true indicates the component is a derivative of the original. A value of false indicates the component has not been modified from the original. - optional bool modified = 18; - // Component pedigree is a way to document complex supply chain scenarios where components are created, distributed, modified, redistributed, combined with other components, etc. - optional Pedigree pedigree = 19; - // Provides the ability to document external references related to the component or to the project the component describes. - repeated ExternalReference external_references = 20; - // Specifies optional sub-components. This is not a dependency tree. It provides a way to specify a hierarchical representation of component assemblies, similar to system -> subsystem -> parts assembly in physical supply chains. - repeated Component components = 21; - // Specifies optional, custom, properties - repeated Property properties = 22; - // Specifies optional license and copyright evidence - repeated Evidence evidence = 23; -} - -// Specifies the data classification. -message DataClassification { - // Specifies the flow direction of the data. - DataFlow flow = 1; - // SimpleContent value of element - string value = 2; -} - -// Specifies the flow direction of the data. Valid values are: inbound, outbound, bi-directional, and unknown. Direction is relative to the service. Inbound flow states that data enters the service. Outbound flow states that data leaves the service. Bi-directional states that data flows both ways, and unknown states that the direction is not known. -enum DataFlow { - DATA_FLOW_NULL = 0; - DATA_FLOW_INBOUND = 1; - DATA_FLOW_OUTBOUND = 2; - DATA_FLOW_BI_DIRECTIONAL = 3; - DATA_FLOW_UNKNOWN = 4; -} - -message Dependency { - // References a component or service by the its bom-ref attribute - string ref = 1; - repeated Dependency dependencies = 2; -} - -message Diff { - // Specifies the optional text of the diff - optional AttachedText text = 1; - // Specifies the URL to the diff - optional string url = 2; -} - -message ExternalReference { - // Specifies the type of external reference. There are built-in types to describe common references. If a type does not exist for the reference being referred to, use the "other" type. - ExternalReferenceType type = 1; - // The URL to the external reference - string url = 2; - // An optional comment describing the external reference - optional string comment = 3; - // Optional integrity hashes for the external resource content - repeated Hash hashes = 4; -} - -enum ExternalReferenceType { - // Use this if no other types accurately describe the purpose of the external reference - EXTERNAL_REFERENCE_TYPE_OTHER = 0; - // Version Control System - EXTERNAL_REFERENCE_TYPE_VCS = 1; - // Issue or defect tracking system, or an Application Lifecycle Management (ALM) system - EXTERNAL_REFERENCE_TYPE_ISSUE_TRACKER = 2; - // Website - EXTERNAL_REFERENCE_TYPE_WEBSITE = 3; - // Security advisories - EXTERNAL_REFERENCE_TYPE_ADVISORIES = 4; - // Bill-of-material document (CycloneDX, SPDX, SWID, etc) - EXTERNAL_REFERENCE_TYPE_BOM = 5; - // Mailing list or discussion group - EXTERNAL_REFERENCE_TYPE_MAILING_LIST = 6; - // Social media account - EXTERNAL_REFERENCE_TYPE_SOCIAL = 7; - // Real-time chat platform - EXTERNAL_REFERENCE_TYPE_CHAT = 8; - // Documentation, guides, or how-to instructions - EXTERNAL_REFERENCE_TYPE_DOCUMENTATION = 9; - // Community or commercial support - EXTERNAL_REFERENCE_TYPE_SUPPORT = 10; - // Direct or repository download location - EXTERNAL_REFERENCE_TYPE_DISTRIBUTION = 11; - // The URL to the license file. If a license URL has been defined in the license node, it should also be defined as an external reference for completeness - EXTERNAL_REFERENCE_TYPE_LICENSE = 12; - // Build-system specific meta file (i.e. pom.xml, package.json, .nuspec, etc) - EXTERNAL_REFERENCE_TYPE_BUILD_META = 13; - // URL to an automated build system - EXTERNAL_REFERENCE_TYPE_BUILD_SYSTEM = 14; -} - -enum HashAlg { - HASH_ALG_NULL = 0; - HASH_ALG_MD_5 = 1; - HASH_ALG_SHA_1 = 2; - HASH_ALG_SHA_256 = 3; - HASH_ALG_SHA_384 = 4; - HASH_ALG_SHA_512 = 5; - HASH_ALG_SHA_3_256 = 6; - HASH_ALG_SHA_3_384 = 7; - HASH_ALG_SHA_3_512 = 8; - HASH_ALG_BLAKE_2_B_256 = 9; - HASH_ALG_BLAKE_2_B_384 = 10; - HASH_ALG_BLAKE_2_B_512 = 11; - HASH_ALG_BLAKE_3 = 12; -} - -// Specifies the file hash of the component -message Hash { - // Specifies the algorithm used to create the hash - HashAlg alg = 1; - // SimpleContent value of element - string value = 2; -} - -message IdentifiableAction { - // The timestamp in which the action occurred - optional google.protobuf.Timestamp timestamp = 1; - // The name of the individual who performed the action - optional string name = 2; - // The email address of the individual who performed the action - optional string email = 3; -} - -enum IssueClassification { - ISSUE_CLASSIFICATION_NULL = 0; - // A fault, flaw, or bug in software - ISSUE_CLASSIFICATION_DEFECT = 1; - // A new feature or behavior in software - ISSUE_CLASSIFICATION_ENHANCEMENT = 2; - // A special type of defect which impacts security - ISSUE_CLASSIFICATION_SECURITY = 3; -} - -message Issue { - // Specifies the type of issue - IssueClassification type = 1; - // The identifier of the issue assigned by the source of the issue - optional string id = 2; - // The name of the issue - optional string name = 3; - // A description of the issue - optional string description = 4; - optional Source source = 5; - repeated string references = 6; -} - -// The source of the issue where it is documented. -message Source { - // The name of the source. For example "National Vulnerability Database", "NVD", and "Apache" - optional string name = 1; - // The url of the issue documentation as provided by the source - optional string url = 2; -} - -message LicenseChoice { - oneof choice { - License license = 1; - string expression = 2; - } -} - -message License { - oneof license { - // A valid SPDX license ID - string id = 1; - // If SPDX does not define the license used, this field may be used to provide the license name - string name = 2; - } - // Specifies the optional full text of the attachment - optional AttachedText text = 3; - // The URL to the attachment file. If the attachment is a license or BOM, an externalReference should also be specified for completeness. - optional string url = 4; -} - -message Metadata { - // The date and time (timestamp) when the document was created. - optional google.protobuf.Timestamp timestamp = 1; - // The tool(s) used in the creation of the BOM. - repeated Tool tools = 2; - // The person(s) who created the BOM. Authors are common in BOMs created through manual processes. BOMs created through automated means may not have authors. - repeated OrganizationalContact authors = 3; - // The component that the BOM describes. - optional Component component = 4; - // The organization that manufactured the component that the BOM describes. - optional OrganizationalEntity manufacture = 5; - // The organization that supplied the component that the BOM describes. The supplier may often be the manufacture, but may also be a distributor or repackager. - optional OrganizationalEntity supplier = 6; - // The license information for the BOM document - optional LicenseChoice licenses = 7; - // Specifies optional, custom, properties - repeated Property properties = 8; -} - -message OrganizationalContact { - // The name of the contact - optional string name = 1; - // The email address of the contact. - optional string email = 2; - // The phone number of the contact. - optional string phone = 3; -} - -message OrganizationalEntity { - // The name of the organization - optional string name = 1; - // The URL of the organization. Multiple URLs are allowed. - repeated string url = 2; - // A contact person at the organization. Multiple contacts are allowed. - repeated OrganizationalContact contact = 3; -} - -enum PatchClassification { - PATCH_CLASSIFICATION_NULL = 0; - // A patch which is not developed by the creators or maintainers of the software being patched. Refer to https://en.wikipedia.org/wiki/Unofficial_patch - PATCH_CLASSIFICATION_UNOFFICIAL = 1; - // A patch which dynamically modifies runtime behavior. Refer to https://en.wikipedia.org/wiki/Monkey_patch - PATCH_CLASSIFICATION_MONKEY = 2; - // A patch which takes code from a newer version of software and applies it to older versions of the same software. Refer to https://en.wikipedia.org/wiki/Backporting - PATCH_CLASSIFICATION_BACKPORT = 3; - // A patch created by selectively applying commits from other versions or branches of the same software. - PATCH_CLASSIFICATION_CHERRY_PICK = 4; -} - -message Patch { - // Specifies the purpose for the patch including the resolution of defects, security issues, or new behavior or functionality - PatchClassification type = 1; - // The patch file (or diff) that show changes. Refer to https://en.wikipedia.org/wiki/Diff - optional Diff diff = 2; - repeated Issue resolves = 3; -} - -// Component pedigree is a way to document complex supply chain scenarios where components are created, distributed, modified, redistributed, combined with other components, etc. Pedigree supports viewing this complex chain from the beginning, the end, or anywhere in the middle. It also provides a way to document variants where the exact relation may not be known. -message Pedigree { - // Describes zero or more components in which a component is derived from. This is commonly used to describe forks from existing projects where the forked version contains a ancestor node containing the original component it was forked from. For example, Component A is the original component. Component B is the component being used and documented in the BOM. However, Component B contains a pedigree node with a single ancestor documenting Component A - the original component from which Component B is derived from. - repeated Component ancestors = 1; - // Descendants are the exact opposite of ancestors. This provides a way to document all forks (and their forks) of an original or root component. - repeated Component descendants = 2; - // Variants describe relations where the relationship between the components are not known. For example, if Component A contains nearly identical code to Component B. They are both related, but it is unclear if one is derived from the other, or if they share a common ancestor. - repeated Component variants = 3; - // A list of zero or more commits which provide a trail describing how the component deviates from an ancestor, descendant, or variant. - repeated Commit commits = 4; - // A list of zero or more patches describing how the component deviates from an ancestor, descendant, or variant. Patches may be complimentary to commits or may be used in place of commits. - repeated Patch patches = 5; - // Notes, observations, and other non-structured commentary describing the components pedigree. - optional string notes = 6; -} - -enum Scope { - // Default - SCOPE_UNSPECIFIED = 0; - // The component is required for runtime - SCOPE_REQUIRED = 1; - // The component is optional at runtime. Optional components are components that are not capable of being called due to them not be installed or otherwise accessible by any means. Components that are installed but due to configuration or other restrictions are prohibited from being called must be scoped as 'required'. - SCOPE_OPTIONAL = 2; - // Components that are excluded provide the ability to document component usage for test and other non-runtime purposes. Excluded components are not reachable within a call graph at runtime. - SCOPE_EXCLUDED = 3; -} - -message Service { - // An optional identifier which can be used to reference the service elsewhere in the BOM. Uniqueness is enforced within all elements and children of the root-level bom element. - optional string bom_ref = 1; - // The organization that provides the service. - optional OrganizationalEntity provider = 2; - // The grouping name, namespace, or identifier. This will often be a shortened, single name of the company or project that produced the service or domain name. Whitespace and special characters should be avoided. - optional string group = 3; - // The name of the service. This will often be a shortened, single name of the service. - string name = 4; - // The service version. - optional string version = 5; - // Specifies a description for the service. - optional string description = 6; - repeated string endpoints = 7; - // A boolean value indicating if the service requires authentication. A value of true indicates the service requires authentication prior to use. A value of false indicates the service does not require authentication. - optional bool authenticated = 8; - // A boolean value indicating if use of the service crosses a trust zone or boundary. A value of true indicates that by using the service, a trust boundary is crossed. A value of false indicates that by using the service, a trust boundary is not crossed. - optional bool x_trust_boundary = 9; - repeated DataClassification data = 10; - repeated LicenseChoice licenses = 11; - // Provides the ability to document external references related to the service. - repeated ExternalReference external_references = 12; - // Specifies optional sub-service. This is not a dependency tree. It provides a way to specify a hierarchical representation of service assemblies, similar to system -> subsystem -> parts assembly in physical supply chains. - repeated Service services = 13; - // Specifies optional, custom, properties - repeated Property properties = 14; -} - -message Swid { - // Maps to the tagId of a SoftwareIdentity. - string tag_id = 1; - // Maps to the name of a SoftwareIdentity. - string name = 2; - // Maps to the version of a SoftwareIdentity. - optional string version = 3; - // Maps to the tagVersion of a SoftwareIdentity. - optional int32 tag_version = 4; - // Maps to the patch of a SoftwareIdentity. - optional bool patch = 5; - // Specifies the full content of the SWID tag. - optional AttachedText text = 6; - // The URL to the SWID file. - optional string url = 7; -} - -// Specifies a tool (manual or automated). -message Tool { - // The vendor of the tool used to create the BOM. - optional string vendor = 1; - // The name of the tool used to create the BOM. - optional string name = 2; - // The version of the tool used to create the BOM. - optional string version = 3; - repeated Hash hashes = 4; -} - -// Specifies a property -message Property { - string name = 1; - optional string value = 2; -} - -enum Aggregate { - // Default, no statement about the aggregate completeness is being made - AGGREGATE_NOT_SPECIFIED = 0; - // The aggregate composition is complete - AGGREGATE_COMPLETE = 1; - // The aggregate composition is incomplete - AGGREGATE_INCOMPLETE = 2; - // The aggregate composition is incomplete for first party components, complete for third party components - AGGREGATE_INCOMPLETE_FIRST_PARTY_ONLY = 3; - // The aggregate composition is incomplete for third party components, complete for first party components - AGGREGATE_INCOMPLETE_THIRD_PARTY_ONLY = 4; - // The aggregate composition completeness is unknown - AGGREGATE_UNKNOWN = 5; -} - -message Composition { - // Indicates the aggregate completeness - Aggregate aggregate = 1; - // The assemblies the aggregate completeness applies to - repeated string assemblies = 2; - // The dependencies the aggregate completeness applies to - repeated string dependencies = 3; -} - -message EvidenceCopyright { - // Copyright text - string text = 1; -} - -message Evidence { - repeated LicenseChoice licenses = 1; - repeated EvidenceCopyright copyright = 2; -} diff --git a/cyclonedx/schema/ext/bom-descriptor-0.9.xsd b/cyclonedx/schema/ext/bom-descriptor-0.9.xsd deleted file mode 100644 index 605df12f..00000000 --- a/cyclonedx/schema/ext/bom-descriptor-0.9.xsd +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - CycloneDX BOM Descriptor Extension - https://cyclonedx.org/ext/bom-descriptor - Apache License, Version 2.0 - - Steve Springett - - - - - - - - - Specifies the name of the software the BOM describes. - - - - - Specifies the version of the software the BOM describes. - - - - - Specifies the edition of the software the BOM describes. - - - - - - - - - - - - - - - - A valid SPDX license expression. - Refer to https://spdx.org/specifications for syntax requirements - - - - - - - - An optional copyright notice informing users of the underlying claims to - copyright ownership in a published work. - - - - - - Specifies a well-formed CPE name. See https://nvd.nist.gov/products/cpe - - - - - - - Specifies the package-url (PURL). The purl, if specified, must be valid and conform - to the specification defined at: https://github.com/package-url/purl-spec - - - - - - The organization that manufactured the software for which the BOM describes. - - - - - The organization that supplied the software for which the BOM describes. The - supplier may often be the manufacture, but may also be a distributor or repackager. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - - - The name of the organization - - - - - The URL of the organization. Multiple URLs are allowed. - - - - - A contact person at the organization. Multiple contacts are allowed. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - - - The name of the person - - - - - The email address of the person. Multiple email addresses are allowed. - - - - - The phone number of the person. Multiple phone numbers are allowed. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - Provides additional information about a BOM. - - - - diff --git a/cyclonedx/schema/ext/bom-descriptor-1.0.xsd b/cyclonedx/schema/ext/bom-descriptor-1.0.xsd deleted file mode 100644 index 013f550e..00000000 --- a/cyclonedx/schema/ext/bom-descriptor-1.0.xsd +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - CycloneDX BOM Descriptor Extension - https://cyclonedx.org/ext/bom-descriptor - Apache License, Version 2.0 - - Steve Springett - - - - - - - - - - - The date and time (timestamp) when the document was created. - - - - - The tool used to create the BOM. - - - - - The person(s) who created the BOM. Authors are common in BOMs created through - manual processes. BOMs created through automated means may not have authors. - - - - - - - - - - The component that the BOM describes. - - - - - The organization that manufactured the component that the BOM describes. - - - - - The organization that supplied the component that the BOM describes. The - supplier may often be the manufacture, but may also be a distributor or repackager. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - - - The name of the organization - - - - - The URL of the organization. Multiple URLs are allowed. - - - - - A contact person at the organization. Multiple contacts are allowed. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - Specifies a tool (manual or automated). - - - - - The vendor of the tool used to create the BOM. - - - - - The name of the tool used to create the BOM. - - - - - The version of the tool used to create the BOM. - - - - - - - - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - - - The name of the person - - - - - The email address of the person. Multiple email addresses are allowed. - - - - - The phone number of the person. Multiple phone numbers are allowed. - - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - Provides additional information about a BOM. - - - - diff --git a/cyclonedx/schema/ext/dependency-graph-1.0.xsd b/cyclonedx/schema/ext/dependency-graph-1.0.xsd deleted file mode 100644 index ddcb5365..00000000 --- a/cyclonedx/schema/ext/dependency-graph-1.0.xsd +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - CycloneDX Dependency Graph Extension - https://cyclonedx.org/ext/dependency-graph - Apache License, Version 2.0 - - Steve Springett - - - - - - - - - - - References a component by the components bom-ref attribute - - - - - User-defined attributes may be used on this element as long as they - do not have the same name as an existing attribute used by the schema. - - - - - - - - - - Components that do not have their own dependencies MUST be declared as empty - elements within the graph. Components that are not represented in the dependency graph MAY - have unknown dependencies. It is RECOMMENDED that implementations assume this to be opaque - and not an indicator of a component being dependency-free. - - - - - - - diff --git a/cyclonedx/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json b/cyclonedx/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json deleted file mode 100644 index 378bd498..00000000 --- a/cyclonedx/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://cyclonedx.org/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json", - "type": "object", - "title": "CycloneDX Vulnerability Extension", - "$comment" : "CycloneDX Vulnerability Extension for JSON Schema is published under the terms of the Apache License 2.0.", - "properties": { - "vulnerabilities": { - "$id": "#/properties/vulnerabilities", - "type": "array", - "items": {"$ref": "#/definitions/vulnerability"}, - "title": "Vulnerabilities", - "description": "Defines a list of vulnerabilities." - } - }, - "definitions": { - "cwe": { - "type": "integer", - "minimum": 1, - "title": "CWE", - "description": "Integer representation of a Common Weaknesses Enumerations (CWE). For example 399 (of https://cwe.mitre.org/data/definitions/399.html)" - }, - "severity": { - "type": "string", - "title": "Severity", - "description": "Textual representation of the severity of the vulnerability adopted by the risk analysis method. If an other risk analysis method is used other than whats defined in scoreSourceType, the user is expected to translate appropriately to match with an element value below.", - "enum": [ - "None", - "Low", - "Medium", - "High", - "Critical", - "Unknown" - ] - }, - "scoreValue": { - "type": "number", - "title": "Score", - "description": "Numerical representation of the vulnerability score. Must be a number between 0 - 10 (maps to lowest severity - highest severity)", - "multipleOf": 0.1, - "examples": [7.9, 10.0] - }, - "scoreSource": { - "type": "string", - "title": "Source", - "description": "Specifies the risk scoring methodology/standard used.", - "enum": [ - "CVSSv2", - "CVSSv3", - "OWASP Risk", - "Open FAIR", - "Other" - ] - }, - "score": { - "type": "object", - "title": "Score", - "description": "Defines the numerical risk score of a vulnerability", - "properties": { - "base": { - "type": "number", - "title": "Base Score", - "description": "The base score of the security vulnerability (Refer CVSS standard for example)", - "multipleOf": 0.1, - "examples": [2.9, 7.2] - }, - "impact": { - "type": "number", - "title": "Impact Score", - "description": "The impact subscore of the security vulnerability (Refer CVSS standard for example)", - "multipleOf": 0.1, - "examples": [2.9, 7.2] - }, - "exploitability": { - "type": "number", - "title": "Exploitability Score", - "description": "The exploitability subscore of the security vulnerability (Refer CVSS standard for example)", - "multipleOf": 0.1, - "examples": [2.9, 7.2] - } - } - }, - "rating": { - "type": "object", - "title": "Rating", - "description": "Defines the risk rating of a vulnerability.", - "properties": { - "score": { - "$ref": "#/definitions/score" - }, - "severity": { - "$ref": "#/definitions/severity" - }, - "method": { - "$ref": "#/definitions/scoreSource" - }, - "vector": { - "type": "string", - "title": "Vector", - "description": "Textual representation of the metric values used to score the vulnerability see attack vector in https://www.first.org/cvss/v3.1/specification-document" - } - } - }, - "source": { - "type": "object", - "title": "Source", - "description": "The source of the vulnerability where it is documented. Usually the name of the organization publishing vulnerability information", - "properties": { - "url": { - "type": "string", - "title": "URL", - "description": "The url of the vulnerability documentation as provided by the source.", - "examples": [ - "https://nvd.nist.gov/vuln/detail/CVE-2019-15842" - ] - }, - "name": { - "type": "string", - "title": "Name", - "description": "The name of the source.", - "examples": [ - "NVD", "National Vulnerability Database", "OSS Index", "VulnDB", "NPM Advisories" - ] - } - } - }, - "vulnerability": { - "type": "object", - "title": "Vulnerability", - "description": "Defines the structure of a vulnerability.", - "properties": { - "ref": { - "type": "string", - "format": "string", - "title": "Reference", - "description": "References a component by the components bom-ref attribute" - }, - "id": { - "type": "string", - "title": "ID", - "description": "The id of the vulnerability as defined by the risk scoring methodology. For example CVE-2019-15842 (of https://nvd.nist.gov/vuln/detail/CVE-2019-15842)" - }, - "source": { - "$ref": "#/definitions/source" - }, - "ratings": { - "type": "array", - "title": "Ratings", - "description": "List of the vulnerability ratings as defined by various risk rating methodologies.", - "items": {"$ref": "#/definitions/rating"} - }, - "cwes": { - "type": "array", - "title": "CWEs", - "description": "List of Common Weaknesses Enumerations (CWEs) codes that describes this vulnerability. For example 399 (of https://cwe.mitre.org/data/definitions/399.html)", - "items": {"$ref": "#/definitions/cwe"} - }, - "description": { - "type": "string", - "title": "Description", - "description": "Description of the vulnerability as provided by the source organization" - }, - "recommendations": { - "type": "array", - "title": "Recommendations", - "description": "List of recommendations of how the particular vulnerability can be avoided/mitigated.", - "items": { - "type": "string" - } - }, - "advisories": { - "type": "array", - "title": "Advisories", - "description": "Published advisories of the vulnerability if provided.", - "items": { - "type": "string" - } - } - } - } - } -} diff --git a/cyclonedx/schema/ext/vulnerability-1.0.xsd b/cyclonedx/schema/ext/vulnerability-1.0.xsd deleted file mode 100644 index 2d684745..00000000 --- a/cyclonedx/schema/ext/vulnerability-1.0.xsd +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - - CycloneDX Vulnerability Extension - https://cyclonedx.org/ext/vulnerability - Apache License, Version 2.0 - - - - - - - Textual representation of the severity of the vulnerability adopted by the risk analysis method. - If an other risk analysis method is used other than whats defined in scoreSourceType, - the user is expected to translate appropriately to match with an element value below. - - - - - - - - - - - - - - - - Numerical representation of the vulnerability score. - Must be a number between 0 - 10 (maps to lowest severity - highest severity) - - - - - - - - - - - - - Specifies the risk scoring methodology/standard used. - - - - - - - The rating is based on CVSS v2 standard - https://www.first.org/cvss/v2/guide - - - - - - - The rating is based on CVSS v3 standard - https://www.first.org/cvss/v3.1/specification-document - - - - - - - The rating is based on OWASP Risk Rating - https://www.owasp.org/index.php/OWASP_Risk_Rating_Methodology - - - - - - - The rating is based on Open FAIR specification - http://www.opengroup.org/subjectareas/security/risk - - - - - - - Use this if the risk scoring methodology is not based on any of the options above - - - - - - - - - - Defines the numerical risk score of a vulnerability - - - - - - - - - - The base score of the security vulnerability (Refer CVSS standard for example) - - - - - - - The impact subscore of the security vulnerability (Refer CVSS standard for example) - - - - - - - The exploitability subscore of the security vulnerability (Refer CVSS standard for - example) - - - - - - - - - - - - Textual representation of the metric values used to score the vulnerability - see attack vector in https://www.first.org/cvss/v3.1/specification-document - - - - - - - - - - Defines the structure of a vulnerability. - - - - - - - The id of the vulnerability as defined by the risk scoring methodology - For example CVE-2019-15842 (of https://nvd.nist.gov/vuln/detail/CVE-2019-15842) - - - - - - - - The source of the vulnerability where it is documented. - Usually the name of the organization publishing vulnerability information - - - - - - - The url of the vulnerability documentation as provided by the source - For example https://nvd.nist.gov/vuln/detail/CVE-2019-15842 - - - - - - - - The name of the source. For example "National Vulnerability Database" - - - - - - - - - List of the vulnerability ratings as defined by various risk rating methodologies. - - - - - - - - - - - - - List of Common Weaknesses Enumerations (CWEs) codes that describes this vulnerability. - For example 399 (of https://cwe.mitre.org/data/definitions/399.html) - - - - - - - - - - - Description of the vulnerability as provided by the source organization - - - - - - - - The remediation options for the vulnerability if available - - - - - - - A recommendation of how the particular vulnerability can be avoided/mitigated. - - - - - - - - - - - Published advisories of the vulnerability if provided - - - - - - - - - - - References a component by the components bom-ref attribute - - - - - - - - Defines a list of vulnerabilities. - Vulnerabilities are intended to be used inside the BOM component element. - Extending a component ability to declare associated vulnerability information. - Each component element optionally can add a vulnerabilities element. - - - - - - - - - diff --git a/cyclonedx/schema/schema.py b/cyclonedx/schema/schema.py index 248376a5..84434212 100644 --- a/cyclonedx/schema/schema.py +++ b/cyclonedx/schema/schema.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +16,7 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. from abc import ABC, abstractmethod +from typing import Dict, Literal, Type from serializable import ViewType @@ -29,7 +28,7 @@ class BaseSchemaVersion(ABC, ViewType): @property @abstractmethod def schema_version_enum(self) -> SchemaVersion: - pass + ... def get_schema_version(self) -> str: return self.schema_version_enum.to_version() @@ -38,42 +37,42 @@ def get_schema_version(self) -> str: class SchemaVersion1Dot4(BaseSchemaVersion): @property - def schema_version_enum(self) -> SchemaVersion: + def schema_version_enum(self) -> Literal[SchemaVersion.V1_4]: return SchemaVersion.V1_4 class SchemaVersion1Dot3(BaseSchemaVersion): @property - def schema_version_enum(self) -> SchemaVersion: + def schema_version_enum(self) -> Literal[SchemaVersion.V1_3]: return SchemaVersion.V1_3 class SchemaVersion1Dot2(BaseSchemaVersion): @property - def schema_version_enum(self) -> SchemaVersion: + def schema_version_enum(self) -> Literal[SchemaVersion.V1_2]: return SchemaVersion.V1_2 class SchemaVersion1Dot1(BaseSchemaVersion): @property - def schema_version_enum(self) -> SchemaVersion: + def schema_version_enum(self) -> Literal[SchemaVersion.V1_1]: return SchemaVersion.V1_1 class SchemaVersion1Dot0(BaseSchemaVersion): @property - def schema_version_enum(self) -> SchemaVersion: + def schema_version_enum(self) -> Literal[SchemaVersion.V1_0]: return SchemaVersion.V1_0 -SCHEMA_VERSIONS = { - '1.0': SchemaVersion1Dot0, - '1.1': SchemaVersion1Dot1, - '1.2': SchemaVersion1Dot2, - '1.3': SchemaVersion1Dot3, - '1.4': SchemaVersion1Dot4 +SCHEMA_VERSIONS: Dict[SchemaVersion, Type[BaseSchemaVersion]] = { + SchemaVersion.V1_4: SchemaVersion1Dot4, + SchemaVersion.V1_3: SchemaVersion1Dot3, + SchemaVersion.V1_2: SchemaVersion1Dot2, + SchemaVersion.V1_1: SchemaVersion1Dot1, + SchemaVersion.V1_0: SchemaVersion1Dot0, } diff --git a/cyclonedx/serialization/__init__.py b/cyclonedx/serialization/__init__.py index 7e84379e..720ee94d 100644 --- a/cyclonedx/serialization/__init__.py +++ b/cyclonedx/serialization/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,31 +11,40 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + """ Set of helper classes for use with ``serializable`` when conducting (de-)serialization. """ +from json import loads as json_loads +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type from uuid import UUID +from xml.etree.ElementTree import Element # nosec B405 # See https://github.com/package-url/packageurl-python/issues/65 from packageurl import PackageURL from serializable.helpers import BaseHelper from ..model.bom_ref import BomRef +from ..model.license import DisjunctiveLicense, LicenseExpression, LicenseRepository + +if TYPE_CHECKING: # pragma: no cover + from serializable import ViewType class BomRefHelper(BaseHelper): @classmethod - def serialize(cls, o: object) -> str: + def serialize(cls, o: Any) -> str: if isinstance(o, BomRef): return o.value raise ValueError(f'Attempt to serialize a non-BomRef: {o.__class__}') @classmethod - def deserialize(cls, o: object) -> BomRef: + def deserialize(cls, o: Any) -> BomRef: try: return BomRef(value=str(o)) except ValueError: @@ -47,14 +54,14 @@ def deserialize(cls, o: object) -> BomRef: class PackageUrl(BaseHelper): @classmethod - def serialize(cls, o: object) -> str: + def serialize(cls, o: Any, ) -> str: if isinstance(o, PackageURL): return str(o.to_string()) raise ValueError(f'Attempt to serialize a non-PackageURL: {o.__class__}') @classmethod - def deserialize(cls, o: object) -> PackageURL: + def deserialize(cls, o: Any) -> PackageURL: try: return PackageURL.from_string(purl=str(o)) except ValueError: @@ -64,15 +71,81 @@ def deserialize(cls, o: object) -> PackageURL: class UrnUuidHelper(BaseHelper): @classmethod - def serialize(cls, o: object) -> str: + def serialize(cls, o: Any) -> str: if isinstance(o, UUID): return o.urn raise ValueError(f'Attempt to serialize a non-UUID: {o.__class__}') @classmethod - def deserialize(cls, o: object) -> UUID: + def deserialize(cls, o: Any) -> UUID: try: return UUID(str(o)) except ValueError: raise ValueError(f'UUID string supplied ({o}) does not parse!') + + +class LicenseRepositoryHelper(BaseHelper): + @classmethod + def json_normalize(cls, o: LicenseRepository, *, + view: Optional[Type['ViewType']], + **__: Any) -> Any: + if len(o) == 0: + return None + expression = next((li for li in o if isinstance(li, LicenseExpression)), None) + if expression: + # mixed license expression and license? this is an invalid constellation according to schema! + # see https://github.com/CycloneDX/specification/pull/205 + # but models need to allow it for backwards compatibility with JSON CDX < 1.5 + return [{'expression': str(expression.value)}] + return [{'license': json_loads(li.as_json( # type:ignore[union-attr] + view_=view))} for li in o] + + @classmethod + def json_denormalize(cls, o: List[Dict[str, Any]], + **__: Any) -> LicenseRepository: + repo = LicenseRepository() + for li in o: + if 'license' in li: + repo.add(DisjunctiveLicense.from_json( # type:ignore[attr-defined] + li['license'])) + elif 'expression' in li: + repo.add(LicenseExpression(li['expression'])) + return repo + + @classmethod + def xml_normalize(cls, o: LicenseRepository, *, + element_name: str, + view: Optional[Type['ViewType']], + xmlns: Optional[str], + **__: Any) -> Optional[Element]: + if len(o) == 0: + return None + elem = Element(element_name) + expression = next((li for li in o if isinstance(li, LicenseExpression)), None) + if expression: + # mixed license expression and license? this is an invalid constellation according to schema! + # see https://github.com/CycloneDX/specification/pull/205 + # but models need to allow it for backwards compatibility with JSON CDX < 1.5 + elem.append(expression.as_xml( # type:ignore[attr-defined] + view, as_string=False, element_name='expression', xmlns=xmlns)) + else: + for li in o: + elem.append(li.as_xml( # type:ignore[union-attr] + view, as_string=False, element_name='license', xmlns=xmlns)) + return elem + + @classmethod + def xml_denormalize(cls, o: Element, + default_ns: Optional[str], + **__: Any) -> LicenseRepository: + repo = LicenseRepository() + for li in o: + tag = li.tag if default_ns is None else li.tag.replace(f'{{{default_ns}}}', '') + if tag == 'license': + repo.add(DisjunctiveLicense.from_xml( # type:ignore[attr-defined] + li, default_ns)) + elif tag == 'expression': + repo.add(LicenseExpression.from_xml( # type:ignore[attr-defined] + li, default_ns)) + return repo diff --git a/cyclonedx/spdx.py b/cyclonedx/spdx.py index 593c133e..be74bd0c 100644 --- a/cyclonedx/spdx.py +++ b/cyclonedx/spdx.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -13,6 +11,8 @@ # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + __all__ = [ 'is_supported_id', 'fixup_id', @@ -20,19 +20,20 @@ ] from json import load as json_load -from os.path import dirname, join as path_join from typing import TYPE_CHECKING, Dict, Optional, Set from license_expression import get_spdx_licensing # type: ignore -if TYPE_CHECKING: +from .schema._res import SPDX_JSON as __SPDX_JSON_SCHEMA + +if TYPE_CHECKING: # pragma: no cover from license_expression import Licensing # region init # python's internal module loader will assure that this init-part runs only once. # !!! this requires to ship the actual schema data with the package. -with open(path_join(dirname(__file__), 'schema', 'spdx.schema.json')) as schema: +with open(__SPDX_JSON_SCHEMA) as schema: __IDS: Set[str] = set(json_load(schema).get('enum', [])) assert len(__IDS) > 0, 'known SPDX-IDs should be non-empty set' diff --git a/cyclonedx/validation/__init__.py b/cyclonedx/validation/__init__.py new file mode 100644 index 00000000..b7dda3f1 --- /dev/null +++ b/cyclonedx/validation/__init__.py @@ -0,0 +1,119 @@ +# 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. + + +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING, Any, Literal, Optional, Protocol, Union, overload + +from ..schema import OutputFormat + +if TYPE_CHECKING: # pragma: no cover + from ..schema import SchemaVersion + from .json import JsonValidator + from .xml import XmlValidator + + +class ValidationError: + """Validation failed with this specific error. + + Use :attr:`~data` to access the content. + """ + + data: Any + + def __init__(self, data: Any) -> None: + self.data = data + + def __repr__(self) -> str: + return repr(self.data) + + def __str__(self) -> str: + return str(self.data) + + +class SchemabasedValidator(Protocol): + """Schema-based Validator protocol""" + + def validate_str(self, data: str) -> Optional[ValidationError]: + """Validate a string + + :param data: the data string to validate + :return: validation error + :retval None: if `data` is valid + :retval ValidationError: if `data` is invalid + """ + ... + + +class BaseSchemabasedValidator(ABC, SchemabasedValidator): + """Base Schema-based Validator""" + + def __init__(self, schema_version: 'SchemaVersion') -> None: + self.__schema_version = schema_version + if not self._schema_file: + raise ValueError(f'Unsupported schema_version: {schema_version!r}') + + @property + def schema_version(self) -> 'SchemaVersion': + """get the schema version.""" + return self.__schema_version + + @property + @abstractmethod + def output_format(self) -> OutputFormat: + """get the format.""" + ... + + @property + @abstractmethod + def _schema_file(self) -> Optional[str]: + """get the schema file according to schema version.""" + ... + + +@overload +def make_schemabased_validator(output_format: Literal[OutputFormat.JSON], schema_version: 'SchemaVersion' + ) -> 'JsonValidator': + ... + + +@overload +def make_schemabased_validator(output_format: Literal[OutputFormat.XML], schema_version: 'SchemaVersion' + ) -> 'XmlValidator': + ... + + +@overload +def make_schemabased_validator(output_format: OutputFormat, schema_version: 'SchemaVersion' + ) -> Union['JsonValidator', 'XmlValidator']: + ... + + +def make_schemabased_validator(output_format: OutputFormat, schema_version: 'SchemaVersion' + ) -> 'BaseSchemabasedValidator': + """get the default Schema-based Validator for a certain :class:``OutputFormat``. + + Raises error when no instance could be made. + """ + if TYPE_CHECKING: # pragma: no cover + from typing import Type + Validator: Type[BaseSchemabasedValidator] # noqa:N806 + if OutputFormat.JSON is output_format: + from .json import JsonValidator as Validator + elif OutputFormat.XML is output_format: + from .xml import XmlValidator as Validator + else: + raise ValueError(f'Unexpected output_format: {output_format!r}') + return Validator(schema_version) diff --git a/cyclonedx/validation/json.py b/cyclonedx/validation/json.py new file mode 100644 index 00000000..8a7dab8a --- /dev/null +++ b/cyclonedx/validation/json.py @@ -0,0 +1,117 @@ +# 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. + + +__all__ = ['JsonValidator', 'JsonStrictValidator'] + +from abc import ABC +from json import loads as json_loads +from typing import TYPE_CHECKING, Any, Literal, Optional, Tuple + +from ..schema import OutputFormat + +if TYPE_CHECKING: # pragma: no cover + from ..schema import SchemaVersion + +from ..exception import MissingOptionalDependencyException +from ..schema._res import BOM_JSON as _S_BOM, BOM_JSON_STRICT as _S_BOM_STRICT, JSF as _S_JSF, SPDX_JSON as _S_SPDX +from . import BaseSchemabasedValidator, SchemabasedValidator, ValidationError + +_missing_deps_error: Optional[Tuple[MissingOptionalDependencyException, ImportError]] = None +try: + from jsonschema.exceptions import ValidationError as JsonValidationError # type:ignore[import-untyped] + from jsonschema.validators import Draft7Validator # type:ignore[import-untyped] + from referencing import Registry + from referencing.jsonschema import DRAFT7 + + if TYPE_CHECKING: # pragma: no cover + from jsonschema.protocols import Validator as JsonSchemaValidator # type:ignore[import-untyped] +except ImportError as err: + _missing_deps_error = MissingOptionalDependencyException( + 'This functionality requires optional dependencies.\n' + 'Please install `cyclonedx-python-lib` with the extra "json-validation".\n' + ), err + + +class _BaseJsonValidator(BaseSchemabasedValidator, ABC): + @property + def output_format(self) -> Literal[OutputFormat.JSON]: + return OutputFormat.JSON + + def __init__(self, schema_version: 'SchemaVersion') -> None: + # this is the def that is used for generating the documentation + super().__init__(schema_version) + + if _missing_deps_error: # noqa:C901 + __MDERROR = _missing_deps_error + + def validate_str(self, data: str) -> Optional[ValidationError]: + raise self.__MDERROR[0] from self.__MDERROR[1] + + else: + def validate_str(self, data: str) -> Optional[ValidationError]: + return self._validata_data( + json_loads(data)) + + def _validata_data(self, data: Any) -> Optional[ValidationError]: + validator = self._validator # may throw on error that MUST NOT be caught + try: + validator.validate(data) + except JsonValidationError as error: + return ValidationError(error) + return None + + __validator: Optional['JsonSchemaValidator'] = None + + @property + def _validator(self) -> 'JsonSchemaValidator': + if not self.__validator: + schema_file = self._schema_file + if schema_file is None: + raise NotImplementedError('missing schema file') + with open(schema_file) as sf: + self.__validator = Draft7Validator( + json_loads(sf.read()), + registry=self.__make_validator_registry(), + format_checker=Draft7Validator.FORMAT_CHECKER) + return self.__validator + + @staticmethod + def __make_validator_registry() -> Registry[Any]: + schema_prefix = 'http://cyclonedx.org/schema/' + with open(_S_SPDX) as spdx, open(_S_JSF) as jsf: + return Registry().with_resources([ + (f'{schema_prefix}spdx.SNAPSHOT.schema.json', DRAFT7.create_resource(json_loads(spdx.read()))), + (f'{schema_prefix}jsf-0.82.SNAPSHOT.schema.json', DRAFT7.create_resource(json_loads(jsf.read()))), + ]) + + +class JsonValidator(_BaseJsonValidator, BaseSchemabasedValidator, SchemabasedValidator): + """Validator for CycloneDX documents in JSON format.""" + + @property + def _schema_file(self) -> Optional[str]: + return _S_BOM.get(self.schema_version) + + +class JsonStrictValidator(_BaseJsonValidator, BaseSchemabasedValidator, SchemabasedValidator): + """Strict validator for CycloneDX documents in JSON format. + + In contrast to :class:`~JsonValidator`, + the document must not have additional or unknown JSON properties. + """ + @property + def _schema_file(self) -> Optional[str]: + return _S_BOM_STRICT.get(self.schema_version) diff --git a/cyclonedx/validation/model.py b/cyclonedx/validation/model.py new file mode 100644 index 00000000..c427e60f --- /dev/null +++ b/cyclonedx/validation/model.py @@ -0,0 +1,20 @@ +# 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. + + +# nothing here, yet. +# in the future this could be the place where model validation is done. +# like the current `model.bom.Bom.validate()` +# see also: https://github.com/CycloneDX/cyclonedx-python-lib/issues/455 diff --git a/cyclonedx/validation/xml.py b/cyclonedx/validation/xml.py new file mode 100644 index 00000000..f868f4ee --- /dev/null +++ b/cyclonedx/validation/xml.py @@ -0,0 +1,100 @@ +# 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. + + +__all__ = ['XmlValidator'] + +from abc import ABC +from typing import TYPE_CHECKING, Any, Literal, Optional, Tuple + +from ..exception import MissingOptionalDependencyException +from ..schema import OutputFormat +from ..schema._res import BOM_XML as _S_BOM +from . import BaseSchemabasedValidator, SchemabasedValidator, ValidationError + +if TYPE_CHECKING: # pragma: no cover + from ..schema import SchemaVersion + +_missing_deps_error: Optional[Tuple[MissingOptionalDependencyException, ImportError]] = None +try: + from lxml.etree import ( # type:ignore[import-untyped] # nosec B410 + XMLParser, + XMLSchema, + fromstring as xml_fromstring, + ) +except ImportError as err: + _missing_deps_error = MissingOptionalDependencyException( + 'This functionality requires optional dependencies.\n' + 'Please install `cyclonedx-python-lib` with the extra "json-validation".\n' + ), err + + +class _BaseXmlValidator(BaseSchemabasedValidator, ABC): + + @property + def output_format(self) -> Literal[OutputFormat.XML]: + return OutputFormat.XML + + def __init__(self, schema_version: 'SchemaVersion') -> None: + # this is the def that is used for generating the documentation + super().__init__(schema_version) + + if _missing_deps_error: + __MDERROR = _missing_deps_error + + def validate_str(self, data: str) -> Optional[ValidationError]: + raise self.__MDERROR[0] from self.__MDERROR[1] + else: + def validate_str(self, data: str) -> Optional[ValidationError]: + return self._validata_data( + xml_fromstring( # nosec B320 + bytes(data, encoding='utf8'), + parser=self.__xml_parser)) + + def _validata_data(self, data: Any) -> Optional[ValidationError]: + validator = self._validator # may throw on error that MUST NOT be caught + if not validator.validate(data): + return ValidationError(validator.error_log.last_error) + return None + + __validator: Optional['XMLSchema'] = None + + @property + def __xml_parser(self) -> XMLParser: + return XMLParser( + attribute_defaults=False, dtd_validation=False, load_dtd=False, + no_network=True, + resolve_entities=False, + huge_tree=True, + compact=True, + recover=False + ) + + @property + def _validator(self) -> 'XMLSchema': + if not self.__validator: + schema_file = self._schema_file + if schema_file is None: + raise NotImplementedError('missing schema file') + self.__validator = XMLSchema(file=schema_file) + return self.__validator + + +class XmlValidator(_BaseXmlValidator, BaseSchemabasedValidator, SchemabasedValidator): + """Validator for CycloneDX documents in XML format.""" + + @property + def _schema_file(self) -> Optional[str]: + return _S_BOM.get(self.schema_version) diff --git a/deps.lowest.r b/deps.lowest.r deleted file mode 100644 index 70b35aaa..00000000 --- a/deps.lowest.r +++ /dev/null @@ -1,7 +0,0 @@ -# exactly pinned dependencies to the lowest version regardless of python_version -# see pyptoject file for ranges - -packageurl-python == 0.11.1 -py-serializable == 0.11.1 - -# file name is a untypical one, so dependabot does not bump this file diff --git a/docs/conf.py b/docs/conf.py index ebe66206..273aa588 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # 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 @@ -22,7 +20,7 @@ # The full version, including alpha/beta/rc tags # !! version is managed by semantic_release -release = '4.2.3' +release = '5.0.0-rc.2' # -- General configuration --------------------------------------------------- @@ -31,15 +29,18 @@ # ones. extensions = [ "sphinx.ext.autodoc", - "sphinx.ext.viewcode", + # "sphinx.ext.viewcode", "autoapi.extension", "sphinx_rtd_theme", "m2r2" ] + # Document Python Code autoapi_type = 'python' autoapi_dirs = ['../cyclonedx'] +# see https://sphinx-autoapi.readthedocs.io/en/latest/reference/config.html#confval-autoapi_options +autoapi_options = ['show-module-summary', 'members', 'undoc-members', 'inherited-members', 'show-inheritance'] source_suffix = ['.rst', '.md'] @@ -49,7 +50,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.venv'] # -- Options for HTML output ------------------------------------------------- diff --git a/docs/contributing.rst b/docs/contributing.rst index 5a7f88a0..4fc50161 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1,83 +1 @@ -Contributing -==================================================== - -Pull requests are welcome, but please read these contributing guidelines first. - -Setup ----------------------------------------------------- - -This project uses `poetry`_. Have it installed and setup first. - -To install dev-dependencies and tools: - -.. code-block:: - - poetry install - -Code style ----------------------------------------------------- - -This project uses `PEP8`_ Style Guide for Python Code. This project loves sorted imports. Get it all applied via: - -.. code-block:: - - poetry run isort . - poetry run flake8 cyclonedx/ tests/ typings/ - - -Documentation ----------------------------------------------------- - -This project uses `Sphinx`_ to generate documentation which is automatically published to `readthedocs.io`_. - -Source for documentation is stored in the ``docs`` folder in `RST`_ format. - -You can generate the documentation locally by running: - -.. code-block:: - - cd docs - pip install -r requirements.txt - make html - - -Testing ----------------------------------------------------- - -Run all tests in dedicated environments, via: - -.. code-block:: - - poetry run tox - - -Sign your commits ----------------------------------------------------- - -Please sign your commits, to show that you agree to publish your changes under the current terms and licenses of the -project. We can't accept contributions, however great, if you do not sign your commits. - -.. code-block:: - - git commit --signed-off ... - - -Pre-commit hooks ----------------------------------------------------- - -If you like to take advantage of `pre-commit hooks`_, you can do so to cover most of the topics on this page when -contributing. - -.. code-block:: - - pre-commit install - -All our pre-commit checks will run locally before you can commit! - - -.. _poetry: https://python-poetry.org -.. _PEP8: https://www.python.org/dev/peps/pep-0008 -.. _Sphinx: https://www.sphinx-doc.org/ -.. _readthedocs.io: https://cyclonedx-python-library.readthedocs.io/ -.. _RST: https://en.wikipedia.org/wiki/ReStructuredText -.. _pre-commit hooks: https://pre-commit.com +.. mdinclude:: ../CONTRIBUTING.md diff --git a/docs/examples.rst b/docs/examples.rst index 0df9d8d1..a2b9c97b 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -15,9 +15,9 @@ Examples ======== -Build & Serialize ------------------ +Complex +------- -.. literalinclude:: ../examples/build_and_serialize.py +.. literalinclude:: ../examples/complex.py :language: python :linenos: diff --git a/docs/install.rst b/docs/install.rst index 43123c61..6e8514f7 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -17,7 +17,7 @@ Installation Install from `pypi.org`_ as you would any other Python module using your preferred package manager: -.. code-block:: bash +.. code-block:: sh pip install cyclonedx-python-lib @@ -25,3 +25,21 @@ Install from `pypi.org`_ as you would any other Python module using your preferr .. _pypi.org: https://pypi.org/project/cyclonedx-python-lib/ .. _conda-forge: https://anaconda.org/conda-forge/cyclonedx-python-lib + +Extras +------ + +The following extras are available when installing this package: + +`json-validation` + Install the optional dependencies needed for JSON validation. +`xml-validation` + Install the optional dependencies needed for XML validation. +`validation` + Install the optional dependencies needed for all supported validations. + +They can be used when installing in order to include additional dependencies, e.g.: + +.. code-block:: sh + + pip install 'cyclonedx-python-lib[validation]' diff --git a/docs/requirements.txt b/docs/requirements.txt index db0c3d0f..dfba7e14 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ m2r2>=0.3.2 -Sphinx>=4.3.2 -sphinx-autoapi>=1.8.4 -sphinx-rtd-theme>=1.0.0 \ No newline at end of file +Sphinx>=7.2.6,<8 +sphinx-autoapi>=2.1.1,<3 +sphinx-rtd-theme>=1.3.0,<2 diff --git a/examples/build_and_serialize.py b/examples/build_and_serialize.py deleted file mode 100644 index 52567e66..00000000 --- a/examples/build_and_serialize.py +++ /dev/null @@ -1,51 +0,0 @@ -from cyclonedx.factory.license import LicenseChoiceFactory, LicenseFactory -from cyclonedx.model import OrganizationalEntity, XsUri -from cyclonedx.model.bom import Bom -from cyclonedx.model.component import Component, ComponentType -from cyclonedx.output.json import JsonV1Dot4 -from cyclonedx.output.xml import XmlV1Dot4 -from packageurl import PackageURL - -lc_factory = LicenseChoiceFactory(license_factory=LicenseFactory()) - -# region build the BOM - -bom = Bom() -bom.metadata.component = rootComponent = Component( - name='myApp', - type=ComponentType.APPLICATION, - licenses=[lc_factory.make_from_string('MIT')], - bom_ref='myApp', -) - -component1 = Component( - type=ComponentType.LIBRARY, - name='some-component', - group='acme', - version='1.33.7-beta.1', - licenses=[lc_factory.make_from_string('(c) 2021 Acme inc.')], - supplier=OrganizationalEntity( - name='Acme Inc', - urls=[XsUri('https://www.acme.org')] - ), - bom_ref='myComponent@1.33.7-beta.1', - purl=PackageURL('generic', 'acme', 'some-component', '1.33.7-beta.1') -) -bom.components.add(component1) -bom.register_dependency(rootComponent, [component1]) - -component2 = Component( - type=ComponentType.LIBRARY, - name='some-library', - licenses=[lc_factory.make_from_string('GPL-3.0-only WITH Classpath-exception-2.0')] -) -bom.components.add(component2) -bom.register_dependency(component1, [component2]) - -# endregion build the BOM - -serializedJSON = JsonV1Dot4(bom).output_as_string() -print(serializedJSON) - -serializedXML = XmlV1Dot4(bom).output_as_string() -print(serializedXML) diff --git a/examples/complex.py b/examples/complex.py new file mode 100644 index 00000000..94799ec5 --- /dev/null +++ b/examples/complex.py @@ -0,0 +1,116 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + +import sys + +from packageurl import PackageURL + +from cyclonedx.exception import MissingOptionalDependencyException +from cyclonedx.factory.license import LicenseFactory +from cyclonedx.model import OrganizationalEntity, XsUri +from cyclonedx.model.bom import Bom +from cyclonedx.model.component import Component, ComponentType +from cyclonedx.output import make_outputter, LATEST_SUPPORTED_SCHEMA_VERSION +from cyclonedx.output.json import JsonV1Dot4 +from cyclonedx.schema import SchemaVersion, OutputFormat +from cyclonedx.validation.json import JsonStrictValidator +from cyclonedx.validation import make_schemabased_validator + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from cyclonedx.output.json import Json as JsonOutputter + from cyclonedx.output.xml import Xml as XmlOutputter + from cyclonedx.validation.xml import XmlValidator + + +lc_factory = LicenseFactory() + +# region build the BOM + +bom = Bom() +bom.metadata.component = root_component = Component( + name='myApp', + type=ComponentType.APPLICATION, + licenses=[lc_factory.make_from_string('MIT')], + bom_ref='myApp', +) + +component1 = Component( + type=ComponentType.LIBRARY, + name='some-component', + group='acme', + version='1.33.7-beta.1', + licenses=[lc_factory.make_from_string('(c) 2021 Acme inc.')], + supplier=OrganizationalEntity( + name='Acme Inc', + urls=[XsUri('https://www.acme.org')] + ), + bom_ref='myComponent@1.33.7-beta.1', + purl=PackageURL('generic', 'acme', 'some-component', '1.33.7-beta.1') +) +bom.components.add(component1) +bom.register_dependency(root_component, [component1]) + +component2 = Component( + type=ComponentType.LIBRARY, + name='some-library', + licenses=[lc_factory.make_from_string('GPL-3.0-only WITH Classpath-exception-2.0')] +) +bom.components.add(component2) +bom.register_dependency(component1, [component2]) + +# endregion build the BOM + +# region JSON +"""demo with explicit instructions for SchemaVersion, outputter and validator""" + +my_json_outputter: 'JsonOutputter' = JsonV1Dot4(bom) +serialized_json = my_json_outputter.output_as_string(indent=2) +print(serialized_json) +my_json_validator = JsonStrictValidator(SchemaVersion.V1_4) +try: + validation_errors = my_json_validator.validate_str(serialized_json) + if validation_errors: + print('JSON invalid', 'ValidationError:', repr(validation_errors), sep='\n', file=sys.stderr) + sys.exit(2) + print('JSON valid') +except MissingOptionalDependencyException as error: + print('JSON-validation was skipped due to', error) + +print('', '=' * 30, '', sep='\n') + +# endregion JSON + +# region XML +"""demo with implicit instructions for SchemaVersion, outputter and validator. TypeCheckers will catch errors.""" + +my_xml_outputter: 'XmlOutputter' = make_outputter(bom, OutputFormat.XML, LATEST_SUPPORTED_SCHEMA_VERSION) +serialized_xml = my_xml_outputter.output_as_string(indent=2) +print(serialized_xml) +my_xml_validator: 'XmlValidator' = make_schemabased_validator( + my_xml_outputter.output_format, my_xml_outputter.schema_version) +try: + validation_errors = my_xml_validator.validate_str(serialized_xml) + if validation_errors: + print('XML invalid', 'ValidationError:', repr(validation_errors), sep='\n', file=sys.stderr) + sys.exit(2) + print('XML valid') +except MissingOptionalDependencyException as error: + print('XML-validation was skipped due to', error) + +# endregion XML diff --git a/pyproject.toml b/pyproject.toml index da747003..ad12f7b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,9 +5,12 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "cyclonedx-python-lib" # !! version is managed by semantic_release -version = "4.2.3" +version = "5.0.0-rc.2" description = "A library for producing CycloneDX SBOM (Software Bill of Materials) files." -authors = ["Paul Horton "] +authors = [ + "Paul Horton ", + "Jan Kowalleck ", +] maintainers = [ "Paul Horton ", "Jan Kowalleck ", @@ -24,6 +27,10 @@ include = [ "README.md", "LICENSE", "NOTICE", { path = "tests", format = "sdist" }, ] +exclude = [ + # exclude dotfiles + "**/.*" +] classifiers = [ # Trove classifiers - https://packaging.python.org/specifications/core-metadata/#metadata-classifier # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers @@ -36,11 +43,11 @@ classifiers = [ 'Topic :: Software Development', 'Topic :: System :: Software Distribution', 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Typing :: Typed', ] keywords = [ @@ -52,29 +59,40 @@ keywords = [ [tool.poetry.dependencies] # ATTENTION: keep `deps.lowest.r` file in sync -python = "^3.7" +python = "^3.8" packageurl-python = ">= 0.11" -py-serializable = "^0.11.1" +py-serializable = "^0.15" sortedcontainers = "^2.4.0" license-expression = "^30" +jsonschema = { version = "^4.18", extras=['format'], optional=true } +lxml = { version="^4", optional=true } + +[tool.poetry.extras] +validation = ["jsonschema", "lxml"] +json-validation = ["jsonschema"] +xml-validation = ["lxml"] [tool.poetry.dev-dependencies] ddt = "1.6.0" -coverage = "7.2.7" -flake8 = "5.0.4" # last version supporting Python 3.7 -flake8-annotations = "2.9.1" # last version supporting Python 3.7 -flake8-bugbear = "22.12.6" # last version supporting Python 3.7 -flake8-isort = "4.2.0" -isort = "5.11.5" # last version supporting Python 3.7 -jsonschema = "4.17.3" -mypy = "1.4.1" -lxml = "4.9.3" -tox = "3.28.0" +coverage = "7.3.2" +flake8 = { version="6.1.0", python=">=3.8.1" } +flake8-annotations = { version="3.0.1", python=">=3.8.1" } +flake8-bugbear = { version="23.9.16", python=">=3.8.1" } +flake8-isort = "6.1.0 " +flake8-quotes = "3.3.2" +flake8-use-fstring = "1.4" +pep8-naming = "0.13.3" +isort = "5.12.0" +autopep8 = "2.0.4" +mypy = "1.6.1" +tox = "4.11.3" xmldiff = "2.6.3" +bandit = "1.7.5" [tool.semantic_release] # see https://python-semantic-release.readthedocs.io/en/latest/configuration.html -commit_message = "chore(release): {version}\n\nAutomatically generated by python-semantic-release" +commit_author = "semantic-release " +commit_message = "chore(release): {version}\n\nAutomatically generated by python-semantic-release\n\nSigned-off-by: semantic-release " upload_to_vcs_release = true build_command = "pip install poetry && poetry build" version_toml = ["pyproject.toml:tool.poetry.version"] @@ -82,15 +100,27 @@ version_variables = [ "cyclonedx/__init__.py:__version__", "docs/conf.py:release", ] + +[tool.semantic_release.publish] +dist_glob_patterns = ["dist/*"] +upload_to_vcs_release = true + [tool.semantic_release.changelog] changelog_file = "CHANGELOG.md" exclude_commit_patterns = [ "chore\\(release\\):", ] + [tool.semantic_release.branches.main] match = "(main|master)" prerelease = false -[tool.semantic_release.branches."feat|fix|tests|style|docs|chore"] -match = "(feat|fix|tests|style|docs|chore)" + +[tool.semantic_release.branches."step"] +match = "(build|chore|ci|docs|feat|fix|perf|style|refactor|test)" prerelease = true prerelease_token = "alpha" + +[tool.semantic_release.branches."major-dev"] +match = "\\d+\\.0\\.0-(dev|rc)" +prerelease = true +prerelease_token = "rc" diff --git a/tests/__init__.py b/tests/__init__.py index 4c965300..f0eaf33c 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,13 +16,141 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. from os import getenv, path +from os.path import join +from typing import TYPE_CHECKING, Any, Generator, Iterable, List, Optional, TypeVar, Union +from unittest import TestCase +from uuid import UUID + +from sortedcontainers import SortedSet + +from cyclonedx.schema import OutputFormat, SchemaVersion -import cyclonedx +if TYPE_CHECKING: + from cyclonedx.model.bom import Bom + from cyclonedx.model.dependency import Dependency -CDX_SCHEMA_DIRECTORY = path.join(path.dirname(cyclonedx.__file__), 'schema') +_T = TypeVar('_T') -FIXTURES_DIRECTORY = path.join(path.dirname(__file__), 'fixtures') +_TESTDATA_DIRECTORY = path.join(path.dirname(__file__), '_data') -RECREATE_SNAPSHOTS = bool(getenv('CDX_TEST_RECREATE_SNAPSHOTS')) +SCHEMA_TESTDATA_DIRECTORY = path.join(_TESTDATA_DIRECTORY, 'schemaTestData') +OWN_DATA_DIRECTORY = path.join(_TESTDATA_DIRECTORY, 'own') +SNAPSHOTS_DIRECTORY = path.join(_TESTDATA_DIRECTORY, 'snapshots') + +RECREATE_SNAPSHOTS = '1' == getenv('CDX_TEST_RECREATE_SNAPSHOTS') if RECREATE_SNAPSHOTS: print('!!! WILL RECREATE ALL SNAPSHOTS !!!') + + +class SnapshotMixin: + + @staticmethod + def getSnapshotFile(snapshot_name: str) -> str: # noqa: N802 + return join(SNAPSHOTS_DIRECTORY, f'{snapshot_name}.bin') + + @classmethod + def writeSnapshot(cls, snapshot_name: str, data: str) -> None: # noqa: N802 + with open(cls.getSnapshotFile(snapshot_name), 'w') as s: + s.write(data) + + @classmethod + def readSnapshot(cls, snapshot_name: str) -> str: # noqa: N802 + with open(cls.getSnapshotFile(snapshot_name), 'r') as s: + return s.read() + + def assertEqualSnapshot(self: Union[TestCase, 'SnapshotMixin'], # noqa: N802 + actual: str, snapshot_name: str) -> None: + if RECREATE_SNAPSHOTS: + self.writeSnapshot(snapshot_name, actual) + _omd = self.maxDiff + _omd = self.maxDiff + self.maxDiff = None + try: + self.assertEqual(actual, self.readSnapshot(snapshot_name)) + finally: + self.maxDiff = _omd + + +class DeepCompareMixin: + def assertDeepEqual(self: Union[TestCase, 'DeepCompareMixin'], # noqa: N802 + first: Any, second: Any, + msg: Optional[str] = None) -> None: + """costly compare, but very verbose""" + _omd = self.maxDiff + self.maxDiff = None + try: + self.maxDiff = None + dd1 = self.__deep_dict(first) + dd2 = self.__deep_dict(second) + self.assertDictEqual(dd1, dd2, msg) + finally: + self.maxDiff = _omd + + def __deep_dict(self, o: Any) -> Any: + if isinstance(o, tuple): + return tuple(self.__deep_dict(i) for i in o) + if isinstance(o, list): + return list(self.__deep_dict(i) for i in o) + if isinstance(o, dict): + return {k: self.__deep_dict(v) for k, v in o.items()} + if isinstance(o, (set, SortedSet)): + # this method returns dict. `dict` is not hashable, so use `tuple` instead. + return tuple(self.__deep_dict(i) for i in sorted(o, key=hash)) + ('%conv:%set',) + if hasattr(o, '__dict__'): + d = {a: self.__deep_dict(v) for a, v in o.__dict__.items() if '__' not in a} + d['%conv'] = str(type(o)) + return d + return o + + def assertBomDeepEqual(self: Union[TestCase, 'DeepCompareMixin'], # noqa: N802 + expected: 'Bom', actual: 'Bom', + msg: Optional[str] = None, *, + fuzzy_deps: bool = True) -> None: + # deps might have been upgraded on serialization, so they might differ + edeps = expected.dependencies + adeps = actual.dependencies + if fuzzy_deps: + expected.dependencies = [] + actual.dependencies = [] + try: + self.assertDeepEqual(expected, actual, msg) + if fuzzy_deps: + self.assertDependenciesFuzzyEqual(edeps, adeps) + finally: + expected.dependencies = edeps + actual.dependencies = adeps + + def assertDependenciesFuzzyEqual(self: TestCase, # noqa: N802 + a: Iterable['Dependency'], b: Iterable['Dependency']) -> None: + delta = set(a) ^ set(b) + for d in delta: + # only actual relevant dependencies shall be taken into account. + self.assertEqual(0, len(d.dependencies), f'unexpected dependencies for {d.ref}') + + +def reorder(items: List[_T], indexes: List[int]) -> List[_T]: + """ + Return list of items in the order indicated by indexes. + """ + reordered_items = [] + for i in range(len(items)): + reordered_items.append(items[indexes[i]]) + return reordered_items + + +def uuid_generator(offset: int = 0, version: int = 4) -> Generator[UUID, None, None]: + v = offset + while True: + v += 1 + yield UUID(int=v, version=version) + + +_SNAME_EXT = { + OutputFormat.JSON: 'json', + OutputFormat.XML: 'xml', +} + + +def mksname(purpose: Union[Any], sv: SchemaVersion, f: OutputFormat) -> str: + purpose = purpose if isinstance(purpose, str) else purpose.__name__ + return f'{purpose}-{sv.to_version()}.{_SNAME_EXT[f]}' diff --git a/tests/_data/__init__.py b/tests/_data/__init__.py new file mode 100644 index 00000000..308d97e7 --- /dev/null +++ b/tests/_data/__init__.py @@ -0,0 +1,18 @@ +# encoding: utf-8 + +# This file is part of CycloneDX Python Lib +# +# 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. diff --git a/tests/data.py b/tests/_data/models.py similarity index 68% rename from tests/data.py rename to tests/_data/models.py index 51e7679b..bc66b512 100644 --- a/tests/data.py +++ b/tests/_data/models.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +16,11 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. import base64 +import sys from datetime import datetime, timezone from decimal import Decimal -from typing import List, Optional, TypeVar +from inspect import getmembers, isfunction +from typing import Any, List, Optional from uuid import UUID # See https://github.com/package-url/packageurl-python/issues/65 @@ -28,14 +28,13 @@ from cyclonedx.model import ( AttachedText, + Copyright, DataClassification, DataFlow, Encoding, ExternalReference, ExternalReferenceType, HashType, - License, - LicenseChoice, Note, NoteText, OrganizationalContact, @@ -45,29 +44,32 @@ XsUri, ) from cyclonedx.model.bom import Bom, BomMetaData +from cyclonedx.model.bom_ref import BomRef from cyclonedx.model.component import ( Commit, Component, ComponentEvidence, ComponentScope, ComponentType, - Copyright, Patch, PatchClassification, Pedigree, Swid, ) from cyclonedx.model.dependency import Dependency +from cyclonedx.model.impact_analysis import ( + ImpactAnalysisAffectedStatus, + ImpactAnalysisJustification, + ImpactAnalysisResponse, + ImpactAnalysisState, +) from cyclonedx.model.issue import IssueClassification, IssueType, IssueTypeSource +from cyclonedx.model.license import DisjunctiveLicense, License, LicenseExpression from cyclonedx.model.release_note import ReleaseNotes from cyclonedx.model.service import Service from cyclonedx.model.vulnerability import ( BomTarget, BomTargetVersionRange, - ImpactAnalysisAffectedStatus, - ImpactAnalysisJustification, - ImpactAnalysisResponse, - ImpactAnalysisState, Vulnerability, VulnerabilityAdvisory, VulnerabilityAnalysis, @@ -79,49 +81,63 @@ VulnerabilitySource, ) -MOCK_TIMESTAMP: datetime = datetime(2021, 12, 31, 10, 0, 0, 0).replace(tzinfo=timezone.utc) -MOCK_UUID_1 = 'be2c6502-7e9a-47db-9a66-e34f729810a3' -MOCK_UUID_2 = '17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda' -MOCK_UUID_3 = '0b049d09-64c0-4490-a0f5-c84d9aacf857' -MOCK_UUID_4 = 'cd3e9c95-9d41-49e7-9924-8cf0465ae789' -MOCK_UUID_5 = 'bb5911d6-1a1d-41c9-b6e0-46e848d16655' -MOCK_UUID_6 = 'df70b5f1-8f53-47a4-be48-669ae78795e6' -MOCK_UUID_7 = UUID('6f266d1c-760f-4552-ae3b-41a9b74232fa') -MOCK_UUID_8 = UUID('77d15ab9-5602-4cca-8ed2-59ae579aafd3') -MOCK_UUID_9 = UUID('859ff614-35a7-4d37-803b-d89130cb2577') -MOCK_UUID_10 = UUID('0afa65bc-4acd-428b-9e17-8e97b1969745') -MOCK_BOM_UUID_1 = UUID('3e671687-395b-41f5-a30f-a58921a69b79') -MOCK_BOM_UUID_2 = UUID('d0b24ba4-102b-497e-b31f-4fdc3f0a3005') - -TEST_UUIDS = [ - UUID(MOCK_UUID_1), UUID(MOCK_UUID_2), UUID(MOCK_UUID_3), UUID(MOCK_UUID_4), UUID(MOCK_UUID_5), UUID(MOCK_UUID_6) -] +MOCK_TIMESTAMP = datetime.fromisoformat('2023-08-15 01:23:45.678900+00:00') + +MOCK_UUID = ( + 'be2c6502-7e9a-47db-9a66-e34f729810a3', + '17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda', + '0b049d09-64c0-4490-a0f5-c84d9aacf857', + 'cd3e9c95-9d41-49e7-9924-8cf0465ae789', + 'bb5911d6-1a1d-41c9-b6e0-46e848d16655', + 'df70b5f1-8f53-47a4-be48-669ae78795e6', + '6f266d1c-760f-4552-ae3b-41a9b74232fa', + '77d15ab9-5602-4cca-8ed2-59ae579aafd3', + '859ff614-35a7-4d37-803b-d89130cb2577', + '0afa65bc-4acd-428b-9e17-8e97b1969745', + '3e671687-395b-41f5-a30f-a58921a69b79', + 'd0b24ba4-102b-497e-b31f-4fdc3f0a3005', + 'd0e0a795-6177-478b-b293-b0d19e4469f4', + '7b2a7a2c-66d5-4b30-8ee2-df966a41024e', + '68f7b744-84c2-4f0d-ac8b-c14bd48c37ff', + '1a2f9dfc-3c86-48c7-8ca7-1db488d5c2a0', + 'a3f4096d-4211-4d68-9d2b-13973c86aca9', +) + +BOM_SERIAL_NUMBER = UUID('1441d33a-e0fc-45b5-af3b-61ee52a88bac') +BOM_TIMESTAMP = datetime.fromisoformat('2023-01-07 13:44:32.312678+00:00') + + +def _make_bom(**kwargs: Any) -> Bom: + bom = Bom(**kwargs) + bom.serial_number = BOM_SERIAL_NUMBER + bom.metadata.timestamp = BOM_TIMESTAMP + return bom def get_bom_with_component_setuptools_basic() -> Bom: - return Bom(components=[get_component_setuptools_simple()]) + return _make_bom(components=[get_component_setuptools_simple()]) def get_bom_with_component_setuptools_with_cpe() -> Bom: component = get_component_setuptools_simple() component.cpe = 'cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*' - return Bom(components=[component]) + return _make_bom(components=[component]) def get_bom_with_component_setuptools_no_component_version() -> Bom: - return Bom(components=[get_component_setuptools_simple_no_version()]) + return _make_bom(components=[get_component_setuptools_simple_no_version()]) def get_bom_with_component_setuptools_with_release_notes() -> Bom: component = get_component_setuptools_simple() component.release_notes = get_release_notes() - return Bom(components=[component]) + return _make_bom(components=[component]) def get_bom_with_dependencies_valid() -> Bom: c1 = get_component_setuptools_simple() c2 = get_component_toml_with_hashes_with_references() - return Bom( + return _make_bom( components=[c1, c2], dependencies=[ Dependency(ref=c1.bom_ref, dependencies=[ Dependency(ref=c2.bom_ref) @@ -138,8 +154,7 @@ def get_bom_with_dependencies_hanging() -> Bom: """ c1 = get_component_setuptools_simple('setuptools') c2 = get_component_toml_with_hashes_with_references('toml') - bom = Bom( - serial_number=UUID(hex='12345678395b41f5a30f1234567890ab'), + bom = _make_bom( version=23, metadata=BomMetaData( component=Component(name='rootComponent', type=ComponentType.APPLICATION, bom_ref='root-component'), @@ -152,37 +167,38 @@ def get_bom_with_dependencies_hanging() -> Bom: Dependency(c2.bom_ref) ] ) - bom.metadata.tools.clear() - bom.metadata.timestamp = datetime( - year=2023, month=6, day=1, - hour=3, minute=3, second=7, microsecond=0, - tzinfo=timezone.utc) return bom -def get_bom_with_dependencies_invalid() -> Bom: +def get_bom_with_dependencies_unlinked_invalid() -> Bom: + """generate a bom with an unlinked dependency. + it is expected to throw on output. + """ c1 = get_component_setuptools_simple() - return Bom(components=[c1], dependencies=[Dependency(ref=c1.bom_ref)]) + return _make_bom(components=[c1], dependencies=[Dependency(ref=BomRef('link-to-ref-not-in-document'))]) def get_bom_with_metadata_component_and_dependencies() -> Bom: - bom = Bom(components=[get_component_toml_with_hashes_with_references()]) + cs = get_component_toml_with_hashes_with_references() + bom = _make_bom(components=[cs]) bom.metadata.component = get_component_setuptools_simple() bom.dependencies.add( Dependency(ref=bom.metadata.component.bom_ref, dependencies=[ - Dependency(ref=get_component_toml_with_hashes_with_references().bom_ref) + Dependency(ref=cs.bom_ref) ]) ) return bom def get_bom_with_component_setuptools_complete() -> Bom: - return Bom(components=[get_component_setuptools_complete()]) + return _make_bom(components=[get_component_setuptools_complete()]) def get_bom_with_component_setuptools_with_vulnerability() -> Bom: - bom = Bom() + bom = _make_bom() component = get_component_setuptools_simple() + if not component.purl: + raise ValueError('purl is required here') bom.components.add(component) bom.vulnerabilities.add(Vulnerability( bom_ref='my-vuln-ref-1', id='CVE-2018-7489', source=get_vulnerability_source_nvd(), @@ -193,12 +209,12 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom: ], ratings=[ VulnerabilityRating( - source=get_vulnerability_source_nvd(), score=Decimal(9.8), severity=VulnerabilitySeverity.CRITICAL, + source=get_vulnerability_source_nvd(), score=Decimal('9.8'), severity=VulnerabilitySeverity.CRITICAL, method=VulnerabilityScoreSource.CVSS_V3, vector='AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', justification='Some justification' ), VulnerabilityRating( - source=get_vulnerability_source_owasp(), score=Decimal(2.7), severity=VulnerabilitySeverity.LOW, + source=get_vulnerability_source_owasp(), score=Decimal('2.7'), severity=VulnerabilitySeverity.LOW, method=VulnerabilityScoreSource.CVSS_V3, vector='AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N', justification='Some other justification' ) @@ -230,7 +246,7 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom: ), affects=[ BomTarget( - ref=component.purl.to_string() if component.purl else None, + ref=component.purl.to_string(), versions=[BomTargetVersionRange( range='49.0.0 - 54.0.0', status=ImpactAnalysisAffectedStatus.AFFECTED )] @@ -242,44 +258,48 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom: def get_bom_with_component_toml_1() -> Bom: - return Bom(components=[get_component_toml_with_hashes_with_references()]) + return _make_bom(components=[get_component_toml_with_hashes_with_references()]) def get_bom_just_complete_metadata() -> Bom: - bom = Bom() + bom = _make_bom() bom.metadata.authors = [get_org_contact_1(), get_org_contact_2()] bom.metadata.component = get_component_setuptools_complete() bom.metadata.manufacture = get_org_entity_1() bom.metadata.supplier = get_org_entity_2() - bom.metadata.licenses = [LicenseChoice(license=License( - id='Apache-2.0', text=AttachedText( - content='VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=', encoding=Encoding.BASE_64 - ), url=XsUri('https://www.apache.org/licenses/LICENSE-2.0.txt') - ))] + bom.metadata.licenses = [DisjunctiveLicense( + id='Apache-2.0', + url=XsUri('https://www.apache.org/licenses/LICENSE-2.0.txt'), + text=AttachedText( + encoding=Encoding.BASE_64, + content='VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=' + ) + )] bom.metadata.properties = get_properties_1() return bom def get_bom_with_external_references() -> Bom: - bom = Bom(external_references=[ + bom = _make_bom(external_references=[ get_external_reference_1(), get_external_reference_2() ]) return bom def get_bom_with_services_simple() -> Bom: - bom = Bom(services=[ - Service(name='my-first-service'), - Service(name='my-second-service') + bom = _make_bom(services=[ + Service(name='my-first-service', bom_ref='my-specific-bom-ref-for-my-first-service'), + Service(name='my-second-service', bom_ref='my-specific-bom-ref-for-my-second-service') ]) bom.metadata.component = Component( - name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY + name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY, + bom_ref='my-specific-bom-ref-for-cpl' ) return bom def get_bom_with_services_complex() -> Bom: - bom = Bom(services=[ + bom = _make_bom(services=[ Service( name='my-first-service', bom_ref='my-specific-bom-ref-for-my-first-service', provider=get_org_entity_1(), group='a-group', version='1.2.3', @@ -290,25 +310,24 @@ def get_bom_with_services_complex() -> Bom: authenticated=False, x_trust_boundary=True, data=[ DataClassification(flow=DataFlow.OUTBOUND, classification='public') ], - licenses=[ - LicenseChoice(expression='Commercial') - ], + licenses=[DisjunctiveLicense(name='Commercial')], external_references=[ get_external_reference_1() ], properties=get_properties_1(), release_notes=get_release_notes() ), - Service(name='my-second-service') + Service(name='my-second-service', bom_ref='my-specific-bom-ref-for-my-second-service') ]) bom.metadata.component = Component( - name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY + name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY, + bom_ref='my-specific-bom-ref-for-cpl' ) return bom def get_bom_with_nested_services() -> Bom: - bom = Bom(services=[ + bom = _make_bom(services=[ Service( name='my-first-service', bom_ref='my-specific-bom-ref-for-my-first-service', provider=get_org_entity_1(), group='a-group', version='1.2.3', @@ -319,16 +338,14 @@ def get_bom_with_nested_services() -> Bom: authenticated=False, x_trust_boundary=True, data=[ DataClassification(flow=DataFlow.OUTBOUND, classification='public') ], - licenses=[ - LicenseChoice(expression='Commercial') - ], + licenses=[DisjunctiveLicense(name='Commercial')], external_references=[ get_external_reference_1() ], properties=get_properties_1(), services=[ Service( - name='first-nested-service' + name='first-nested-service', bom_ref='my-specific-bom-ref-for-first-nested-service', ), Service( name='second-nested-service', bom_ref='my-specific-bom-ref-for-second-nested-service', @@ -340,6 +357,7 @@ def get_bom_with_nested_services() -> Bom: ), Service( name='my-second-service', + bom_ref='my-specific-bom-ref-for-my-second-service', services=[ Service( name='yet-another-nested-service', provider=get_org_entity_1(), group='what-group', version='6.5.4' @@ -352,7 +370,8 @@ def get_bom_with_nested_services() -> Bom: ) ]) bom.metadata.component = Component( - name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY + name='cyclonedx-python-lib', version='1.0.0', type=ComponentType.LIBRARY, + bom_ref='my-specific-bom-ref-for-cpl' ) return bom @@ -362,10 +381,10 @@ def get_bom_for_issue_275_components() -> Bom: see https://github.com/CycloneDX/cyclonedx-python-lib/issues/275 """ - app = Component(bom_ref=MOCK_UUID_1, name="app", version="1.0.0") - comp_a = Component(bom_ref=MOCK_UUID_2, name="comp_a", version="1.0.0") - comp_b = Component(bom_ref=MOCK_UUID_3, name="comp_b", version="1.0.0") - comp_c = Component(bom_ref=MOCK_UUID_4, name="comp_c", version="1.0.0") + app = Component(bom_ref=MOCK_UUID[0], name='app', version='1.0.0') + comp_a = Component(bom_ref=MOCK_UUID[1], name='comp_a', version='1.0.0') + comp_b = Component(bom_ref=MOCK_UUID[2], name='comp_b', version='1.0.0') + comp_c = Component(bom_ref=MOCK_UUID[3], name='comp_c', version='1.0.0') comp_b.components.add(comp_c) # comp_b.dependencies.add(comp_c.bom_ref) @@ -374,7 +393,7 @@ def get_bom_for_issue_275_components() -> Bom: # app.dependencies.add(comp_a.bom_ref) # app.dependencies.add(comp_b.bom_ref) - bom = Bom(components=libs) + bom = _make_bom(components=libs) bom.metadata.component = app bom.register_dependency(target=app, depends_on=[comp_a, comp_b]) bom.register_dependency(target=comp_b, depends_on=[comp_c]) @@ -393,7 +412,7 @@ def get_bom_for_issue_275_components() -> Bom: # serv_b.services.add(serv_c) # serv_b.dependencies.add(serv_c.bom_ref) # -# bom = Bom(services=[serv_a, serv_b]) +# bom = _makeBom(services=[serv_a, serv_b]) # bom.metadata.component = app # return bom @@ -402,6 +421,7 @@ def get_bom_for_issue_328_components() -> Bom: """regression test for issue #328 see https://github.com/CycloneDX/cyclonedx-python-lib/issues/328 """ + bom = _make_bom() comp_root = Component(type=ComponentType.APPLICATION, name='my-project', version='1', bom_ref='my-project') @@ -412,19 +432,20 @@ def get_bom_for_issue_328_components() -> Bom: # Make a tree of components A -> B -> C comp_a.components = [comp_b] comp_b.components = [comp_c] - # Declare dependencies the same way: A -> B -> C - comp_a.dependencies = [comp_b.bom_ref] - comp_b.dependencies = [comp_c.bom_ref] - bom = Bom() bom.metadata.component = comp_root - comp_root.dependencies = [comp_a.bom_ref] + bom.register_dependency(comp_root, [comp_a]) bom.components = [comp_a] + + # Declare dependencies the same way: A -> B -> C + bom.register_dependency(comp_a, [comp_b]) + bom.register_dependency(comp_b, [comp_c]) + return bom def get_component_setuptools_complete(include_pedigree: bool = True) -> Component: - component = get_component_setuptools_simple(bom_ref=None) + component = get_component_setuptools_simple(bom_ref='my-specific-bom-ref-for-dings') component.supplier = get_org_entity_1() component.publisher = 'CycloneDX' component.description = 'This component is awesome' @@ -456,7 +477,7 @@ def get_component_setuptools_simple( purl=PackageURL( type='pypi', name='setuptools', version='50.3.2', qualifiers='extension=tar.gz' ), - licenses=[LicenseChoice(expression='MIT License')], + licenses=[DisjunctiveLicense(id='MIT')], author='Test Author' ) @@ -467,7 +488,7 @@ def get_component_setuptools_simple_no_version(bom_ref: Optional[str] = None) -> purl=PackageURL( type='pypi', name='setuptools', qualifiers='extension=tar.gz' ), - licenses=[LicenseChoice(expression='MIT License')], + licenses=[DisjunctiveLicense(id='MIT')], author='Test Author' ) @@ -562,7 +583,7 @@ def get_pedigree_1() -> Pedigree: get_component_toml_with_hashes_with_references(bom_ref='e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66'), get_component_setuptools_simple(bom_ref='ded1d73e-1fca-4302-b520-f1bc53979958') ], - commits=[Commit(uid='a-random-uid', message="A commit message")], + commits=[Commit(uid='a-random-uid', message='A commit message')], patches=[Patch(type=PatchClassification.BACKPORT)], notes='Some notes here please' ) @@ -581,12 +602,12 @@ def get_release_notes() -> ReleaseNotes: ).decode(encoding='UTF-8') return ReleaseNotes( - type='major', title="Release Notes Title", + type='major', title='Release Notes Title', featured_image=XsUri('https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png'), social_image=XsUri('https://cyclonedx.org/cyclonedx-icon.png'), - description="This release is a test release", timestamp=MOCK_TIMESTAMP, + description='This release is a test release', timestamp=MOCK_TIMESTAMP, aliases=[ - "First Test Release" + 'First Test Release' ], tags=['test', 'alpha'], resolves=[get_issue_1()], @@ -640,14 +661,128 @@ def get_vulnerability_source_owasp() -> VulnerabilitySource: return VulnerabilitySource(name='OWASP', url=XsUri('https://owasp.org')) -T = TypeVar('T') +def get_bom_with_licenses() -> Bom: + return _make_bom( + metadata=BomMetaData( + licenses=[DisjunctiveLicense(id='CC-BY-1.0')], + component=Component(name='app', type=ComponentType.APPLICATION, bom_ref='my-app', + licenses=[DisjunctiveLicense(name='proprietary')]) + ), + components=[ + Component(name='c-with-expression', type=ComponentType.LIBRARY, bom_ref='C1', + licenses=[LicenseExpression(value='Apache-2.0 OR MIT')]), + Component(name='c-with-SPDX', type=ComponentType.LIBRARY, bom_ref='C2', + licenses=[DisjunctiveLicense(id='Apache-2.0')]), + Component(name='c-with-name', type=ComponentType.LIBRARY, bom_ref='C3', + licenses=[DisjunctiveLicense(name='(c) ACME Inc.')]), + ], + services=[ + Service(name='s-with-expression', bom_ref='S1', + licenses=[LicenseExpression(value='Apache-2.0 OR MIT')]), + Service(name='s-with-SPDX', bom_ref='S2', + licenses=[DisjunctiveLicense(id='Apache-2.0')]), + Service(name='s-with-name', bom_ref='S3', + licenses=[DisjunctiveLicense(name='(c) ACME Inc.')]), + ]) + + +def get_bom_metadata_licenses_invalid() -> Bom: + return Bom(metadata=BomMetaData(licenses=get_invalid_license_repository())) -def reorder(items: List[T], indexes: List[int]) -> List[T]: +def get_invalid_license_repository() -> List[License]: """ - Return list of items in the order indicated by indexes. + license expression and a license -- this is an invalid constellation according to schema + see https://github.com/CycloneDX/specification/pull/205 """ - reordered_items = [] - for i in range(len(items)): - reordered_items.append(items[indexes[i]]) - return reordered_items + return [ + LicenseExpression(value='Apache-2.0 OR MIT'), + DisjunctiveLicense(id='GPL-2.0-only'), + ] + + +def get_component_licenses_invalid() -> Component: + return Component(name='foo', type=ComponentType.LIBRARY, + licenses=get_invalid_license_repository()) + + +def get_bom_metadata_component_licenses_invalid() -> Bom: + comp = get_component_licenses_invalid() + return Bom(metadata=BomMetaData(component=comp), + dependencies=[Dependency(comp.bom_ref)]) + + +def get_bom_metadata_component_nested_licenses_invalid() -> Bom: + comp = Component(name='bar', type=ComponentType.LIBRARY, + components=[get_component_licenses_invalid()]) + return Bom(metadata=BomMetaData(component=comp), + dependencies=[Dependency(comp.bom_ref)]) + + +def get_bom_component_licenses_invalid() -> Bom: + return Bom(components=[get_component_licenses_invalid()]) + + +def get_bom_component_nested_licenses_invalid() -> Bom: + return Bom(components=[ + Component(name='bar', type=ComponentType.LIBRARY, + components=[get_component_licenses_invalid()]) + ]) + + +def get_bom_service_licenses_invalid() -> Bom: + return Bom(services=[ + Service(name='foo', licenses=get_invalid_license_repository()) + ]) + + +def get_bom_with_multiple_licenses() -> Bom: + multi_licenses = ( + DisjunctiveLicense(id='MIT'), + DisjunctiveLicense(name='foo license'), + ) + return _make_bom( + metadata=BomMetaData( + licenses=multi_licenses, + component=Component(name='app', type=ComponentType.APPLICATION, bom_ref='my-app', + licenses=multi_licenses) + ), + components=[Component(name='comp', type=ComponentType.LIBRARY, bom_ref='my-compo', + licenses=multi_licenses)], + services=[Service(name='serv', bom_ref='my-serv', + licenses=multi_licenses)] + ) + + +# --- + + +all_get_bom_funct_valid = tuple( + (n, f) for n, f in getmembers(sys.modules[__name__], isfunction) + if n.startswith('get_bom_') and not n.endswith('_invalid') +) + +all_get_bom_funct_invalid = tuple( + (n, f) for n, f in getmembers(sys.modules[__name__], isfunction) + if n.startswith('get_bom_') and n.endswith('_invalid') +) + +all_get_bom_funct_with_incomplete_deps = { + # List of functions that return BOM with an incomplte dependency graph. + # It is expected that some process auto-fixes this before actual serialization takes place. + get_bom_just_complete_metadata, + get_bom_with_component_setuptools_basic, + get_bom_with_component_setuptools_complete, + get_bom_with_component_setuptools_no_component_version, + get_bom_with_component_setuptools_with_cpe, + get_bom_with_component_setuptools_with_release_notes, + get_bom_with_component_setuptools_with_vulnerability, + get_bom_with_component_toml_1, + get_bom_with_dependencies_hanging, + get_bom_with_metadata_component_and_dependencies, + get_bom_with_nested_services, + get_bom_with_services_complex, + get_bom_with_services_simple, + get_bom_with_licenses, + get_bom_with_multiple_licenses, +} diff --git a/tests/_data/own/.gitattributes b/tests/_data/own/.gitattributes new file mode 100644 index 00000000..2b6ec797 --- /dev/null +++ b/tests/_data/own/.gitattributes @@ -0,0 +1,2 @@ +xml/*/*.xml linguist-generated +json/*/*.json linguist-generated diff --git a/tests/_data/own/README.md b/tests/_data/own/README.md new file mode 100644 index 00000000..ad527e19 --- /dev/null +++ b/tests/_data/own/README.md @@ -0,0 +1 @@ +# TEST FIXTURES diff --git a/tests/_data/own/json/1.2/bom_with_mixed_licenses.json b/tests/_data/own/json/1.2/bom_with_mixed_licenses.json new file mode 100644 index 00000000..da4d3c54 --- /dev/null +++ b/tests/_data/own/json/1.2/bom_with_mixed_licenses.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "metadata": { + "component": { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}} + ], + "name": "app", + "type": "application" + }, + "licenses": [ + {"license": {"name": "foo license"}}, + {"license": {"id": "MIT"}}, + {"expression": "MIT OR Apache-2.0"} + ] + }, + "components": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"} + ], + "name": "comp", + "type": "library" + } + ], + "services": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}} + ], + "name": "serv" + } + ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1337 +} diff --git a/tests/_data/own/json/1.3/bom_with_mixed_licenses.json b/tests/_data/own/json/1.3/bom_with_mixed_licenses.json new file mode 100644 index 00000000..da4d3c54 --- /dev/null +++ b/tests/_data/own/json/1.3/bom_with_mixed_licenses.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "metadata": { + "component": { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}} + ], + "name": "app", + "type": "application" + }, + "licenses": [ + {"license": {"name": "foo license"}}, + {"license": {"id": "MIT"}}, + {"expression": "MIT OR Apache-2.0"} + ] + }, + "components": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"} + ], + "name": "comp", + "type": "library" + } + ], + "services": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}} + ], + "name": "serv" + } + ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1337 +} diff --git a/tests/_data/own/json/1.4/bom_with_mixed_licenses.json b/tests/_data/own/json/1.4/bom_with_mixed_licenses.json new file mode 100644 index 00000000..da4d3c54 --- /dev/null +++ b/tests/_data/own/json/1.4/bom_with_mixed_licenses.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "metadata": { + "component": { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}} + ], + "name": "app", + "type": "application" + }, + "licenses": [ + {"license": {"name": "foo license"}}, + {"license": {"id": "MIT"}}, + {"expression": "MIT OR Apache-2.0"} + ] + }, + "components": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"id": "MIT"}}, + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"} + ], + "name": "comp", + "type": "library" + } + ], + "services": [ + { + "description": "before CDX 1.5 it was allowed to mix `expression` and `license`", + "licenses": [ + {"license": {"name": "foo license"}}, + {"expression": "MIT OR Apache-2.0"}, + {"license": {"id": "MIT"}} + ], + "name": "serv" + } + ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1337 +} diff --git a/tests/fixtures/xml/1.4/bom_setuptools.xml b/tests/_data/own/xml/1.4/bom_setuptools.xml similarity index 100% rename from tests/fixtures/xml/1.4/bom_setuptools.xml rename to tests/_data/own/xml/1.4/bom_setuptools.xml diff --git a/tests/fixtures/xml/1.4/webgoat-6.1.xml b/tests/_data/own/xml/1.4/webgoat-6.1.xml similarity index 100% rename from tests/fixtures/xml/1.4/webgoat-6.1.xml rename to tests/_data/own/xml/1.4/webgoat-6.1.xml diff --git a/tests/_data/schemaTestData/.gitattributes b/tests/_data/schemaTestData/.gitattributes new file mode 100644 index 00000000..60a50df0 --- /dev/null +++ b/tests/_data/schemaTestData/.gitattributes @@ -0,0 +1,3 @@ +* binary +*/*.json linguist-vendored diff=json +*/*.xml linguist-vendored diff=xml diff --git a/tests/_data/schemaTestData/1.0/valid-bom-1.0.xml b/tests/_data/schemaTestData/1.0/valid-bom-1.0.xml new file mode 100644 index 00000000..f0bfba22 --- /dev/null +++ b/tests/_data/schemaTestData/1.0/valid-bom-1.0.xml @@ -0,0 +1,69 @@ + + + + + org.example + myapplication + 1.0.0 + An example application + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + + + twitter + bootstrap + 3.3.7 + The most popular front-end framework for developing responsive, mobile first projects on the web. + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + + pkg:npm/bootstrap@3.3.7 + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + + + + diff --git a/tests/_data/schemaTestData/1.0/valid-component-hashes-1.0.xml b/tests/_data/schemaTestData/1.0/valid-component-hashes-1.0.xml new file mode 100644 index 00000000..5e028659 --- /dev/null +++ b/tests/_data/schemaTestData/1.0/valid-component-hashes-1.0.xml @@ -0,0 +1,19 @@ + + + + + acme-example + 1.0.0 + + 641b6e166f8b33c5e959e2adcc18b1c7 + 9188560f22e0b73070d2efce670c74af2bdf30af + d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964 + d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad + 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6 + 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa + 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20 + + false + + + diff --git a/tests/_data/schemaTestData/1.1/invalid-component-ref-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-component-ref-1.1.xml new file mode 100644 index 00000000..2eaaf789 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-component-ref-1.1.xml @@ -0,0 +1,15 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-component-type-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-component-type-1.1.xml new file mode 100644 index 00000000..125cf096 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-component-type-1.1.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-empty-component-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-empty-component-1.1.xml new file mode 100644 index 00000000..20d8ef39 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-empty-component-1.1.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-hash-alg-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-hash-alg-1.1.xml new file mode 100644 index 00000000..e7c28b8e --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-hash-alg-1.1.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-hash-md5-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-hash-md5-1.1.xml new file mode 100644 index 00000000..64473513 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-hash-md5-1.1.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + foo + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-hash-sha1-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-hash-sha1-1.1.xml new file mode 100644 index 00000000..f13b5696 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-hash-sha1-1.1.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + foo + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-hash-sha256-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-hash-sha256-1.1.xml new file mode 100644 index 00000000..a1815e43 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-hash-sha256-1.1.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + foo + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-hash-sha512-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-hash-sha512-1.1.xml new file mode 100644 index 00000000..53d2bdd4 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-hash-sha512-1.1.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + foo + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-license-choice-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-license-choice-1.1.xml new file mode 100644 index 00000000..d217aa5e --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-license-choice-1.1.xml @@ -0,0 +1,26 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-license-encoding-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-license-encoding-1.1.xml new file mode 100644 index 00000000..a7d73d17 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-license-encoding-1.1.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-license-id-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-license-id-1.1.xml new file mode 100644 index 00000000..f9b083a4 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-license-id-1.1.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-license-id-count-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-license-id-count-1.1.xml new file mode 100644 index 00000000..7f89adf3 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-license-id-count-1.1.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + MIT + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-license-name-count-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-license-name-count-1.1.xml new file mode 100644 index 00000000..70470cb1 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-license-name-count-1.1.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-missing-component-type-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-missing-component-type-1.1.xml new file mode 100644 index 00000000..8825945b --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-missing-component-type-1.1.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-namespace-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-namespace-1.1.xml new file mode 100644 index 00000000..2e83863c --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-namespace-1.1.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-scope-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-scope-1.1.xml new file mode 100644 index 00000000..f093dc14 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-scope-1.1.xml @@ -0,0 +1,10 @@ + + + + + acme-library + 1.0.0 + foo + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/invalid-serialnumber-1.1.xml b/tests/_data/schemaTestData/1.1/invalid-serialnumber-1.1.xml new file mode 100644 index 00000000..5149a031 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/invalid-serialnumber-1.1.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-bom-1.1.xml b/tests/_data/schemaTestData/1.1/valid-bom-1.1.xml new file mode 100644 index 00000000..06fc5e87 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-bom-1.1.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-component-hashes-1.1.xml b/tests/_data/schemaTestData/1.1/valid-component-hashes-1.1.xml new file mode 100644 index 00000000..0ee0e69b --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-component-hashes-1.1.xml @@ -0,0 +1,18 @@ + + + + + acme-example + 1.0.0 + + 641b6e166f8b33c5e959e2adcc18b1c7 + 9188560f22e0b73070d2efce670c74af2bdf30af + d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964 + d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad + 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6 + 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa + 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20 + + + + diff --git a/tests/_data/schemaTestData/1.1/valid-component-ref-1.1.xml b/tests/_data/schemaTestData/1.1/valid-component-ref-1.1.xml new file mode 100644 index 00000000..6712fb5a --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-component-ref-1.1.xml @@ -0,0 +1,19 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + acme-library + 1.0.0 + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-component-types-1.1.xml b/tests/_data/schemaTestData/1.1/valid-component-types-1.1.xml new file mode 100644 index 00000000..714f6c71 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-component-types-1.1.xml @@ -0,0 +1,29 @@ + + + + + application-a + 1.0 + + + library-a + 1.0 + + + framework-a + 1.0 + + + operating-system-a + 1.0 + + + device-a + 1.0 + + + file-a + 1.0 + + + diff --git a/tests/_data/schemaTestData/1.1/valid-empty-components-1.1.xml b/tests/_data/schemaTestData/1.1/valid-empty-components-1.1.xml new file mode 100644 index 00000000..9763b2c4 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-empty-components-1.1.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-external-elements-1.1.xml b/tests/_data/schemaTestData/1.1/valid-external-elements-1.1.xml new file mode 100644 index 00000000..6fab6f35 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-external-elements-1.1.xml @@ -0,0 +1,158 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + Banana + + + Banana + + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + Banana + + + Banana + + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + Banana + + + Banana + + + + Banana + + + Banana + + + + + foo + 1.0 + + + Banana + + + Banana + + + + + bar + 1.0 + + + Banana + + + Banana + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + Banana + + + Banana + + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Banana + + + Banana + + + Initial commit + + Banana + + + Banana + + + + Banana + + + Banana + + + Commentary here + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-license-expression-1.1.xml b/tests/_data/schemaTestData/1.1/valid-license-expression-1.1.xml new file mode 100644 index 00000000..436c09a1 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-license-expression-1.1.xml @@ -0,0 +1,23 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-license-id-1.1.xml b/tests/_data/schemaTestData/1.1/valid-license-id-1.1.xml new file mode 100644 index 00000000..fdd25ac6 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-license-id-1.1.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-license-name-1.1.xml b/tests/_data/schemaTestData/1.1/valid-license-name-1.1.xml new file mode 100644 index 00000000..d3a72f13 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-license-name-1.1.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-minimal-viable-1.1.xml b/tests/_data/schemaTestData/1.1/valid-minimal-viable-1.1.xml new file mode 100644 index 00000000..6d681aab --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-minimal-viable-1.1.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-random-attributes-1.1.xml b/tests/_data/schemaTestData/1.1/valid-random-attributes-1.1.xml new file mode 100644 index 00000000..15525e88 --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-random-attributes-1.1.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.1/valid-xml-signature-1.1.xml b/tests/_data/schemaTestData/1.1/valid-xml-signature-1.1.xml new file mode 100644 index 00000000..b3a7ccaa --- /dev/null +++ b/tests/_data/schemaTestData/1.1/valid-xml-signature-1.1.xml @@ -0,0 +1,177 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + Initial commit + + + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + blah + fdaf + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + + + + + + + + + +PrB8/rofGs34XwIX5OIdYSjV2aKSe5VaztJKBvsgjIk= + + + +ePGNg30Zl9CW7RZdcRn8gFCp1AlWncjudA9pQDXyqZOvyj9RC2YtkI688WdfDOdVRZs6mflJFXr7 +IKA9wY6jVrEqZmlef55Qp/8iGwOjOjWbwYsm2AhrdkUi9gaFSWEd8uITYHOpWbiPFSsnimiK9+ft +56dkg/oJMLdXzlaukzq9iGkRcafRkW433OQcZIXwD2K8lg4cdD0pNNNqBa+PgIvzbxA5H84TyQDB +HBcQiw/j1edRBJgPOwlqzZDUawOJaFhAPUQ+GGKMetIJH2FqqrHXGuV1NIwnbWTCg40RdOcBdCrl +PDtDVjFh34uZ4dYBpJBIlM4daD2N4B6WPB5iHRyuZTczF2q03ObabuTgkpK6EeadFVqFNsEOOPPt +MDDyda+Lwff5KjvUHvRRtUDIOm2rNIQKzaseulwYcA9UWQHAFcupJmWcLLM4zzY7F/uOdZuSurzh +U6h5kdb76Juepof6ee4Q5YpwNOGNL5JfB4C3sc/Dbbv8dZ8OuXFYSZN7reUGZzCNksByqERPEbAe +n1ldJu1HnRXRQpwaon8Asy9CuNmPfFCfDwOs2B4p4tb+tLNIKFHdRlpd19Zr9vCMCbltXeqq0Cpq +OejSyLYGqSWzzzUh449dJrg6KTevrTNEln5GAlLBFSdjM5JA7KV2u/GyDVFwSEW7UKooGN4CtgU= + + + +CN=bomsigner,OU=development,O=cyclonedx + +MIIE+DCCAuCgAwIBAgIEXGzayTANBgkqhkiG9w0BAQsFADA+MRIwEAYDVQQKDAljeWNsb25lZHgx +FDASBgNVBAsMC2RldmVsb3BtZW50MRIwEAYDVQQDDAlib21zaWduZXIwHhcNMTkwMjIwMDQ0MjQ5 +WhcNNDkwMjIwMDQ0MjQ5WjA+MRIwEAYDVQQKDAljeWNsb25lZHgxFDASBgNVBAsMC2RldmVsb3Bt +ZW50MRIwEAYDVQQDDAlib21zaWduZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo +5JZsM4ZLfWW/dpRlU6CpnItWspddF+bEVDETKVwVj9tGpqR5jURgKS/BOQP2TGUsR3/ZJJBhYRll +ONhrUQrVKV/I6wp3Z40qPEa1RJLE+QlG9iL8qBV52CnXkLmnUSax3dspSzmSct5vDiTnvpHG9jr0 +AKFeTjy7U9rv8GJybz0ijwlpBoO9JRdYPX2PrrzoSeJLoxKq+GwuyCZ5LhXRN0p1a+NAirTAmY+c +G1ZTLkMmfeCUy1t6H/bG4RnYOSSPOvk7Rb68lQpUqb+pbbNuB2o/b9cDwtLLCtGVlu+5Wj8mrytY +3FGFQM20j3yVeRInmGqTTDBelQa/CO4JKqBlmaeYEIvNYbFs9+AlqadivwDO51RpdPo9fPSpsBpy +ZMv6S2bXNuUML+Rk99WyKJTPM0PTZhRLZ64ZXEhlz3kQWVoSlrcwwim6sj6LRUb5IRqA3lxRFUI6 +NXKyiQLamQp+t3/9OGW9L1rLCcw7yFo0s8LhMTPMiv4ol9/hQViT+8ICzDsr0OM9ZiF4/UagFRlt +IClV70cjh1DpsZjzQIRVGaj8uQ/JdtfRz4E43Ki7U0a2Vpho/t6poLVndv46tkX5nYGtMW4WfMoD +ZflQ9pajvvKtr2jB1wob6nsU+VTmAcWZy4BCPH+XyfDw/0SFBdUceJJJtPWIeYFDUY7onptf+wID +AQABMA0GCSqGSIb3DQEBCwUAA4ICAQCOVariNgK+9OF/5T9ZaSvZbkk45RTmzgQNXtFc5xfRvqwP +s+pu/DFXm1R+ltjyS5j3w6NBZUFUI5MqLQr6JEEDrbu8BvfBO57wJNAEATj1JIHEfDfh7BxnBF8f +oYFOwbrh4jOt0wz0FW2obsSVmF4GSvS7tTlWqTcsxjdZVmwP40RWu18B9jzv7M61adrWD3ksDA5O +amSOsZi3Nt0aacDkyGRdCIEFi0fplxQInXMtD1z3RhXu2JSTAIr54Cei49Bh71kAXSWHMCog/f8a +lSrZyqZBty/ACfU9DqlPIM+giHePKm4z2bcdpUdKZk6wcKDn4CvuBOqsMBMg7L05UEyyqTPD/4dk +2GwJ8Nv0E5gsYHCIXF2cZ3OUVsw0mB/ozleEJVDE02uZZN/1wW1Xq028LsMdgN0Wk1WvWyF5MEdh +nPWuhqp6tNaDI/kK6XQF+LjYJUzua3AQFOHfYNLKhO6d+bJ4rr0833v4v3cLW34kbXkKb6U3Yv8X +SK3jBGCACiPgnc0N6awkh1kDlrZQ7GMsl14c+2+vpl9Lf0sL0mRUIyICfSC8MjlsP/BZH3emyfsk +iWivPALomycKqP+PSkt1WaWApGENZWk1wNN99FYSYlt6LViW2p6T97fRx4jPRlHu+wecfD2k9RP4 +bt5W2HWfOP0zNAS7SnAVLEl2QZxXKw== + + + + + +qOSWbDOGS31lv3aUZVOgqZyLVrKXXRfmxFQxEylcFY/bRqakeY1EYCkvwTkD9kxlLEd/2SSQYWEZ +ZTjYa1EK1SlfyOsKd2eNKjxGtUSSxPkJRvYi/KgVedgp15C5p1Emsd3bKUs5knLebw4k576RxvY6 +9AChXk48u1Pa7/Bicm89Io8JaQaDvSUXWD19j6686EniS6MSqvhsLsgmeS4V0TdKdWvjQIq0wJmP +nBtWUy5DJn3glMtbeh/2xuEZ2Dkkjzr5O0W+vJUKVKm/qW2zbgdqP2/XA8LSywrRlZbvuVo/Jq8r +WNxRhUDNtI98lXkSJ5hqk0wwXpUGvwjuCSqgZZmnmBCLzWGxbPfgJamnYr8AzudUaXT6PXz0qbAa +cmTL+ktm1zblDC/kZPfVsiiUzzND02YUS2euGVxIZc95EFlaEpa3MMIpurI+i0VG+SEagN5cURVC +OjVysokC2pkKfrd//ThlvS9aywnMO8haNLPC4TEzzIr+KJff4UFYk/vCAsw7K9DjPWYheP1GoBUZ +bSApVe9HI4dQ6bGY80CEVRmo/LkPyXbX0c+BONyou1NGtlaYaP7eqaC1Z3b+OrZF+Z2BrTFuFnzK +A2X5UPaWo77yra9owdcKG+p7FPlU5gHFmcuAQjx/l8nw8P9EhQXVHHiSSbT1iHmBQ1GO6J6bX/s= + +AQAB + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.2/invalid-bomformat-1.2.json b/tests/_data/schemaTestData/1.2/invalid-bomformat-1.2.json new file mode 100644 index 00000000..ab493ea0 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-bomformat-1.2.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "AnotherFormat", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.json b/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.json new file mode 100644 index 00000000..570520d4 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.xml new file mode 100644 index 00000000..7ddef820 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-ref-1.2.xml @@ -0,0 +1,15 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.json b/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.json new file mode 100644 index 00000000..e93d6ed1 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.json @@ -0,0 +1,18 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.xml new file mode 100644 index 00000000..4aac9cbe --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-swid-1.2.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.json b/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.json new file mode 100644 index 00000000..a34b26e3 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "foo", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.xml new file mode 100644 index 00000000..881350ab --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-component-type-1.2.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.json b/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.json new file mode 100644 index 00000000..248d4f8f --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.json @@ -0,0 +1,37 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.xml new file mode 100644 index 00000000..b954f29d --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-dependency-1.2.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-empty-component-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-empty-component-1.2.xml new file mode 100644 index 00000000..af24c96a --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-empty-component-1.2.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.json b/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.json new file mode 100644 index 00000000..9a4a5047 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "FOO", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.xml new file mode 100644 index 00000000..7f4f077f --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-alg-1.2.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.json b/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.json new file mode 100644 index 00000000..9edb2eb4 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "foo" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.xml new file mode 100644 index 00000000..1f12a35b --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-md5-1.2.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + foo + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.json b/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.json new file mode 100644 index 00000000..7cfa1e04 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "foo" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.xml new file mode 100644 index 00000000..8c660bda --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha1-1.2.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + foo + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.json b/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.json new file mode 100644 index 00000000..3ec0bdd5 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "foo" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.xml new file mode 100644 index 00000000..13954ca3 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha256-1.2.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + foo + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.json b/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.json new file mode 100644 index 00000000..a80fb9c8 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "foo" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.xml new file mode 100644 index 00000000..36bd8093 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-hash-sha512-1.2.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + foo + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.json b/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.json new file mode 100644 index 00000000..ce04bd3f --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "foo", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.xml new file mode 100644 index 00000000..611fc2eb --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-issue-type-1.2.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.json b/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.json new file mode 100644 index 00000000..2084a197 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.json @@ -0,0 +1,23 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.xml new file mode 100644 index 00000000..02396c08 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-choice-1.2.xml @@ -0,0 +1,26 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.json b/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.json new file mode 100644 index 00000000..c46dbce8 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.json @@ -0,0 +1,28 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base85", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.xml new file mode 100644 index 00000000..e003ce04 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-encoding-1.2.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.json b/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.json new file mode 100644 index 00000000..3e16a5c6 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.xml new file mode 100644 index 00000000..f8543002 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-id-1.2.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-license-id-count-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-license-id-count-1.2.xml new file mode 100644 index 00000000..cca7e050 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-id-count-1.2.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + MIT + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-license-name-count-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-license-name-count-1.2.xml new file mode 100644 index 00000000..0d335e16 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-license-name-count-1.2.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.json b/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.json new file mode 100644 index 00000000..b1dcfa8d --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.xml new file mode 100644 index 00000000..b34b81e7 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-metadata-timestamp-1.2.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07 + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-missing-component-type-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-missing-component-type-1.2.xml new file mode 100644 index 00000000..91dd2775 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-missing-component-type-1.2.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-namespace-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-namespace-1.2.xml new file mode 100644 index 00000000..9e42be40 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-namespace-1.2.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.json b/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.json new file mode 100644 index 00000000..4a1eb80a --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "foo", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.xml new file mode 100644 index 00000000..8a5ba460 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-patch-type-1.2.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-scope-1.2.json b/tests/_data/schemaTestData/1.2/invalid-scope-1.2.json new file mode 100644 index 00000000..987481fc --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-scope-1.2.json @@ -0,0 +1,14 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "foo" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-scope-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-scope-1.2.xml new file mode 100644 index 00000000..b1e61012 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-scope-1.2.xml @@ -0,0 +1,10 @@ + + + + + acme-library + 1.0.0 + foo + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.json b/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.json new file mode 100644 index 00000000..691956ad --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.xml new file mode 100644 index 00000000..1fabd243 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-serialnumber-1.2.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.json b/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.json new file mode 100644 index 00000000..b341c481 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "name": "Stock ticker service", + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "foo", + "flow": "bar" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.xml b/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.xml new file mode 100644 index 00000000..5ef78890 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/invalid-service-data-1.2.xml @@ -0,0 +1,11 @@ + + + + + Stock ticker service + + bar + + + + diff --git a/tests/_data/schemaTestData/1.2/skip_invalid-empty-component-1.2.json b/tests/_data/schemaTestData/1.2/skip_invalid-empty-component-1.2.json new file mode 100644 index 00000000..fa916a9e --- /dev/null +++ b/tests/_data/schemaTestData/1.2/skip_invalid-empty-component-1.2.json @@ -0,0 +1,12 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "$comment": "expected to fail, since `name` and `version` are missing. But in fact `name` and `version` are optional as they have a default value in CDX-v1.2" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/skip_invalid-missing-component-type-1.2.json b/tests/_data/schemaTestData/1.2/skip_invalid-missing-component-type-1.2.json new file mode 100644 index 00000000..141da072 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/skip_invalid-missing-component-type-1.2.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "name": "acme-library", + "version": "1.0.0", + "$comment": "expected to fail, since `type` is missing. But in fact `type` is optional as it has a default value in CDX-v1.2" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-assembly-1.2.json b/tests/_data/schemaTestData/1.2/valid-assembly-1.2.json new file mode 100644 index 00000000..2516922c --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-assembly-1.2.json @@ -0,0 +1,30 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library-a", + "version": "1.0.0", + "components": [ + { + "type": "library", + "name": "acme-library-b", + "version": "2.0.0" + } + ] + } + ], + "services": [ + { + "name": "acme-service-a", + "services": [ + { + "name": "acme-service-b" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-assembly-1.2.xml b/tests/_data/schemaTestData/1.2/valid-assembly-1.2.xml new file mode 100644 index 00000000..c58ef4d2 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-assembly-1.2.xml @@ -0,0 +1,25 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 2.0.0 + + + + + + + acme-service-a + + + acme-service-b + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-bom-1.2.json b/tests/_data/schemaTestData/1.2/valid-bom-1.2.json new file mode 100644 index 00000000..62979356 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-bom-1.2.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-bom-1.2.xml b/tests/_data/schemaTestData/1.2/valid-bom-1.2.xml new file mode 100644 index 00000000..6be1b4f0 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-bom-1.2.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.json b/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.json new file mode 100644 index 00000000..98d4285e --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.json @@ -0,0 +1,63 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-example", + "version": "1.0.0", + "hashes": [ + { + "alg": "MD5", + "content": "641b6e166f8b33c5e959e2adcc18b1c7" + }, + { + "alg": "SHA-1", + "content": "9188560f22e0b73070d2efce670c74af2bdf30af" + }, + { + "alg": "SHA-256", + "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" + }, + { + "alg": "SHA-384", + "content": "d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" + }, + { + "alg": "SHA-512", + "content": "74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" + }, + { + "alg": "SHA3-256", + "content": "7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa" + }, + { + "alg": "SHA3-384", + "content": "a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5" + }, + { + "alg": "SHA3-512", + "content": "7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20" + }, + { + "alg": "BLAKE2b-256", + "content": "d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237" + }, + { + "alg": "BLAKE2b-384", + "content": "e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a" + }, + { + "alg": "BLAKE2b-512", + "content": "f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d" + }, + { + "alg": "BLAKE3", + "content": "26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.xml b/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.xml new file mode 100644 index 00000000..309e0ee2 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-hashes-1.2.xml @@ -0,0 +1,23 @@ + + + + + acme-example + 1.0.0 + + 641b6e166f8b33c5e959e2adcc18b1c7 + 9188560f22e0b73070d2efce670c74af2bdf30af + d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964 + d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad + 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6 + 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa + a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5 + 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20 + d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237 + e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a + f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d + 26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.json b/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.json new file mode 100644 index 00000000..131af1d7 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "456", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.xml b/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.xml new file mode 100644 index 00000000..46d33c47 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-ref-1.2.xml @@ -0,0 +1,19 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.json b/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.json new file mode 100644 index 00000000..96a0ae1c --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.json @@ -0,0 +1,19 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.xml b/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.xml new file mode 100644 index 00000000..4e1fe539 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-swid-1.2.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.json b/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.json new file mode 100644 index 00000000..02b935e3 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.json @@ -0,0 +1,24 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.xml b/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.xml new file mode 100644 index 00000000..d7bba6bc --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-swid-full-1.2.xml @@ -0,0 +1,13 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-component-types-1.2.json b/tests/_data/schemaTestData/1.2/valid-component-types-1.2.json new file mode 100644 index 00000000..5ffcbd71 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-types-1.2.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "name": "application-a", + "version": "1.0" + }, + { + "type": "library", + "name": "library-a", + "version": "1.0" + }, + { + "type": "framework", + "name": "framework-a", + "version": "1.0" + }, + { + "type": "container", + "name": "container-a", + "version": "1.0" + }, + { + "type": "operating-system", + "name": "operating-system-a", + "version": "1.0" + }, + { + "type": "firmware", + "name": "firmware-a", + "version": "1.0" + }, + { + "type": "device", + "name": "device-a", + "version": "1.0" + }, + { + "type": "file", + "name": "file-a", + "version": "1.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-component-types-1.2.xml b/tests/_data/schemaTestData/1.2/valid-component-types-1.2.xml new file mode 100644 index 00000000..0349a1a4 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-component-types-1.2.xml @@ -0,0 +1,37 @@ + + + + + application-a + 1.0 + + + library-a + 1.0 + + + framework-a + 1.0 + + + container-a + 1.0 + + + operating-system-a + 1.0 + + + firmware-a + 1.0 + + + device-a + 1.0 + + + file-a + 1.0 + + + diff --git a/tests/_data/schemaTestData/1.2/valid-dependency-1.2.json b/tests/_data/schemaTestData/1.2/valid-dependency-1.2.json new file mode 100644 index 00000000..bf3a2649 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-dependency-1.2.json @@ -0,0 +1,38 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "library-a", + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-dependency-1.2.xml b/tests/_data/schemaTestData/1.2/valid-dependency-1.2.xml new file mode 100644 index 00000000..e245766c --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-dependency-1.2.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.json b/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.json new file mode 100644 index 00000000..c3878bf6 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.xml b/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.xml new file mode 100644 index 00000000..cacbb9df --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-empty-components-1.2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-external-elements-1.2.xml b/tests/_data/schemaTestData/1.2/valid-external-elements-1.2.xml new file mode 100644 index 00000000..3231b703 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-external-elements-1.2.xml @@ -0,0 +1,158 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + Banana + + + Banana + + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + Banana + + + Banana + + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + Banana + + + Banana + + + + Banana + + + Banana + + + + + foo + 1.0 + + + Banana + + + Banana + + + + + bar + 1.0 + + + Banana + + + Banana + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + Banana + + + Banana + + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Banana + + + Banana + + + Initial commit + + Banana + + + Banana + + + + Banana + + + Banana + + + Commentary here + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + diff --git a/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.json b/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.json new file mode 100644 index 00000000..89c06c1c --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.xml b/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.xml new file mode 100644 index 00000000..53f5c1ca --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-expression-1.2.xml @@ -0,0 +1,23 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/valid-license-id-1.2.json b/tests/_data/schemaTestData/1.2/valid-license-id-1.2.json new file mode 100644 index 00000000..0b3ff68b --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-id-1.2.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-license-id-1.2.xml b/tests/_data/schemaTestData/1.2/valid-license-id-1.2.xml new file mode 100644 index 00000000..2cf536cd --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-id-1.2.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/valid-license-name-1.2.json b/tests/_data/schemaTestData/1.2/valid-license-name-1.2.json new file mode 100644 index 00000000..4dabe805 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-name-1.2.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-license-name-1.2.xml b/tests/_data/schemaTestData/1.2/valid-license-name-1.2.xml new file mode 100644 index 00000000..11cb08a6 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-license-name-1.2.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.json b/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.json new file mode 100644 index 00000000..e0c0b45a --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.xml b/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.xml new file mode 100644 index 00000000..e37ac51d --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-author-1.2.xml @@ -0,0 +1,13 @@ + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.json b/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.json new file mode 100644 index 00000000..fb92230a --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.xml b/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.xml new file mode 100644 index 00000000..b6773a54 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-manufacture-1.2.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.json b/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.json new file mode 100644 index 00000000..5a241c78 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.xml b/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.xml new file mode 100644 index 00000000..8a980b25 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-supplier-1.2.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.json b/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.json new file mode 100644 index 00000000..cf242cca --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.xml b/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.xml new file mode 100644 index 00000000..4891b1a5 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-timestamp-1.2.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07T07:01:00Z + + + diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.json b/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.json new file mode 100644 index 00000000..7adade0d --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.json @@ -0,0 +1,26 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.xml b/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.xml new file mode 100644 index 00000000..ebfc4085 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-metadata-tool-1.2.xml @@ -0,0 +1,17 @@ + + + + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.json b/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.json new file mode 100644 index 00000000..5c9795c2 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.xml b/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.xml new file mode 100644 index 00000000..7088bb51 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-minimal-viable-1.2.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.2/valid-patch-1.2.json b/tests/_data/schemaTestData/1.2/valid-patch-1.2.json new file mode 100644 index 00000000..2b53cf4c --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-patch-1.2.json @@ -0,0 +1,88 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + }, + { + "type": "backport", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "security", + "id": "CVE-2019-9997", + "name": "CVE-2019-9997", + "description": "blah blah", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + }, + { + "type": "defect", + "id": "JIRA-874319", + "description": "Enable to do something", + "source": { + "name": "Example Org", + "url": "https://issues.example.org/874319" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-patch-1.2.xml b/tests/_data/schemaTestData/1.2/valid-patch-1.2.xml new file mode 100644 index 00000000..80f9984b --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-patch-1.2.xml @@ -0,0 +1,70 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + blah + uri/to/changes.diff + + + + CVE-2019-9997 + CVE-2019-9997 + blah blah + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + http://some/other/site-1 + http://some/other/site-2 + + + + JIRA-874319 + Enable to do something + + Example Org + https://issues.example.org/874319 + + + http://some/other/site-1 + http://some/other/site-2 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-random-attributes-1.2.xml b/tests/_data/schemaTestData/1.2/valid-random-attributes-1.2.xml new file mode 100644 index 00000000..a76db616 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-random-attributes-1.2.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-service-1.2.json b/tests/_data/schemaTestData/1.2/valid-service-1.2.json new file mode 100644 index 00000000..2b75c68b --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-service-1.2.json @@ -0,0 +1,101 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "stock-java-client", + "version": "1.0.12", + "hashes": [ + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "purl": "pkg:maven/com.acme/stock-java-client@1.0.12" + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "name": "Partner Org", + "url": [ + "https://partner.org" + ], + "contact": [ + { + "name": "Support", + "email": "support@partner", + "phone": "800-555-1212" + } + ] + }, + "group": "org.partner", + "name": "Stock ticker service", + "version": "2020-Q2", + "description": "Provides real-time stock information", + "endpoints": [ + "https://partner.org/api/v1/lookup", + "https://partner.org/api/v1/stock" + ], + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "PII", + "flow": "inbound" + }, + { + "classification": "PIFI", + "flow": "outbound" + }, + { + "classification": "pubic", + "flow": "bi-directional" + }, + { + "classification": "partner-data", + "flow": "unknown" + } + ], + "licenses": [ + { + "license": { + "name": "Partner license" + } + } + ], + "externalReferences": [ + { + "type": "website", + "url": "http://partner.org" + }, + { + "type": "documentation", + "url": "http://api.partner.org/swagger" + } + ] + } + ], + "dependencies": [ + { + "ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "dependsOn": [ + "b2a46a4b-8367-4bae-9820-95557cfe03a8" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-service-1.2.xml b/tests/_data/schemaTestData/1.2/valid-service-1.2.xml new file mode 100644 index 00000000..48ee7af2 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-service-1.2.xml @@ -0,0 +1,66 @@ + + + + + com.acme + stock-java-client + 1.0.12 + + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + + + + Apache-2.0 + + + pkg:maven/com.acme/stock-java-client@1.0.12 + + + + + + Partner Org + https://partner.org + + Support + support@partner + 800-555-1212 + + + org.partner + Stock ticker service + 2020-Q2 + Provides real-time stock information + + https://partner.org/api/v1/lookup + https://partner.org/api/v1/stock + + true + true + + PII + PIFI + pubic + partner-data + + + + Partner license + + + + + http://partner.org + + + http://api.partner.org/swagger + + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.json b/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.json new file mode 100644 index 00000000..ece3a65f --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "contact": [ + ] + }, + "name": "Stock ticker service", + "endpoints": [ + ], + "data": [ + ], + "externalReferences": [ + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.xml b/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.xml new file mode 100644 index 00000000..b1ecb31e --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-service-empty-objects-1.2.xml @@ -0,0 +1,16 @@ + + + + + + + Stock ticker service + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.2/valid-xml-signature-1.2.xml b/tests/_data/schemaTestData/1.2/valid-xml-signature-1.2.xml new file mode 100644 index 00000000..96051448 --- /dev/null +++ b/tests/_data/schemaTestData/1.2/valid-xml-signature-1.2.xml @@ -0,0 +1,177 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + Initial commit + + + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + blah + fdaf + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + + + + + + + + + + PrB8/rofGs34XwIX5OIdYSjV2aKSe5VaztJKBvsgjIk= + + + + ePGNg30Zl9CW7RZdcRn8gFCp1AlWncjudA9pQDXyqZOvyj9RC2YtkI688WdfDOdVRZs6mflJFXr7 + IKA9wY6jVrEqZmlef55Qp/8iGwOjOjWbwYsm2AhrdkUi9gaFSWEd8uITYHOpWbiPFSsnimiK9+ft + 56dkg/oJMLdXzlaukzq9iGkRcafRkW433OQcZIXwD2K8lg4cdD0pNNNqBa+PgIvzbxA5H84TyQDB + HBcQiw/j1edRBJgPOwlqzZDUawOJaFhAPUQ+GGKMetIJH2FqqrHXGuV1NIwnbWTCg40RdOcBdCrl + PDtDVjFh34uZ4dYBpJBIlM4daD2N4B6WPB5iHRyuZTczF2q03ObabuTgkpK6EeadFVqFNsEOOPPt + MDDyda+Lwff5KjvUHvRRtUDIOm2rNIQKzaseulwYcA9UWQHAFcupJmWcLLM4zzY7F/uOdZuSurzh + U6h5kdb76Juepof6ee4Q5YpwNOGNL5JfB4C3sc/Dbbv8dZ8OuXFYSZN7reUGZzCNksByqERPEbAe + n1ldJu1HnRXRQpwaon8Asy9CuNmPfFCfDwOs2B4p4tb+tLNIKFHdRlpd19Zr9vCMCbltXeqq0Cpq + OejSyLYGqSWzzzUh449dJrg6KTevrTNEln5GAlLBFSdjM5JA7KV2u/GyDVFwSEW7UKooGN4CtgU= + + + + CN=bomsigner,OU=development,O=cyclonedx + + MIIE+DCCAuCgAwIBAgIEXGzayTANBgkqhkiG9w0BAQsFADA+MRIwEAYDVQQKDAljeWNsb25lZHgx + FDASBgNVBAsMC2RldmVsb3BtZW50MRIwEAYDVQQDDAlib21zaWduZXIwHhcNMTkwMjIwMDQ0MjQ5 + WhcNNDkwMjIwMDQ0MjQ5WjA+MRIwEAYDVQQKDAljeWNsb25lZHgxFDASBgNVBAsMC2RldmVsb3Bt + ZW50MRIwEAYDVQQDDAlib21zaWduZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo + 5JZsM4ZLfWW/dpRlU6CpnItWspddF+bEVDETKVwVj9tGpqR5jURgKS/BOQP2TGUsR3/ZJJBhYRll + ONhrUQrVKV/I6wp3Z40qPEa1RJLE+QlG9iL8qBV52CnXkLmnUSax3dspSzmSct5vDiTnvpHG9jr0 + AKFeTjy7U9rv8GJybz0ijwlpBoO9JRdYPX2PrrzoSeJLoxKq+GwuyCZ5LhXRN0p1a+NAirTAmY+c + G1ZTLkMmfeCUy1t6H/bG4RnYOSSPOvk7Rb68lQpUqb+pbbNuB2o/b9cDwtLLCtGVlu+5Wj8mrytY + 3FGFQM20j3yVeRInmGqTTDBelQa/CO4JKqBlmaeYEIvNYbFs9+AlqadivwDO51RpdPo9fPSpsBpy + ZMv6S2bXNuUML+Rk99WyKJTPM0PTZhRLZ64ZXEhlz3kQWVoSlrcwwim6sj6LRUb5IRqA3lxRFUI6 + NXKyiQLamQp+t3/9OGW9L1rLCcw7yFo0s8LhMTPMiv4ol9/hQViT+8ICzDsr0OM9ZiF4/UagFRlt + IClV70cjh1DpsZjzQIRVGaj8uQ/JdtfRz4E43Ki7U0a2Vpho/t6poLVndv46tkX5nYGtMW4WfMoD + ZflQ9pajvvKtr2jB1wob6nsU+VTmAcWZy4BCPH+XyfDw/0SFBdUceJJJtPWIeYFDUY7onptf+wID + AQABMA0GCSqGSIb3DQEBCwUAA4ICAQCOVariNgK+9OF/5T9ZaSvZbkk45RTmzgQNXtFc5xfRvqwP + s+pu/DFXm1R+ltjyS5j3w6NBZUFUI5MqLQr6JEEDrbu8BvfBO57wJNAEATj1JIHEfDfh7BxnBF8f + oYFOwbrh4jOt0wz0FW2obsSVmF4GSvS7tTlWqTcsxjdZVmwP40RWu18B9jzv7M61adrWD3ksDA5O + amSOsZi3Nt0aacDkyGRdCIEFi0fplxQInXMtD1z3RhXu2JSTAIr54Cei49Bh71kAXSWHMCog/f8a + lSrZyqZBty/ACfU9DqlPIM+giHePKm4z2bcdpUdKZk6wcKDn4CvuBOqsMBMg7L05UEyyqTPD/4dk + 2GwJ8Nv0E5gsYHCIXF2cZ3OUVsw0mB/ozleEJVDE02uZZN/1wW1Xq028LsMdgN0Wk1WvWyF5MEdh + nPWuhqp6tNaDI/kK6XQF+LjYJUzua3AQFOHfYNLKhO6d+bJ4rr0833v4v3cLW34kbXkKb6U3Yv8X + SK3jBGCACiPgnc0N6awkh1kDlrZQ7GMsl14c+2+vpl9Lf0sL0mRUIyICfSC8MjlsP/BZH3emyfsk + iWivPALomycKqP+PSkt1WaWApGENZWk1wNN99FYSYlt6LViW2p6T97fRx4jPRlHu+wecfD2k9RP4 + bt5W2HWfOP0zNAS7SnAVLEl2QZxXKw== + + + + + + qOSWbDOGS31lv3aUZVOgqZyLVrKXXRfmxFQxEylcFY/bRqakeY1EYCkvwTkD9kxlLEd/2SSQYWEZ + ZTjYa1EK1SlfyOsKd2eNKjxGtUSSxPkJRvYi/KgVedgp15C5p1Emsd3bKUs5knLebw4k576RxvY6 + 9AChXk48u1Pa7/Bicm89Io8JaQaDvSUXWD19j6686EniS6MSqvhsLsgmeS4V0TdKdWvjQIq0wJmP + nBtWUy5DJn3glMtbeh/2xuEZ2Dkkjzr5O0W+vJUKVKm/qW2zbgdqP2/XA8LSywrRlZbvuVo/Jq8r + WNxRhUDNtI98lXkSJ5hqk0wwXpUGvwjuCSqgZZmnmBCLzWGxbPfgJamnYr8AzudUaXT6PXz0qbAa + cmTL+ktm1zblDC/kZPfVsiiUzzND02YUS2euGVxIZc95EFlaEpa3MMIpurI+i0VG+SEagN5cURVC + OjVysokC2pkKfrd//ThlvS9aywnMO8haNLPC4TEzzIr+KJff4UFYk/vCAsw7K9DjPWYheP1GoBUZ + bSApVe9HI4dQ6bGY80CEVRmo/LkPyXbX0c+BONyou1NGtlaYaP7eqaC1Z3b+OrZF+Z2BrTFuFnzK + A2X5UPaWo77yra9owdcKG+p7FPlU5gHFmcuAQjx/l8nw8P9EhQXVHHiSSbT1iHmBQ1GO6J6bX/s= + + AQAB + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-bomformat-1.3.json b/tests/_data/schemaTestData/1.3/invalid-bomformat-1.3.json new file mode 100644 index 00000000..7df3cac2 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-bomformat-1.3.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "AnotherFormat", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.json b/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.json new file mode 100644 index 00000000..ba06096b --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.xml new file mode 100644 index 00000000..4b5976dd --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-ref-1.3.xml @@ -0,0 +1,15 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.json b/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.json new file mode 100644 index 00000000..455f2f33 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.json @@ -0,0 +1,18 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.xml new file mode 100644 index 00000000..868072da --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-swid-1.3.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.json b/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.json new file mode 100644 index 00000000..a22bf388 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "foo", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.xml new file mode 100644 index 00000000..2a9da0fb --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-component-type-1.3.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.json b/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.json new file mode 100644 index 00000000..988a0450 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.json @@ -0,0 +1,37 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.xml new file mode 100644 index 00000000..d3c1567b --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-dependency-1.3.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.json b/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.json new file mode 100644 index 00000000..31537b2c --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.json @@ -0,0 +1,11 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.xml new file mode 100644 index 00000000..c47376c0 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-empty-component-1.3.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.json b/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.json new file mode 100644 index 00000000..625094c3 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "FOO", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.xml new file mode 100644 index 00000000..541b2ed2 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-alg-1.3.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.json b/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.json new file mode 100644 index 00000000..40812819 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "foo" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.xml new file mode 100644 index 00000000..9e63b8fd --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-md5-1.3.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + foo + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.json b/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.json new file mode 100644 index 00000000..7b1e0036 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "foo" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.xml new file mode 100644 index 00000000..082a8267 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha1-1.3.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + foo + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.json b/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.json new file mode 100644 index 00000000..49f747e0 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "foo" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.xml new file mode 100644 index 00000000..e29c2b22 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha256-1.3.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + foo + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.json b/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.json new file mode 100644 index 00000000..5e83aae6 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "foo" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.xml new file mode 100644 index 00000000..46303523 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-hash-sha512-1.3.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + foo + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.json b/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.json new file mode 100644 index 00000000..cea6add4 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "foo", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.xml new file mode 100644 index 00000000..f3b80ba8 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-issue-type-1.3.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.json b/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.json new file mode 100644 index 00000000..1218f847 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.json @@ -0,0 +1,23 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.xml new file mode 100644 index 00000000..0a89d024 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-choice-1.3.xml @@ -0,0 +1,26 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.json b/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.json new file mode 100644 index 00000000..b61550ee --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.json @@ -0,0 +1,28 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base85", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.xml new file mode 100644 index 00000000..1518cb71 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-encoding-1.3.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.json b/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.json new file mode 100644 index 00000000..0d275dd0 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.xml new file mode 100644 index 00000000..9adb85ce --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-id-1.3.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-license-id-count-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-license-id-count-1.3.xml new file mode 100644 index 00000000..ce13178d --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-id-count-1.3.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + MIT + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-license-name-count-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-license-name-count-1.3.xml new file mode 100644 index 00000000..85d87e5a --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-license-name-count-1.3.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.json b/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.json new file mode 100644 index 00000000..82a79226 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "licenses": [ + { + "license": { + "id": "Apache-2" + } + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.xml new file mode 100644 index 00000000..07d4f9cb --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-metadata-license-1.3.xml @@ -0,0 +1,11 @@ + + + + + + Apache-2 + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.json b/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.json new file mode 100644 index 00000000..a021eb67 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.xml new file mode 100644 index 00000000..4154eed9 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-metadata-timestamp-1.3.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07 + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.json b/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.json new file mode 100644 index 00000000..f11a51ef --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.json @@ -0,0 +1,12 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.xml new file mode 100644 index 00000000..ee10a82c --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-missing-component-type-1.3.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-namespace-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-namespace-1.3.xml new file mode 100644 index 00000000..9e42be40 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-namespace-1.3.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.json b/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.json new file mode 100644 index 00000000..a8897abd --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "foo", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.xml new file mode 100644 index 00000000..c6d591e9 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-patch-type-1.3.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-scope-1.3.json b/tests/_data/schemaTestData/1.3/invalid-scope-1.3.json new file mode 100644 index 00000000..38e5bb10 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-scope-1.3.json @@ -0,0 +1,14 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "foo" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-scope-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-scope-1.3.xml new file mode 100644 index 00000000..6d25da49 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-scope-1.3.xml @@ -0,0 +1,10 @@ + + + + + acme-library + 1.0.0 + foo + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.json b/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.json new file mode 100644 index 00000000..70d3112a --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.xml new file mode 100644 index 00000000..b5578dc9 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-serialnumber-1.3.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.json b/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.json new file mode 100644 index 00000000..51068413 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "name": "Stock ticker service", + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "foo", + "flow": "bar" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.xml b/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.xml new file mode 100644 index 00000000..af9ed8b3 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/invalid-service-data-1.3.xml @@ -0,0 +1,11 @@ + + + + + Stock ticker service + + bar + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-assembly-1.3.json b/tests/_data/schemaTestData/1.3/valid-assembly-1.3.json new file mode 100644 index 00000000..78720ccb --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-assembly-1.3.json @@ -0,0 +1,30 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library-a", + "version": "1.0.0", + "components": [ + { + "type": "library", + "name": "acme-library-b", + "version": "2.0.0" + } + ] + } + ], + "services": [ + { + "name": "acme-service-a", + "services": [ + { + "name": "acme-service-b" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-assembly-1.3.xml b/tests/_data/schemaTestData/1.3/valid-assembly-1.3.xml new file mode 100644 index 00000000..b53f3eb7 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-assembly-1.3.xml @@ -0,0 +1,25 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 2.0.0 + + + + + + + acme-service-a + + + acme-service-b + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-bom-1.3.json b/tests/_data/schemaTestData/1.3/valid-bom-1.3.json new file mode 100644 index 00000000..75550db7 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-bom-1.3.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-bom-1.3.xml b/tests/_data/schemaTestData/1.3/valid-bom-1.3.xml new file mode 100644 index 00000000..c9cda0c6 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-bom-1.3.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.json b/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.json new file mode 100644 index 00000000..77be6651 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.json @@ -0,0 +1,63 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-example", + "version": "1.0.0", + "hashes": [ + { + "alg": "MD5", + "content": "641b6e166f8b33c5e959e2adcc18b1c7" + }, + { + "alg": "SHA-1", + "content": "9188560f22e0b73070d2efce670c74af2bdf30af" + }, + { + "alg": "SHA-256", + "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" + }, + { + "alg": "SHA-384", + "content": "d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" + }, + { + "alg": "SHA-512", + "content": "74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" + }, + { + "alg": "SHA3-256", + "content": "7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa" + }, + { + "alg": "SHA3-384", + "content": "a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5" + }, + { + "alg": "SHA3-512", + "content": "7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20" + }, + { + "alg": "BLAKE2b-256", + "content": "d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237" + }, + { + "alg": "BLAKE2b-384", + "content": "e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a" + }, + { + "alg": "BLAKE2b-512", + "content": "f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d" + }, + { + "alg": "BLAKE3", + "content": "26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.xml b/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.xml new file mode 100644 index 00000000..53df1b7c --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-hashes-1.3.xml @@ -0,0 +1,23 @@ + + + + + acme-example + 1.0.0 + + 641b6e166f8b33c5e959e2adcc18b1c7 + 9188560f22e0b73070d2efce670c74af2bdf30af + d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964 + d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad + 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6 + 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa + a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5 + 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20 + d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237 + e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a + f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d + 26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.json b/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.json new file mode 100644 index 00000000..b7e2bb38 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "456", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.xml b/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.xml new file mode 100644 index 00000000..89cdb880 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-ref-1.3.xml @@ -0,0 +1,19 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.json b/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.json new file mode 100644 index 00000000..4dbad442 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.json @@ -0,0 +1,19 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.xml b/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.xml new file mode 100644 index 00000000..859c11d6 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-swid-1.3.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.json b/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.json new file mode 100644 index 00000000..074dd07e --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.json @@ -0,0 +1,24 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.xml b/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.xml new file mode 100644 index 00000000..0896c06d --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-swid-full-1.3.xml @@ -0,0 +1,13 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-component-types-1.3.json b/tests/_data/schemaTestData/1.3/valid-component-types-1.3.json new file mode 100644 index 00000000..591dd3bf --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-types-1.3.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "name": "application-a", + "version": "1.0" + }, + { + "type": "library", + "name": "library-a", + "version": "1.0" + }, + { + "type": "framework", + "name": "framework-a", + "version": "1.0" + }, + { + "type": "container", + "name": "container-a", + "version": "1.0" + }, + { + "type": "operating-system", + "name": "operating-system-a", + "version": "1.0" + }, + { + "type": "firmware", + "name": "firmware-a", + "version": "1.0" + }, + { + "type": "device", + "name": "device-a", + "version": "1.0" + }, + { + "type": "file", + "name": "file-a", + "version": "1.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-component-types-1.3.xml b/tests/_data/schemaTestData/1.3/valid-component-types-1.3.xml new file mode 100644 index 00000000..34676a63 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-component-types-1.3.xml @@ -0,0 +1,37 @@ + + + + + application-a + 1.0 + + + library-a + 1.0 + + + framework-a + 1.0 + + + container-a + 1.0 + + + operating-system-a + 1.0 + + + firmware-a + 1.0 + + + device-a + 1.0 + + + file-a + 1.0 + + + diff --git a/tests/_data/schemaTestData/1.3/valid-compositions-1.3.json b/tests/_data/schemaTestData/1.3/valid-compositions-1.3.json new file mode 100644 index 00000000..eeb6e48f --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-compositions-1.3.json @@ -0,0 +1,65 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "component": { + "bom-ref": "acme-application-1.0", + "type": "application", + "name": "Acme Application", + "version": "1.0" + } + }, + "components": [ + { + "bom-ref": "pkg:maven/partner/shaded-library@1.0", + "type": "library", + "name": "Partner Shaded Library", + "version": "1.0", + "purl": "pkg:maven/partner/shaded-library@1.0", + "components": [ + { + "bom-ref": "pkg:maven/ossproject/library@2.0", + "type": "library", + "name": "Some Opensource Library", + "version": "2.0", + "purl": "pkg:maven/ossproject/library@2.0" + } + ] + }, + { + "bom-ref": "pkg:maven/acme/library@3.0", + "type": "library", + "name": "Acme Library", + "version": "3.0", + "purl": "pkg:maven/acme/library@3.0" + } + ], + "dependencies": [ + { + "ref": "acme-application-1.0", + "dependsOn": [ + "pkg:maven/partner/shaded-library@1.0", + "pkg:maven/acme/library@3.0" + ] + } + ], + "compositions": [ + { + "aggregate": "complete", + "assemblies": [ + "pkg:maven/partner/shaded-library@1.0" + ], + "dependencies": [ + "acme-application-1.0" + ] + }, + { + "aggregate": "unknown", + "assemblies": [ + "pkg:maven/acme/library@3.0" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-compositions-1.3.xml b/tests/_data/schemaTestData/1.3/valid-compositions-1.3.xml new file mode 100644 index 00000000..2b2d7847 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-compositions-1.3.xml @@ -0,0 +1,51 @@ + + + + + Acme Application + 1.0 + + + + + Partner Shaded Library + 1.0 + pkg:maven/partner/shaded-library@1.0 + + + Some Opensource Library + 2.0 + pkg:maven/ossproject/library@2.0 + + + + + Acme Library + 2.0 + pkg:maven/acme/library@3.0 + + + + + + + + + + + complete + + + + + + + + + unknown + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-dependency-1.3.json b/tests/_data/schemaTestData/1.3/valid-dependency-1.3.json new file mode 100644 index 00000000..87f70743 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-dependency-1.3.json @@ -0,0 +1,38 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "library-a", + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-dependency-1.3.xml b/tests/_data/schemaTestData/1.3/valid-dependency-1.3.xml new file mode 100644 index 00000000..d02773b4 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-dependency-1.3.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.json b/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.json new file mode 100644 index 00000000..ba708657 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.xml b/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.xml new file mode 100644 index 00000000..0c37d3f3 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-empty-components-1.3.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-evidence-1.3.json b/tests/_data/schemaTestData/1.3/valid-evidence-1.3.json new file mode 100644 index 00000000..4fc32ab8 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-evidence-1.3.json @@ -0,0 +1,53 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "group": "com.google.code.findbugs", + "name": "findbugs-project", + "version": "3.0.0", + "licenses": [ + { + "license": { + "id": "LGPL-3.0-or-later", + "url": "https://www.gnu.org/licenses/lgpl-3.0-standalone.html" + } + } + ], + "purl": "pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0", + "evidence": { + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + } + }, + { + "license": { + "id": "LGPL-2.1-only", + "url": "https://opensource.org/licenses/LGPL-2.1" + } + } + ], + "copyright": [ + { + "text": "Copyright 2012 Google Inc. All Rights Reserved." + }, + { + "text": "Copyright (C) 2004,2005 Dave Brosius " + }, + { + "text": "Copyright (C) 2005 William Pugh" + }, + { + "text": "Copyright (C) 2004,2005 University of Maryland" + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-evidence-1.3.xml b/tests/_data/schemaTestData/1.3/valid-evidence-1.3.xml new file mode 100644 index 00000000..c2435a4b --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-evidence-1.3.xml @@ -0,0 +1,35 @@ + + + + + com.google.code.findbugs + findbugs-project + 3.0.0 + + + LGPL-3.0-or-later + https://www.gnu.org/licenses/lgpl-3.0-standalone.html + + + pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0 + + + + Apache-2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + + + + + ]]> + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-external-elements-1.3.xml b/tests/_data/schemaTestData/1.3/valid-external-elements-1.3.xml new file mode 100644 index 00000000..4fe8ffdf --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-external-elements-1.3.xml @@ -0,0 +1,158 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + Banana + + + Banana + + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + Banana + + + Banana + + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + Banana + + + Banana + + + + Banana + + + Banana + + + + + foo + 1.0 + + + Banana + + + Banana + + + + + bar + 1.0 + + + Banana + + + Banana + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + Banana + + + Banana + + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Banana + + + Banana + + + Initial commit + + Banana + + + Banana + + + + Banana + + + Banana + + + Commentary here + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + diff --git a/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.json b/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.json new file mode 100644 index 00000000..060770e1 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.json @@ -0,0 +1,38 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0", + "externalReferences": [ + { + "type": "advisories", + "url": "https://example.org/security/feed/csaf", + "comment": "Security advisories from the vendor" + }, + { + "type": "bom", + "url": "https://example.org/support/sbom/portal-server/1.0.0", + "comment": "An external SBOM that describes what this component includes", + "hashes": [ + { + "alg": "SHA-256", + "content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313" + } + ] + }, + { + "type": "documentation", + "url": "https://example.org/support/documentation/portal-server/1.0.0", + "comment": "Vendor provided documentation for the product" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.xml b/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.xml new file mode 100644 index 00000000..6a2888ed --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-external-reference-1.3.xml @@ -0,0 +1,27 @@ + + + + + org.example + mylibrary + 1.0.0 + + + https://example.org/security/feed/csaf + Security advisories from the vendor + + + https://example.org/support/sbom/portal-server/1.0.0 + An external SBOM that describes what this component includes + + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + + + + https://example.org/support/documentation/portal-server/1.0.0 + Vendor provided documentation for the product + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.json b/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.json new file mode 100644 index 00000000..787a8cd6 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.xml b/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.xml new file mode 100644 index 00000000..ae9099a2 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-expression-1.3.xml @@ -0,0 +1,23 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/valid-license-id-1.3.json b/tests/_data/schemaTestData/1.3/valid-license-id-1.3.json new file mode 100644 index 00000000..e227babc --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-id-1.3.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-license-id-1.3.xml b/tests/_data/schemaTestData/1.3/valid-license-id-1.3.xml new file mode 100644 index 00000000..e25e9203 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-id-1.3.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/valid-license-name-1.3.json b/tests/_data/schemaTestData/1.3/valid-license-name-1.3.json new file mode 100644 index 00000000..9d865b99 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-name-1.3.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-license-name-1.3.xml b/tests/_data/schemaTestData/1.3/valid-license-name-1.3.xml new file mode 100644 index 00000000..9097df57 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-license-name-1.3.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.json new file mode 100644 index 00000000..9c78197a --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.xml new file mode 100644 index 00000000..e9492df0 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-author-1.3.xml @@ -0,0 +1,13 @@ + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.json new file mode 100644 index 00000000..8ab89962 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.xml new file mode 100644 index 00000000..3c9d10d6 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-license-1.3.xml @@ -0,0 +1,11 @@ + + + + + + Apache-2.0 + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.json new file mode 100644 index 00000000..e4c69498 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.xml new file mode 100644 index 00000000..c94d01c9 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-manufacture-1.3.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.json new file mode 100644 index 00000000..103882ca --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.xml new file mode 100644 index 00000000..1235f4c2 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-supplier-1.3.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.json new file mode 100644 index 00000000..8f47f110 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.xml new file mode 100644 index 00000000..88134921 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-timestamp-1.3.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07T07:01:00Z + + + diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.json b/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.json new file mode 100644 index 00000000..61bcaec3 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.json @@ -0,0 +1,26 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.xml b/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.xml new file mode 100644 index 00000000..8c2d17fe --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-metadata-tool-1.3.xml @@ -0,0 +1,17 @@ + + + + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.json b/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.json new file mode 100644 index 00000000..6a9e646d --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.xml b/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.xml new file mode 100644 index 00000000..6a948029 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-minimal-viable-1.3.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.3/valid-patch-1.3.json b/tests/_data/schemaTestData/1.3/valid-patch-1.3.json new file mode 100644 index 00000000..eebdf67a --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-patch-1.3.json @@ -0,0 +1,88 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + }, + { + "type": "backport", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "security", + "id": "CVE-2019-9997", + "name": "CVE-2019-9997", + "description": "blah blah", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + }, + { + "type": "defect", + "id": "JIRA-874319", + "description": "Enable to do something", + "source": { + "name": "Example Org", + "url": "https://issues.example.org/874319" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-patch-1.3.xml b/tests/_data/schemaTestData/1.3/valid-patch-1.3.xml new file mode 100644 index 00000000..d6e1f442 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-patch-1.3.xml @@ -0,0 +1,70 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + blah + uri/to/changes.diff + + + + CVE-2019-9997 + CVE-2019-9997 + blah blah + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + http://some/other/site-1 + http://some/other/site-2 + + + + JIRA-874319 + Enable to do something + + Example Org + https://issues.example.org/874319 + + + http://some/other/site-1 + http://some/other/site-2 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-properties-1.3.json b/tests/_data/schemaTestData/1.3/valid-properties-1.3.json new file mode 100644 index 00000000..f30e2dbe --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-properties-1.3.json @@ -0,0 +1,55 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "properties": [ + { + "name": "Foo", + "value": "Bar" + }, + { + "name": "Foo", + "value": "You" + }, + { + "name": "Foo", + "value": "Two" + }, + { + "name": "Bar", + "value": "Foo" + } + ] + }, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "properties": [ + { + "name": "Foo", + "value": "Bar" + } + ] + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "group": "org.partner", + "name": "Stock ticker service", + "endpoints": [ + "https://partner.org/api/v1/stock" + ], + "properties": [ + { + "name": "Foo", + "value": "Bar" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-properties-1.3.xml b/tests/_data/schemaTestData/1.3/valid-properties-1.3.xml new file mode 100644 index 00000000..79d49c2e --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-properties-1.3.xml @@ -0,0 +1,34 @@ + + + + + Bar + You + Two + Foo + + + + + acme-library + 1.0.0 + + Bar + Foo + + + + + + org.partner + Stock ticker service + + https://partner.org/api/v1/stock + + + Bar + Foo + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-random-attributes-1.3.xml b/tests/_data/schemaTestData/1.3/valid-random-attributes-1.3.xml new file mode 100644 index 00000000..b07d29db --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-random-attributes-1.3.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-service-1.3.json b/tests/_data/schemaTestData/1.3/valid-service-1.3.json new file mode 100644 index 00000000..1a627c4c --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-service-1.3.json @@ -0,0 +1,101 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "stock-java-client", + "version": "1.0.12", + "hashes": [ + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "purl": "pkg:maven/com.acme/stock-java-client@1.0.12" + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "name": "Partner Org", + "url": [ + "https://partner.org" + ], + "contact": [ + { + "name": "Support", + "email": "support@partner", + "phone": "800-555-1212" + } + ] + }, + "group": "org.partner", + "name": "Stock ticker service", + "version": "2020-Q2", + "description": "Provides real-time stock information", + "endpoints": [ + "https://partner.org/api/v1/lookup", + "https://partner.org/api/v1/stock" + ], + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "PII", + "flow": "inbound" + }, + { + "classification": "PIFI", + "flow": "outbound" + }, + { + "classification": "pubic", + "flow": "bi-directional" + }, + { + "classification": "partner-data", + "flow": "unknown" + } + ], + "licenses": [ + { + "license": { + "name": "Partner license" + } + } + ], + "externalReferences": [ + { + "type": "website", + "url": "http://partner.org" + }, + { + "type": "documentation", + "url": "http://api.partner.org/swagger" + } + ] + } + ], + "dependencies": [ + { + "ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "dependsOn": [ + "b2a46a4b-8367-4bae-9820-95557cfe03a8" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-service-1.3.xml b/tests/_data/schemaTestData/1.3/valid-service-1.3.xml new file mode 100644 index 00000000..5fe3aa5e --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-service-1.3.xml @@ -0,0 +1,66 @@ + + + + + com.acme + stock-java-client + 1.0.12 + + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + + + + Apache-2.0 + + + pkg:maven/com.acme/stock-java-client@1.0.12 + + + + + + Partner Org + https://partner.org + + Support + support@partner + 800-555-1212 + + + org.partner + Stock ticker service + 2020-Q2 + Provides real-time stock information + + https://partner.org/api/v1/lookup + https://partner.org/api/v1/stock + + true + true + + PII + PIFI + pubic + partner-data + + + + Partner license + + + + + http://partner.org + + + http://api.partner.org/swagger + + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.json b/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.json new file mode 100644 index 00000000..72c9ceae --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "contact": [ + ] + }, + "name": "Stock ticker service", + "endpoints": [ + ], + "data": [ + ], + "externalReferences": [ + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.xml b/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.xml new file mode 100644 index 00000000..c5cdb1fb --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-service-empty-objects-1.3.xml @@ -0,0 +1,16 @@ + + + + + + + Stock ticker service + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.3/valid-xml-signature-1.3.xml b/tests/_data/schemaTestData/1.3/valid-xml-signature-1.3.xml new file mode 100644 index 00000000..24801812 --- /dev/null +++ b/tests/_data/schemaTestData/1.3/valid-xml-signature-1.3.xml @@ -0,0 +1,177 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + Initial commit + + + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + blah + fdaf + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + + + + + + + + + + PrB8/rofGs34XwIX5OIdYSjV2aKSe5VaztJKBvsgjIk= + + + + ePGNg30Zl9CW7RZdcRn8gFCp1AlWncjudA9pQDXyqZOvyj9RC2YtkI688WdfDOdVRZs6mflJFXr7 + IKA9wY6jVrEqZmlef55Qp/8iGwOjOjWbwYsm2AhrdkUi9gaFSWEd8uITYHOpWbiPFSsnimiK9+ft + 56dkg/oJMLdXzlaukzq9iGkRcafRkW433OQcZIXwD2K8lg4cdD0pNNNqBa+PgIvzbxA5H84TyQDB + HBcQiw/j1edRBJgPOwlqzZDUawOJaFhAPUQ+GGKMetIJH2FqqrHXGuV1NIwnbWTCg40RdOcBdCrl + PDtDVjFh34uZ4dYBpJBIlM4daD2N4B6WPB5iHRyuZTczF2q03ObabuTgkpK6EeadFVqFNsEOOPPt + MDDyda+Lwff5KjvUHvRRtUDIOm2rNIQKzaseulwYcA9UWQHAFcupJmWcLLM4zzY7F/uOdZuSurzh + U6h5kdb76Juepof6ee4Q5YpwNOGNL5JfB4C3sc/Dbbv8dZ8OuXFYSZN7reUGZzCNksByqERPEbAe + n1ldJu1HnRXRQpwaon8Asy9CuNmPfFCfDwOs2B4p4tb+tLNIKFHdRlpd19Zr9vCMCbltXeqq0Cpq + OejSyLYGqSWzzzUh449dJrg6KTevrTNEln5GAlLBFSdjM5JA7KV2u/GyDVFwSEW7UKooGN4CtgU= + + + + CN=bomsigner,OU=development,O=cyclonedx + + MIIE+DCCAuCgAwIBAgIEXGzayTANBgkqhkiG9w0BAQsFADA+MRIwEAYDVQQKDAljeWNsb25lZHgx + FDASBgNVBAsMC2RldmVsb3BtZW50MRIwEAYDVQQDDAlib21zaWduZXIwHhcNMTkwMjIwMDQ0MjQ5 + WhcNNDkwMjIwMDQ0MjQ5WjA+MRIwEAYDVQQKDAljeWNsb25lZHgxFDASBgNVBAsMC2RldmVsb3Bt + ZW50MRIwEAYDVQQDDAlib21zaWduZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo + 5JZsM4ZLfWW/dpRlU6CpnItWspddF+bEVDETKVwVj9tGpqR5jURgKS/BOQP2TGUsR3/ZJJBhYRll + ONhrUQrVKV/I6wp3Z40qPEa1RJLE+QlG9iL8qBV52CnXkLmnUSax3dspSzmSct5vDiTnvpHG9jr0 + AKFeTjy7U9rv8GJybz0ijwlpBoO9JRdYPX2PrrzoSeJLoxKq+GwuyCZ5LhXRN0p1a+NAirTAmY+c + G1ZTLkMmfeCUy1t6H/bG4RnYOSSPOvk7Rb68lQpUqb+pbbNuB2o/b9cDwtLLCtGVlu+5Wj8mrytY + 3FGFQM20j3yVeRInmGqTTDBelQa/CO4JKqBlmaeYEIvNYbFs9+AlqadivwDO51RpdPo9fPSpsBpy + ZMv6S2bXNuUML+Rk99WyKJTPM0PTZhRLZ64ZXEhlz3kQWVoSlrcwwim6sj6LRUb5IRqA3lxRFUI6 + NXKyiQLamQp+t3/9OGW9L1rLCcw7yFo0s8LhMTPMiv4ol9/hQViT+8ICzDsr0OM9ZiF4/UagFRlt + IClV70cjh1DpsZjzQIRVGaj8uQ/JdtfRz4E43Ki7U0a2Vpho/t6poLVndv46tkX5nYGtMW4WfMoD + ZflQ9pajvvKtr2jB1wob6nsU+VTmAcWZy4BCPH+XyfDw/0SFBdUceJJJtPWIeYFDUY7onptf+wID + AQABMA0GCSqGSIb3DQEBCwUAA4ICAQCOVariNgK+9OF/5T9ZaSvZbkk45RTmzgQNXtFc5xfRvqwP + s+pu/DFXm1R+ltjyS5j3w6NBZUFUI5MqLQr6JEEDrbu8BvfBO57wJNAEATj1JIHEfDfh7BxnBF8f + oYFOwbrh4jOt0wz0FW2obsSVmF4GSvS7tTlWqTcsxjdZVmwP40RWu18B9jzv7M61adrWD3ksDA5O + amSOsZi3Nt0aacDkyGRdCIEFi0fplxQInXMtD1z3RhXu2JSTAIr54Cei49Bh71kAXSWHMCog/f8a + lSrZyqZBty/ACfU9DqlPIM+giHePKm4z2bcdpUdKZk6wcKDn4CvuBOqsMBMg7L05UEyyqTPD/4dk + 2GwJ8Nv0E5gsYHCIXF2cZ3OUVsw0mB/ozleEJVDE02uZZN/1wW1Xq028LsMdgN0Wk1WvWyF5MEdh + nPWuhqp6tNaDI/kK6XQF+LjYJUzua3AQFOHfYNLKhO6d+bJ4rr0833v4v3cLW34kbXkKb6U3Yv8X + SK3jBGCACiPgnc0N6awkh1kDlrZQ7GMsl14c+2+vpl9Lf0sL0mRUIyICfSC8MjlsP/BZH3emyfsk + iWivPALomycKqP+PSkt1WaWApGENZWk1wNN99FYSYlt6LViW2p6T97fRx4jPRlHu+wecfD2k9RP4 + bt5W2HWfOP0zNAS7SnAVLEl2QZxXKw== + + + + + + qOSWbDOGS31lv3aUZVOgqZyLVrKXXRfmxFQxEylcFY/bRqakeY1EYCkvwTkD9kxlLEd/2SSQYWEZ + ZTjYa1EK1SlfyOsKd2eNKjxGtUSSxPkJRvYi/KgVedgp15C5p1Emsd3bKUs5knLebw4k576RxvY6 + 9AChXk48u1Pa7/Bicm89Io8JaQaDvSUXWD19j6686EniS6MSqvhsLsgmeS4V0TdKdWvjQIq0wJmP + nBtWUy5DJn3glMtbeh/2xuEZ2Dkkjzr5O0W+vJUKVKm/qW2zbgdqP2/XA8LSywrRlZbvuVo/Jq8r + WNxRhUDNtI98lXkSJ5hqk0wwXpUGvwjuCSqgZZmnmBCLzWGxbPfgJamnYr8AzudUaXT6PXz0qbAa + cmTL+ktm1zblDC/kZPfVsiiUzzND02YUS2euGVxIZc95EFlaEpa3MMIpurI+i0VG+SEagN5cURVC + OjVysokC2pkKfrd//ThlvS9aywnMO8haNLPC4TEzzIr+KJff4UFYk/vCAsw7K9DjPWYheP1GoBUZ + bSApVe9HI4dQ6bGY80CEVRmo/LkPyXbX0c+BONyou1NGtlaYaP7eqaC1Z3b+OrZF+Z2BrTFuFnzK + A2X5UPaWo77yra9owdcKG+p7FPlU5gHFmcuAQjx/l8nw8P9EhQXVHHiSSbT1iHmBQ1GO6J6bX/s= + + AQAB + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-bomformat-1.4.json b/tests/_data/schemaTestData/1.4/invalid-bomformat-1.4.json new file mode 100644 index 00000000..6959cab0 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-bomformat-1.4.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "AnotherFormat", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.json b/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.json new file mode 100644 index 00000000..3be019a3 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.xml new file mode 100644 index 00000000..d4417909 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-ref-1.4.xml @@ -0,0 +1,15 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.json b/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.json new file mode 100644 index 00000000..4ad023c5 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.json @@ -0,0 +1,18 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.xml new file mode 100644 index 00000000..5ba6401e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-swid-1.4.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.json b/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.json new file mode 100644 index 00000000..7c7bd8bb --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.json @@ -0,0 +1,13 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "foo", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.xml new file mode 100644 index 00000000..4f82adfe --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-component-type-1.4.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.json b/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.json new file mode 100644 index 00000000..1e5f12a1 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.json @@ -0,0 +1,37 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.xml new file mode 100644 index 00000000..3c9e0049 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-dependency-1.4.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.json b/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.json new file mode 100644 index 00000000..2bbf057b --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.json @@ -0,0 +1,11 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.xml new file mode 100644 index 00000000..8d82fe53 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-empty-component-1.4.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.json b/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.json new file mode 100644 index 00000000..9cb10fb0 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "FOO", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.xml new file mode 100644 index 00000000..51fd9fed --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-alg-1.4.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.json b/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.json new file mode 100644 index 00000000..07d0ac03 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "foo" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.xml new file mode 100644 index 00000000..d964a592 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-md5-1.4.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + foo + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.json b/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.json new file mode 100644 index 00000000..9342157a --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "foo" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.xml new file mode 100644 index 00000000..0c6c2814 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha1-1.4.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + foo + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.json b/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.json new file mode 100644 index 00000000..a3a9a9dc --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "foo" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.xml new file mode 100644 index 00000000..e753128e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha256-1.4.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + foo + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.json b/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.json new file mode 100644 index 00000000..fdf1f5b8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.json @@ -0,0 +1,32 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "foo" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.xml new file mode 100644 index 00000000..0339763d --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-hash-sha512-1.4.xml @@ -0,0 +1,16 @@ + + + + + acme-library + 1.0.0 + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + foo + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.json b/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.json new file mode 100644 index 00000000..e1f02ce8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "foo", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.xml new file mode 100644 index 00000000..0e005c28 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-issue-type-1.4.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.json b/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.json new file mode 100644 index 00000000..82fcfdba --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.json @@ -0,0 +1,23 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.xml new file mode 100644 index 00000000..83e4e379 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-choice-1.4.xml @@ -0,0 +1,26 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.json b/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.json new file mode 100644 index 00000000..ce76280f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.json @@ -0,0 +1,28 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base85", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.xml new file mode 100644 index 00000000..95bd2bcb --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-encoding-1.4.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.json b/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.json new file mode 100644 index 00000000..ed317a5b --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.xml new file mode 100644 index 00000000..68ca8efa --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-id-1.4.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-license-id-count-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-license-id-count-1.4.xml new file mode 100644 index 00000000..27f73e5d --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-id-count-1.4.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + MIT + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-license-name-count-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-license-name-count-1.4.xml new file mode 100644 index 00000000..e986db56 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-license-name-count-1.4.xml @@ -0,0 +1,27 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.json b/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.json new file mode 100644 index 00000000..0ea6d35a --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "licenses": [ + { + "license": { + "id": "Apache-2" + } + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.xml new file mode 100644 index 00000000..51cbe10e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-metadata-license-1.4.xml @@ -0,0 +1,11 @@ + + + + + + Apache-2 + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.json b/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.json new file mode 100644 index 00000000..22ce0aa8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.xml new file mode 100644 index 00000000..544abc19 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-metadata-timestamp-1.4.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07 + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.json b/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.json new file mode 100644 index 00000000..eee0ac3a --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.json @@ -0,0 +1,12 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.xml new file mode 100644 index 00000000..7200d4ad --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-missing-component-type-1.4.xml @@ -0,0 +1,9 @@ + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-namespace-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-namespace-1.4.xml new file mode 100644 index 00000000..9e42be40 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-namespace-1.4.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.json b/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.json new file mode 100644 index 00000000..1e35b095 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "foo", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.xml new file mode 100644 index 00000000..0e8a30d1 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-patch-type-1.4.xml @@ -0,0 +1,37 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-scope-1.4.json b/tests/_data/schemaTestData/1.4/invalid-scope-1.4.json new file mode 100644 index 00000000..7a9faeac --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-scope-1.4.json @@ -0,0 +1,14 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "scope": "foo" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-scope-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-scope-1.4.xml new file mode 100644 index 00000000..9c34b135 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-scope-1.4.xml @@ -0,0 +1,10 @@ + + + + + acme-library + 1.0.0 + foo + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.json b/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.json new file mode 100644 index 00000000..42569ecd --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.xml new file mode 100644 index 00000000..c4637f26 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-serialnumber-1.4.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.json b/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.json new file mode 100644 index 00000000..3cc11be1 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "name": "Stock ticker service", + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "foo", + "flow": "bar" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.xml b/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.xml new file mode 100644 index 00000000..d999dca9 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/invalid-service-data-1.4.xml @@ -0,0 +1,11 @@ + + + + + Stock ticker service + + bar + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-assembly-1.4.json b/tests/_data/schemaTestData/1.4/valid-assembly-1.4.json new file mode 100644 index 00000000..6d8f8227 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-assembly-1.4.json @@ -0,0 +1,30 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library-a", + "version": "1.0.0", + "components": [ + { + "type": "library", + "name": "acme-library-b", + "version": "2.0.0" + } + ] + } + ], + "services": [ + { + "name": "acme-service-a", + "services": [ + { + "name": "acme-service-b" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-assembly-1.4.xml b/tests/_data/schemaTestData/1.4/valid-assembly-1.4.xml new file mode 100644 index 00000000..7aa65a3f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-assembly-1.4.xml @@ -0,0 +1,25 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 2.0.0 + + + + + + + acme-service-a + + + acme-service-b + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-bom-1.4.json b/tests/_data/schemaTestData/1.4/valid-bom-1.4.json new file mode 100644 index 00000000..a6494a7b --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-bom-1.4.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-bom-1.4.xml b/tests/_data/schemaTestData/1.4/valid-bom-1.4.xml new file mode 100644 index 00000000..a675a967 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-bom-1.4.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.json b/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.json new file mode 100644 index 00000000..af90bd1f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.json @@ -0,0 +1,63 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-example", + "version": "1.0.0", + "hashes": [ + { + "alg": "MD5", + "content": "641b6e166f8b33c5e959e2adcc18b1c7" + }, + { + "alg": "SHA-1", + "content": "9188560f22e0b73070d2efce670c74af2bdf30af" + }, + { + "alg": "SHA-256", + "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" + }, + { + "alg": "SHA-384", + "content": "d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" + }, + { + "alg": "SHA-512", + "content": "74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" + }, + { + "alg": "SHA3-256", + "content": "7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa" + }, + { + "alg": "SHA3-384", + "content": "a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5" + }, + { + "alg": "SHA3-512", + "content": "7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20" + }, + { + "alg": "BLAKE2b-256", + "content": "d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237" + }, + { + "alg": "BLAKE2b-384", + "content": "e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a" + }, + { + "alg": "BLAKE2b-512", + "content": "f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d" + }, + { + "alg": "BLAKE3", + "content": "26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.xml b/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.xml new file mode 100644 index 00000000..5def2ebd --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-hashes-1.4.xml @@ -0,0 +1,23 @@ + + + + + acme-example + 1.0.0 + + 641b6e166f8b33c5e959e2adcc18b1c7 + 9188560f22e0b73070d2efce670c74af2bdf30af + d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964 + d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad + 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6 + 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa + a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5 + 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20 + d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237 + e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a + f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d + 26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.json b/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.json new file mode 100644 index 00000000..f21c7fb7 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "bom-ref": "123", + "name": "acme-library", + "version": "1.0.0" + }, + { + "type": "library", + "bom-ref": "456", + "name": "acme-library", + "version": "1.0.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.xml b/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.xml new file mode 100644 index 00000000..9c66ef41 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-ref-1.4.xml @@ -0,0 +1,19 @@ + + + + + acme-library + 1.0.0 + + + acme-library + 1.0.0 + + + + + acme-library + 1.0.0 + + + diff --git a/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.json b/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.json new file mode 100644 index 00000000..fd037a2f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.json @@ -0,0 +1,19 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1" + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.xml b/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.xml new file mode 100644 index 00000000..f651bab2 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-swid-1.4.xml @@ -0,0 +1,11 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.json b/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.json new file mode 100644 index 00000000..fe6de237 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.json @@ -0,0 +1,24 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.xml b/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.xml new file mode 100644 index 00000000..e0d968dd --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-swid-full-1.4.xml @@ -0,0 +1,13 @@ + + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-component-types-1.4.json b/tests/_data/schemaTestData/1.4/valid-component-types-1.4.json new file mode 100644 index 00000000..dfcc9bcd --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-types-1.4.json @@ -0,0 +1,48 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "name": "application-a", + "version": "1.0" + }, + { + "type": "library", + "name": "library-a", + "version": "1.0" + }, + { + "type": "framework", + "name": "framework-a", + "version": "1.0" + }, + { + "type": "container", + "name": "container-a", + "version": "1.0" + }, + { + "type": "operating-system", + "name": "operating-system-a", + "version": "1.0" + }, + { + "type": "firmware", + "name": "firmware-a", + "version": "1.0" + }, + { + "type": "device", + "name": "device-a", + "version": "1.0" + }, + { + "type": "file", + "name": "file-a", + "version": "1.0" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-component-types-1.4.xml b/tests/_data/schemaTestData/1.4/valid-component-types-1.4.xml new file mode 100644 index 00000000..2c41ad6e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-component-types-1.4.xml @@ -0,0 +1,37 @@ + + + + + application-a + 1.0 + + + library-a + 1.0 + + + framework-a + 1.0 + + + container-a + 1.0 + + + operating-system-a + 1.0 + + + firmware-a + 1.0 + + + device-a + 1.0 + + + file-a + 1.0 + + + diff --git a/tests/_data/schemaTestData/1.4/valid-compositions-1.4.json b/tests/_data/schemaTestData/1.4/valid-compositions-1.4.json new file mode 100644 index 00000000..ed86e490 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-compositions-1.4.json @@ -0,0 +1,65 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "component": { + "bom-ref": "acme-application-1.0", + "type": "application", + "name": "Acme Application", + "version": "1.0" + } + }, + "components": [ + { + "bom-ref": "pkg:maven/partner/shaded-library@1.0", + "type": "library", + "name": "Partner Shaded Library", + "version": "1.0", + "purl": "pkg:maven/partner/shaded-library@1.0", + "components": [ + { + "bom-ref": "pkg:maven/ossproject/library@2.0", + "type": "library", + "name": "Some Opensource Library", + "version": "2.0", + "purl": "pkg:maven/ossproject/library@2.0" + } + ] + }, + { + "bom-ref": "pkg:maven/acme/library@3.0", + "type": "library", + "name": "Acme Library", + "version": "3.0", + "purl": "pkg:maven/acme/library@3.0" + } + ], + "dependencies": [ + { + "ref": "acme-application-1.0", + "dependsOn": [ + "pkg:maven/partner/shaded-library@1.0", + "pkg:maven/acme/library@3.0" + ] + } + ], + "compositions": [ + { + "aggregate": "complete", + "assemblies": [ + "pkg:maven/partner/shaded-library@1.0" + ], + "dependencies": [ + "acme-application-1.0" + ] + }, + { + "aggregate": "unknown", + "assemblies": [ + "pkg:maven/acme/library@3.0" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-compositions-1.4.xml b/tests/_data/schemaTestData/1.4/valid-compositions-1.4.xml new file mode 100644 index 00000000..ae0b0ef8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-compositions-1.4.xml @@ -0,0 +1,51 @@ + + + + + Acme Application + 1.0 + + + + + Partner Shaded Library + 1.0 + pkg:maven/partner/shaded-library@1.0 + + + Some Opensource Library + 2.0 + pkg:maven/ossproject/library@2.0 + + + + + Acme Library + 2.0 + pkg:maven/acme/library@3.0 + + + + + + + + + + + complete + + + + + + + + + unknown + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-dependency-1.4.json b/tests/_data/schemaTestData/1.4/valid-dependency-1.4.json new file mode 100644 index 00000000..b15c6b92 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-dependency-1.4.json @@ -0,0 +1,38 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "library-a", + "type": "library", + "name": "library-a", + "version": "1.0.0" + }, + { + "bom-ref": "library-b", + "type": "library", + "name": "library-b", + "version": "1.0.0" + }, + { + "bom-ref": "library-c", + "type": "library", + "name": "library-c", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "library-a", + "dependsOn": [] + }, + { + "ref": "library-b", + "dependsOn": [ + "library-c" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-dependency-1.4.xml b/tests/_data/schemaTestData/1.4/valid-dependency-1.4.xml new file mode 100644 index 00000000..7e4bc15f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-dependency-1.4.xml @@ -0,0 +1,23 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 1.0.0 + + + acme-library-b + 1.0.0 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.json b/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.json new file mode 100644 index 00000000..0cc93e13 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.xml b/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.xml new file mode 100644 index 00000000..5789e04c --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-empty-components-1.4.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-evidence-1.4.json b/tests/_data/schemaTestData/1.4/valid-evidence-1.4.json new file mode 100644 index 00000000..a588fdd2 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-evidence-1.4.json @@ -0,0 +1,53 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "application", + "group": "com.google.code.findbugs", + "name": "findbugs-project", + "version": "3.0.0", + "licenses": [ + { + "license": { + "id": "LGPL-3.0-or-later", + "url": "https://www.gnu.org/licenses/lgpl-3.0-standalone.html" + } + } + ], + "purl": "pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0", + "evidence": { + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + } + }, + { + "license": { + "id": "LGPL-2.1-only", + "url": "https://opensource.org/licenses/LGPL-2.1" + } + } + ], + "copyright": [ + { + "text": "Copyright 2012 Google Inc. All Rights Reserved." + }, + { + "text": "Copyright (C) 2004,2005 Dave Brosius " + }, + { + "text": "Copyright (C) 2005 William Pugh" + }, + { + "text": "Copyright (C) 2004,2005 University of Maryland" + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-evidence-1.4.xml b/tests/_data/schemaTestData/1.4/valid-evidence-1.4.xml new file mode 100644 index 00000000..3e03c8c3 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-evidence-1.4.xml @@ -0,0 +1,35 @@ + + + + + com.google.code.findbugs + findbugs-project + 3.0.0 + + + LGPL-3.0-or-later + https://www.gnu.org/licenses/lgpl-3.0-standalone.html + + + pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0 + + + + Apache-2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + + + + + ]]> + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-external-elements-1.4.xml b/tests/_data/schemaTestData/1.4/valid-external-elements-1.4.xml new file mode 100644 index 00000000..25c7e5b7 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-external-elements-1.4.xml @@ -0,0 +1,158 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + Banana + + + Banana + + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + Banana + + + Banana + + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + Banana + + + Banana + + + + Banana + + + Banana + + + + + foo + 1.0 + + + Banana + + + Banana + + + + + bar + 1.0 + + + Banana + + + Banana + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + Banana + + + Banana + + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Banana + + + Banana + + + Initial commit + + Banana + + + Banana + + + + Banana + + + Banana + + + Commentary here + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + + + Banana + + + Banana + + diff --git a/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.json b/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.json new file mode 100644 index 00000000..088172ea --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.json @@ -0,0 +1,38 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0", + "externalReferences": [ + { + "type": "advisories", + "url": "https://example.org/security/feed/csaf", + "comment": "Security advisories from the vendor" + }, + { + "type": "bom", + "url": "https://example.org/support/sbom/portal-server/1.0.0", + "comment": "An external SBOM that describes what this component includes", + "hashes": [ + { + "alg": "SHA-256", + "content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313" + } + ] + }, + { + "type": "documentation", + "url": "https://example.org/support/documentation/portal-server/1.0.0", + "comment": "Vendor provided documentation for the product" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.xml b/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.xml new file mode 100644 index 00000000..7e9ec93e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-external-reference-1.4.xml @@ -0,0 +1,27 @@ + + + + + org.example + mylibrary + 1.0.0 + + + https://example.org/security/feed/csaf + Security advisories from the vendor + + + https://example.org/support/sbom/portal-server/1.0.0 + An external SBOM that describes what this component includes + + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + + + + https://example.org/support/documentation/portal-server/1.0.0 + Vendor provided documentation for the product + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.json b/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.json new file mode 100644 index 00000000..c101ebe9 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.json @@ -0,0 +1,20 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.xml b/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.xml new file mode 100644 index 00000000..6e939d32 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-expression-1.4.xml @@ -0,0 +1,23 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/valid-license-id-1.4.json b/tests/_data/schemaTestData/1.4/valid-license-id-1.4.json new file mode 100644 index 00000000..1d097485 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-id-1.4.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-license-id-1.4.xml b/tests/_data/schemaTestData/1.4/valid-license-id-1.4.xml new file mode 100644 index 00000000..e0b514f4 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-id-1.4.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/valid-license-name-1.4.json b/tests/_data/schemaTestData/1.4/valid-license-name-1.4.json new file mode 100644 index 00000000..03c884ca --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-name-1.4.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "licenses": [ + { + "license": { + "name": "Apache License 2.0" + } + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-license-name-1.4.xml b/tests/_data/schemaTestData/1.4/valid-license-name-1.4.xml new file mode 100644 index 00000000..7feade6b --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-license-name-1.4.xml @@ -0,0 +1,25 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache License 2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.json new file mode 100644 index 00000000..febeed4f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.xml new file mode 100644 index 00000000..807fc5c6 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-author-1.4.xml @@ -0,0 +1,13 @@ + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.json new file mode 100644 index 00000000..10e75af0 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.json @@ -0,0 +1,16 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.xml new file mode 100644 index 00000000..295389f8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-license-1.4.xml @@ -0,0 +1,11 @@ + + + + + + Apache-2.0 + + + + + \ No newline at end of file diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.json new file mode 100644 index 00000000..68705c41 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.xml new file mode 100644 index 00000000..36b70a5b --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-manufacture-1.4.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.json new file mode 100644 index 00000000..33b1af25 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.json @@ -0,0 +1,21 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.xml new file mode 100644 index 00000000..37a222da --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-supplier-1.4.xml @@ -0,0 +1,14 @@ + + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.json new file mode 100644 index 00000000..26ab14ad --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00" + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.xml new file mode 100644 index 00000000..06adc1b0 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-timestamp-1.4.xml @@ -0,0 +1,7 @@ + + + + 2020-04-07T07:01:00Z + + + diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.json b/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.json new file mode 100644 index 00000000..19175ee0 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.json @@ -0,0 +1,26 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ] + }, + "components": [] +} diff --git a/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.xml b/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.xml new file mode 100644 index 00000000..ead4ea0d --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-metadata-tool-1.4.xml @@ -0,0 +1,17 @@ + + + + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.json b/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.json new file mode 100644 index 00000000..c1029f0f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.json @@ -0,0 +1,12 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-library" + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.xml b/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.xml new file mode 100644 index 00000000..92ac5cc7 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-minimal-viable-1.4.xml @@ -0,0 +1,8 @@ + + + + + acme-library + + + diff --git a/tests/_data/schemaTestData/1.4/valid-patch-1.4.json b/tests/_data/schemaTestData/1.4/valid-patch-1.4.json new file mode 100644 index 00000000..66db19aa --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-patch-1.4.json @@ -0,0 +1,88 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "group": "com.acme", + "name": "sample-library", + "version": "1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "group": "org.example", + "name": "sample-library", + "version": "1.0.0" + } + ], + "patches": [ + { + "type": "unofficial", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.acme.org/17240" + } + } + ] + }, + { + "type": "backport", + "diff": { + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "blah" + }, + "url": "uri/to/changes.diff" + }, + "resolves": [ + { + "type": "security", + "id": "CVE-2019-9997", + "name": "CVE-2019-9997", + "description": "blah blah", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + }, + { + "type": "defect", + "id": "JIRA-874319", + "description": "Enable to do something", + "source": { + "name": "Example Org", + "url": "https://issues.example.org/874319" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + } + ] + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-patch-1.4.xml b/tests/_data/schemaTestData/1.4/valid-patch-1.4.xml new file mode 100644 index 00000000..7c0a3d77 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-patch-1.4.xml @@ -0,0 +1,70 @@ + + + + + com.acme + sample-library + 1.0.0 + + + + org.example + sample-library + 1.0.0 + + + + + + blah + uri/to/changes.diff + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.acme.org/17240 + + + + + + + blah + uri/to/changes.diff + + + + CVE-2019-9997 + CVE-2019-9997 + blah blah + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + http://some/other/site-1 + http://some/other/site-2 + + + + JIRA-874319 + Enable to do something + + Example Org + https://issues.example.org/874319 + + + http://some/other/site-1 + http://some/other/site-2 + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-properties-1.4.json b/tests/_data/schemaTestData/1.4/valid-properties-1.4.json new file mode 100644 index 00000000..bdf67f7e --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-properties-1.4.json @@ -0,0 +1,55 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "properties": [ + { + "name": "Foo", + "value": "Bar" + }, + { + "name": "Foo", + "value": "You" + }, + { + "name": "Foo", + "value": "Two" + }, + { + "name": "Bar", + "value": "Foo" + } + ] + }, + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "properties": [ + { + "name": "Foo", + "value": "Bar" + } + ] + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "group": "org.partner", + "name": "Stock ticker service", + "endpoints": [ + "https://partner.org/api/v1/stock" + ], + "properties": [ + { + "name": "Foo", + "value": "Bar" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-properties-1.4.xml b/tests/_data/schemaTestData/1.4/valid-properties-1.4.xml new file mode 100644 index 00000000..38d41faf --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-properties-1.4.xml @@ -0,0 +1,34 @@ + + + + + Bar + You + Two + Foo + + + + + acme-library + 1.0.0 + + Bar + Foo + + + + + + org.partner + Stock ticker service + + https://partner.org/api/v1/stock + + + Bar + Foo + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-random-attributes-1.4.xml b/tests/_data/schemaTestData/1.4/valid-random-attributes-1.4.xml new file mode 100644 index 00000000..428692ad --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-random-attributes-1.4.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.json b/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.json new file mode 100644 index 00000000..bd45f940 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.json @@ -0,0 +1,194 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-example", + "version": "1.0.0", + "releaseNotes": { + "type": "major", + "title": "My new release", + "featuredImage": "https://example.com/featured_image.png", + "socialImage": "https://example.com/social_image.png", + "description": "The main description of your release", + "timestamp": "2021-09-17T00:51:18+00:00", + "aliases": [ + "Project Orion" + ], + "tags": [ + "CMS", + "SEO", + "wysiwyg" + ], + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.example.com/17240" + } + }, + { + "type": "security", + "id": "CVE-2019-9997", + "name": "CVE-2019-9997", + "description": "Great new feature that does something", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + } + ], + "notes": [ + { + "locale": "en-US", + "text": { + "contentType": "text/html", + "encoding": "base64", + "content": "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+" + } + }, + { + "locale": "es", + "text": { + "contentType": "text/html", + "encoding": "base64", + "content": "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4=" + } + } + ] + } + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "name": "Partner Org", + "url": [ + "https://partner.org" + ], + "contact": [ + { + "name": "Support", + "email": "support@partner.org", + "phone": "800-555-1212" + } + ] + }, + "group": "org.partner", + "name": "Stock ticker service", + "version": "2020-Q2", + "description": "Provides real-time stock information", + "endpoints": [ + "https://partner.org/api/v1/lookup", + "https://partner.org/api/v1/stock" + ], + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "PII", + "flow": "inbound" + }, + { + "classification": "PIFI", + "flow": "outbound" + }, + { + "classification": "pubic", + "flow": "bi-directional" + }, + { + "classification": "partner-data", + "flow": "unknown" + } + ], + "licenses": [ + { + "license": { + "name": "Partner license" + } + } + ], + "externalReferences": [ + { + "type": "website", + "url": "http://partner.org" + }, + { + "type": "documentation", + "url": "http://api.partner.org/swagger" + } + ], + "releaseNotes": { + "type": "major", + "title": "My new release", + "featuredImage": "https://example.com/featured_image.png", + "socialImage": "https://example.com/social_image.png", + "description": "The main description of your release", + "timestamp": "2021-09-17T00:51:18+00:00", + "aliases": [ + "Project Orion" + ], + "tags": [ + "CMS", + "SEO", + "wysiwyg" + ], + "resolves": [ + { + "type": "enhancement", + "id": "JIRA-17240", + "description": "Great new feature that does something", + "source": { + "name": "Acme Org", + "url": "https://issues.example.com/17240" + } + }, + { + "type": "security", + "id": "CVE-2019-9997", + "name": "CVE-2019-9997", + "description": "Great new feature that does something", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + }, + "references": [ + "http://some/other/site-1", + "http://some/other/site-2" + ] + } + ], + "notes": [ + { + "locale": "en-US", + "text": { + "contentType": "text/html", + "encoding": "base64", + "content": "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+" + } + }, + { + "locale": "es", + "text": { + "contentType": "text/html", + "encoding": "base64", + "content": "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4=" + } + } + ] + } + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.xml b/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.xml new file mode 100644 index 00000000..7102926f --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-release-notes-1.4.xml @@ -0,0 +1,149 @@ + + + + + acme-example + 1.0.0 + + major + My new release + https://example.com/featured_image.png + https://example.com/social_image.png + The main description of your release + 2021-09-17T00:51:18+00:00 + + Project Orion + + + CMS + SEO + wysiwyg + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.example.com/17240 + + + + CVE-2019-9997 + CVE-2019-9997 + A security issue was fixed that did something bad + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + http://some/other/site-1 + http://some/other/site-2 + + + + + + en-US + PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+ + + + es + PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= + + + + + + + + + Partner Org + https://partner.org + + Support + support@partner + 800-555-1212 + + + org.partner + Stock ticker service + 2020-Q2 + Provides real-time stock information + + https://partner.org/api/v1/lookup + https://partner.org/api/v1/stock + + true + true + + PII + PIFI + pubic + partner-data + + + + Partner license + + + + + http://partner.org + + + http://api.partner.org/swagger + + + + major + My new release + https://example.com/featured_image.png + https://example.com/social_image.png + The main description of your release + 2021-09-17T00:51:18+00:00 + + Project Orion + + + CMS + SEO + wysiwyg + + + + JIRA-17240 + Great new feature that does something + + Acme Org + https://issues.example.com/17240 + + + + CVE-2019-9997 + CVE-2019-9997 + A security issue was fixed that did something bad + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + http://some/other/site-1 + http://some/other/site-2 + + + + + + en-US + PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+ + + + es + PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-service-1.4.json b/tests/_data/schemaTestData/1.4/valid-service-1.4.json new file mode 100644 index 00000000..2b23fce2 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-service-1.4.json @@ -0,0 +1,101 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "stock-java-client", + "version": "1.0.12", + "hashes": [ + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "purl": "pkg:maven/com.acme/stock-java-client@1.0.12" + } + ], + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "name": "Partner Org", + "url": [ + "https://partner.org" + ], + "contact": [ + { + "name": "Support", + "email": "support@partner.org", + "phone": "800-555-1212" + } + ] + }, + "group": "org.partner", + "name": "Stock ticker service", + "version": "2020-Q2", + "description": "Provides real-time stock information", + "endpoints": [ + "https://partner.org/api/v1/lookup", + "https://partner.org/api/v1/stock" + ], + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "PII", + "flow": "inbound" + }, + { + "classification": "PIFI", + "flow": "outbound" + }, + { + "classification": "pubic", + "flow": "bi-directional" + }, + { + "classification": "partner-data", + "flow": "unknown" + } + ], + "licenses": [ + { + "license": { + "name": "Partner license" + } + } + ], + "externalReferences": [ + { + "type": "website", + "url": "http://partner.org" + }, + { + "type": "documentation", + "url": "http://api.partner.org/swagger" + } + ] + } + ], + "dependencies": [ + { + "ref": "pkg:maven/com.acme/stock-java-client@1.0.12", + "dependsOn": [ + "b2a46a4b-8367-4bae-9820-95557cfe03a8" + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-service-1.4.xml b/tests/_data/schemaTestData/1.4/valid-service-1.4.xml new file mode 100644 index 00000000..c315ec04 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-service-1.4.xml @@ -0,0 +1,66 @@ + + + + + com.acme + stock-java-client + 1.0.12 + + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + + + + Apache-2.0 + + + pkg:maven/com.acme/stock-java-client@1.0.12 + + + + + + Partner Org + https://partner.org + + Support + support@partner + 800-555-1212 + + + org.partner + Stock ticker service + 2020-Q2 + Provides real-time stock information + + https://partner.org/api/v1/lookup + https://partner.org/api/v1/stock + + true + true + + PII + PIFI + pubic + partner-data + + + + Partner license + + + + + http://partner.org + + + http://api.partner.org/swagger + + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.json b/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.json new file mode 100644 index 00000000..c54c1efe --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.json @@ -0,0 +1,22 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "services": [ + { + "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", + "provider": { + "contact": [ + ] + }, + "name": "Stock ticker service", + "endpoints": [ + ], + "data": [ + ], + "externalReferences": [ + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.xml b/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.xml new file mode 100644 index 00000000..4c97cfa8 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-service-empty-objects-1.4.xml @@ -0,0 +1,16 @@ + + + + + + + Stock ticker service + + + + + + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-signatures-1.4.json b/tests/_data/schemaTestData/1.4/valid-signatures-1.4.json new file mode 100644 index 00000000..48dec3ef --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-signatures-1.4.json @@ -0,0 +1,78 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "5366293e-0740-4dcf-b1d0-0c1fc26e4981", + "type": "application", + "name": "amce app", + "version": "1.0", + "signature": { + "algorithm": "ES256", + "certificatePath": [ + "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", + "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" + ], + "value": "tqITqIm0gUMWXIjqDgwqzqPw1CwTUKRewZQ5YpX3VwFMWV68NJgX4npU91cSwSC-MRlx1QfOYwSQkeU26VpXSg" + } + } + ], + "services": [ + { + "bom-ref": "ee10d0a2-baba-4656-a5ac-d49e172a0d3d", + "group": "org.partner", + "name": "Stock ticker service", + "version": "2020-Q2", + "endpoints": [ + "https://partner.org/api/v1/lookup", + "https://partner.org/api/v1/stock" + ], + "authenticated": true, + "x-trust-boundary": true, + "data": [ + { + "classification": "PII", + "flow": "inbound" + } + ], + "signature": { + "algorithm": "ES256", + "certificatePath": [ + "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", + "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" + ], + "value": "6A77T3RBTAuVpZOgFFFfOvGOQ1hqMbfSQ91VucRM1RIP6QqX9kEF1Pi1_vCl37qpVzK51kIyppgUF_i9s999XA" + } + } + ], + "compositions": [ + { + "aggregate": "complete", + "assemblies": [ + "5366293e-0740-4dcf-b1d0-0c1fc26e4981", + "ee10d0a2-baba-4656-a5ac-d49e172a0d3d" + ], + "dependencies": [ + "5366293e-0740-4dcf-b1d0-0c1fc26e4981" + ], + "signature": { + "algorithm": "ES256", + "certificatePath": [ + "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", + "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" + ], + "value": "lm6wx-elyBTbNMKNF8riooZhvrm6f5j8JpvgP9JtVv50dd7sXQLH7PqJcn9fmKV8eoF8cszPllEsQQhEQOM4hA" + } + } + ], + "signature": { + "algorithm": "ES256", + "certificatePath": [ + "MIIB-TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8-g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV_5jRHsiBQWA-5DxEa-x_zJVRz8tpp-jjT2tSCU82bwUOBLu6te1YIDpWCA", + "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm-GFObe5Dk4t3Jrtk_Pbs8-3VW_4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw_WnJVa0ELXKICC73lkjskWPfE-cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p_2xK7veRubQEhG-nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH-DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB-Q75Jov1gVF3bScAbxb7Mw7tf5z3Cvqmfo0Gatkgzz6-jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia_pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY_DLAi4kaLyf9sHT_tkH-gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm-nq23NtHl5FbCzeXWcKRayIgimT-An1WIOeJP4F7-BctYLIooKoQzJZR1tOWvprUs22_xAivVBz7J_LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw" + ], + "value": "m4pMbQQVV61TlP4Og7a75SeY8lh00LkkUDXZ4PIhXsR512MPRgZmusFYorJlYq9wM3P9n9gM3T8BTg9XdFdQkQ" + } +} diff --git a/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.json b/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.json new file mode 100644 index 00000000..184a6641 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.json @@ -0,0 +1,140 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "bom-ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.4", + "type": "library", + "group": "com.fasterxml.jackson.core", + "name": "jackson-databind", + "version": "2.9.4", + "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.4" + } + ], + "vulnerabilities": [ + { + "bom-ref": "6eee14da-8f42-4cc4-bb65-203235f02415", + "id": "SNYK-JAVA-COMFASTERXMLJACKSONCORE-32111", + "source": { + "name": "Snyk", + "url": "https://snyk.io/vuln/SNYK-JAVA-COMFASTERXMLJACKSONCORE-32111" + }, + "references": [ + { + "id": "CVE-2018-7489", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" + } + } + ], + "ratings": [ + { + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.0" + }, + "score": 9.8, + "severity": "critical", + "method": "CVSSv3", + "vector": "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "justification": "An optional reason for rating the vulnerability as it was" + } + ], + "cwes": [ + 184, + 502 + ], + "description": "FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath.", + "detail": "", + "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.6.7.5, 2.8.11.1, 2.9.5 or higher.", + "advisories": [ + { + "title": "GitHub Commit", + "url": "https://github.com/FasterXML/jackson-databind/commit/6799f8f10cc78e9af6d443ed6982d00a13f2e7d2" + }, + { + "title": "GitHub Issue", + "url": "https://github.com/FasterXML/jackson-databind/issues/1931" + } + ], + "created": "2021-01-01T00:00:00.000Z", + "published": "2021-01-01T00:00:00.000Z", + "updated": "2021-01-01T00:00:00.000Z", + "credits": { + "organizations": [ + { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ] + } + ], + "individuals": [ + { + "name": "Jane Doe", + "email": "jane.doe@example.com" + } + ] + }, + "tools": [ + { + "vendor": "Snyk", + "name": "Snyk CLI (Linux)", + "version": "1.729.0", + "hashes": [ + { + "alg": "SHA-256", + "content": "2eaf8c62831a1658c95d41fdc683cd177c147733c64a93e59cb2362829e45b7d" + } + ] + } + ], + "analysis": { + "state": "not_affected", + "justification": "code_not_reachable", + "response": ["will_not_fix", "update"], + "detail": "An optional explanation of why the application is not affected by the vulnerable component." + }, + "affects": [ + { + "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.4", + "versions": [ + { + "range": "vers:semver/<2.6.7.5", + "status": "affected" + }, + { + "range": "vers:semver/2.7.0|<2.8.11.1", + "status": "affected" + }, + { + "range": "vers:semver/2.9.0|<2.9.5", + "status": "affected" + } + ] + } + ], + "properties": [ + { + "name": "Foo", + "value": "Bar" + }, + { + "name": "Foo", + "value": "You" + }, + { + "name": "Foo", + "value": "Two" + }, + { + "name": "Bar", + "value": "Foo" + } + ] + } + ] +} diff --git a/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.xml b/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.xml new file mode 100644 index 00000000..8e21f552 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-vulnerability-1.4.xml @@ -0,0 +1,127 @@ + + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.4 + pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.4 + + + + + SNYK-JAVA-COMFASTERXMLJACKSONCORE-32111 + + Snyk + https://snyk.io/vuln/SNYK-JAVA-COMFASTERXMLJACKSONCORE-32111 + + + + CVE-2018-7489 + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + + CVE-2018-7489 + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2019-9997 + + + + + + + NVD + https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.0 + + 9.8 + critical + CVSSv3 + AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H + An optional reason for rating the vulnerability as it was + + + + 184 + 502 + + FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath. + + Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.6.7.5, 2.8.11.1, 2.9.5 or higher. + + + GitHub Commit + https://github.com/FasterXML/jackson-databind/commit/6799f8f10cc78e9af6d443ed6982d00a13f2e7d2 + + + GitHub Issue + https://github.com/FasterXML/jackson-databind/issues/1931 + + + 2021-01-01T00:00:00.000Z + 2021-01-01T00:00:00.000Z + 2021-01-01T00:00:00.000Z + + + + Acme, Inc. + https://example.com + + + + + Jane Doe + jane.doe@example.com + + + + + + Snyk + Snyk CLI (Linux) + 1.729.0 + + 2eaf8c62831a1658c95d41fdc683cd177c147733c64a93e59cb2362829e45b7d + + + + + not_affected + code_not_reachable + + will_not_fix + update + + An optional explanation of why the application is not affected by the vulnerable component. + + + + pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.4 + + + vers:semver/<2.6.7.5 + affected + + + vers:semver/2.7.0|<2.8.11.1 + affected + + + vers:semver/2.9.0|<2.9.5 + affected + + + + + + Bar + You + Two + Foo + + + + diff --git a/tests/_data/schemaTestData/1.4/valid-xml-signature-1.4.xml b/tests/_data/schemaTestData/1.4/valid-xml-signature-1.4.xml new file mode 100644 index 00000000..b3ee4e61 --- /dev/null +++ b/tests/_data/schemaTestData/1.4/valid-xml-signature-1.4.xml @@ -0,0 +1,177 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + + 2018-11-07T22:01:45Z + John Doe + jdoe@example.com + + Initial commit + + + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + blah + fdaf + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + + + + + + + + + + PrB8/rofGs34XwIX5OIdYSjV2aKSe5VaztJKBvsgjIk= + + + + ePGNg30Zl9CW7RZdcRn8gFCp1AlWncjudA9pQDXyqZOvyj9RC2YtkI688WdfDOdVRZs6mflJFXr7 + IKA9wY6jVrEqZmlef55Qp/8iGwOjOjWbwYsm2AhrdkUi9gaFSWEd8uITYHOpWbiPFSsnimiK9+ft + 56dkg/oJMLdXzlaukzq9iGkRcafRkW433OQcZIXwD2K8lg4cdD0pNNNqBa+PgIvzbxA5H84TyQDB + HBcQiw/j1edRBJgPOwlqzZDUawOJaFhAPUQ+GGKMetIJH2FqqrHXGuV1NIwnbWTCg40RdOcBdCrl + PDtDVjFh34uZ4dYBpJBIlM4daD2N4B6WPB5iHRyuZTczF2q03ObabuTgkpK6EeadFVqFNsEOOPPt + MDDyda+Lwff5KjvUHvRRtUDIOm2rNIQKzaseulwYcA9UWQHAFcupJmWcLLM4zzY7F/uOdZuSurzh + U6h5kdb76Juepof6ee4Q5YpwNOGNL5JfB4C3sc/Dbbv8dZ8OuXFYSZN7reUGZzCNksByqERPEbAe + n1ldJu1HnRXRQpwaon8Asy9CuNmPfFCfDwOs2B4p4tb+tLNIKFHdRlpd19Zr9vCMCbltXeqq0Cpq + OejSyLYGqSWzzzUh449dJrg6KTevrTNEln5GAlLBFSdjM5JA7KV2u/GyDVFwSEW7UKooGN4CtgU= + + + + CN=bomsigner,OU=development,O=cyclonedx + + MIIE+DCCAuCgAwIBAgIEXGzayTANBgkqhkiG9w0BAQsFADA+MRIwEAYDVQQKDAljeWNsb25lZHgx + FDASBgNVBAsMC2RldmVsb3BtZW50MRIwEAYDVQQDDAlib21zaWduZXIwHhcNMTkwMjIwMDQ0MjQ5 + WhcNNDkwMjIwMDQ0MjQ5WjA+MRIwEAYDVQQKDAljeWNsb25lZHgxFDASBgNVBAsMC2RldmVsb3Bt + ZW50MRIwEAYDVQQDDAlib21zaWduZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo + 5JZsM4ZLfWW/dpRlU6CpnItWspddF+bEVDETKVwVj9tGpqR5jURgKS/BOQP2TGUsR3/ZJJBhYRll + ONhrUQrVKV/I6wp3Z40qPEa1RJLE+QlG9iL8qBV52CnXkLmnUSax3dspSzmSct5vDiTnvpHG9jr0 + AKFeTjy7U9rv8GJybz0ijwlpBoO9JRdYPX2PrrzoSeJLoxKq+GwuyCZ5LhXRN0p1a+NAirTAmY+c + G1ZTLkMmfeCUy1t6H/bG4RnYOSSPOvk7Rb68lQpUqb+pbbNuB2o/b9cDwtLLCtGVlu+5Wj8mrytY + 3FGFQM20j3yVeRInmGqTTDBelQa/CO4JKqBlmaeYEIvNYbFs9+AlqadivwDO51RpdPo9fPSpsBpy + ZMv6S2bXNuUML+Rk99WyKJTPM0PTZhRLZ64ZXEhlz3kQWVoSlrcwwim6sj6LRUb5IRqA3lxRFUI6 + NXKyiQLamQp+t3/9OGW9L1rLCcw7yFo0s8LhMTPMiv4ol9/hQViT+8ICzDsr0OM9ZiF4/UagFRlt + IClV70cjh1DpsZjzQIRVGaj8uQ/JdtfRz4E43Ki7U0a2Vpho/t6poLVndv46tkX5nYGtMW4WfMoD + ZflQ9pajvvKtr2jB1wob6nsU+VTmAcWZy4BCPH+XyfDw/0SFBdUceJJJtPWIeYFDUY7onptf+wID + AQABMA0GCSqGSIb3DQEBCwUAA4ICAQCOVariNgK+9OF/5T9ZaSvZbkk45RTmzgQNXtFc5xfRvqwP + s+pu/DFXm1R+ltjyS5j3w6NBZUFUI5MqLQr6JEEDrbu8BvfBO57wJNAEATj1JIHEfDfh7BxnBF8f + oYFOwbrh4jOt0wz0FW2obsSVmF4GSvS7tTlWqTcsxjdZVmwP40RWu18B9jzv7M61adrWD3ksDA5O + amSOsZi3Nt0aacDkyGRdCIEFi0fplxQInXMtD1z3RhXu2JSTAIr54Cei49Bh71kAXSWHMCog/f8a + lSrZyqZBty/ACfU9DqlPIM+giHePKm4z2bcdpUdKZk6wcKDn4CvuBOqsMBMg7L05UEyyqTPD/4dk + 2GwJ8Nv0E5gsYHCIXF2cZ3OUVsw0mB/ozleEJVDE02uZZN/1wW1Xq028LsMdgN0Wk1WvWyF5MEdh + nPWuhqp6tNaDI/kK6XQF+LjYJUzua3AQFOHfYNLKhO6d+bJ4rr0833v4v3cLW34kbXkKb6U3Yv8X + SK3jBGCACiPgnc0N6awkh1kDlrZQ7GMsl14c+2+vpl9Lf0sL0mRUIyICfSC8MjlsP/BZH3emyfsk + iWivPALomycKqP+PSkt1WaWApGENZWk1wNN99FYSYlt6LViW2p6T97fRx4jPRlHu+wecfD2k9RP4 + bt5W2HWfOP0zNAS7SnAVLEl2QZxXKw== + + + + + + qOSWbDOGS31lv3aUZVOgqZyLVrKXXRfmxFQxEylcFY/bRqakeY1EYCkvwTkD9kxlLEd/2SSQYWEZ + ZTjYa1EK1SlfyOsKd2eNKjxGtUSSxPkJRvYi/KgVedgp15C5p1Emsd3bKUs5knLebw4k576RxvY6 + 9AChXk48u1Pa7/Bicm89Io8JaQaDvSUXWD19j6686EniS6MSqvhsLsgmeS4V0TdKdWvjQIq0wJmP + nBtWUy5DJn3glMtbeh/2xuEZ2Dkkjzr5O0W+vJUKVKm/qW2zbgdqP2/XA8LSywrRlZbvuVo/Jq8r + WNxRhUDNtI98lXkSJ5hqk0wwXpUGvwjuCSqgZZmnmBCLzWGxbPfgJamnYr8AzudUaXT6PXz0qbAa + cmTL+ktm1zblDC/kZPfVsiiUzzND02YUS2euGVxIZc95EFlaEpa3MMIpurI+i0VG+SEagN5cURVC + OjVysokC2pkKfrd//ThlvS9aywnMO8haNLPC4TEzzIr+KJff4UFYk/vCAsw7K9DjPWYheP1GoBUZ + bSApVe9HI4dQ6bGY80CEVRmo/LkPyXbX0c+BONyou1NGtlaYaP7eqaC1Z3b+OrZF+Z2BrTFuFnzK + A2X5UPaWo77yra9owdcKG+p7FPlU5gHFmcuAQjx/l8nw8P9EhQXVHHiSSbT1iHmBQ1GO6J6bX/s= + + AQAB + + + + diff --git a/tests/_data/schemaTestData/README.md b/tests/_data/schemaTestData/README.md new file mode 100644 index 00000000..4f45a14d --- /dev/null +++ b/tests/_data/schemaTestData/README.md @@ -0,0 +1,2 @@ +files in here are taken from https://github.com/CycloneDX/specification/tree/master/tools/src/test/resources +they are fetched via [`fetch.sh`](fetch.sh) diff --git a/tests/_data/schemaTestData/fetch.sh b/tests/_data/schemaTestData/fetch.sh new file mode 100755 index 00000000..8a3f34a2 --- /dev/null +++ b/tests/_data/schemaTestData/fetch.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -eux + +SOURCE_PACKAGE='https://github.com/CycloneDX/specification/archive/refs/heads/master.zip' +SOURCE_DIR='specification-master/tools/src/test/resources' + +THIS_DIR="$(dirname "$0")" +TEMP_DIR="$(mktemp -d)" +LOCAL_PACKAGE="$TEMP_DIR/source_package.zip" + +wget -O "$LOCAL_PACKAGE" "$SOURCE_PACKAGE" +for SCHEMA_VERSION in '1.4' '1.3' '1.2' '1.1' '1.0' +do + unzip -d "$TEMP_DIR" "$LOCAL_PACKAGE" "$SOURCE_DIR/$SCHEMA_VERSION/*" + rm -rf "${THIS_DIR:?}/$SCHEMA_VERSION" + mkdir -p "$THIS_DIR/$SCHEMA_VERSION" + cp -rf "$TEMP_DIR/$SOURCE_DIR/$SCHEMA_VERSION/"*.xml "$THIS_DIR/$SCHEMA_VERSION/" + cp -rf "$TEMP_DIR/$SOURCE_DIR/$SCHEMA_VERSION/"*.json "$THIS_DIR/$SCHEMA_VERSION/" || true +done + +rm -rf "${TEMP_DIR:?}" diff --git a/tests/_data/snapshots/.gitattributes b/tests/_data/snapshots/.gitattributes new file mode 100644 index 00000000..cb164e3d --- /dev/null +++ b/tests/_data/snapshots/.gitattributes @@ -0,0 +1,3 @@ +# files are compared bype-wise, so they need to be treated as binary +xml/** linguist-generated binary diff=xml +json/** linguist-generated binary diff=json diff --git a/tests/fixtures/README.md b/tests/_data/snapshots/README.md similarity index 100% rename from tests/fixtures/README.md rename to tests/_data/snapshots/README.md diff --git a/tests/_data/snapshots/get_bom_for_issue_275_components-1.0.xml.bin b/tests/_data/snapshots/get_bom_for_issue_275_components-1.0.xml.bin new file mode 100644 index 00000000..9c17482c --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.0.xml.bin @@ -0,0 +1,22 @@ + + + + + comp_a + 1.0.0 + false + + + comp_b + 1.0.0 + false + + + comp_c + 1.0.0 + false + + + + + diff --git a/tests/_data/snapshots/get_bom_for_issue_275_components-1.1.xml.bin b/tests/_data/snapshots/get_bom_for_issue_275_components-1.1.xml.bin new file mode 100644 index 00000000..85289a74 --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.1.xml.bin @@ -0,0 +1,19 @@ + + + + + comp_a + 1.0.0 + + + comp_b + 1.0.0 + + + comp_c + 1.0.0 + + + + + diff --git a/tests/fixtures/json/1.2/bom_issue_275_components.json b/tests/_data/snapshots/get_bom_for_issue_275_components-1.2.json.bin similarity index 79% rename from tests/fixtures/json/1.2/bom_issue_275_components.json rename to tests/_data/snapshots/get_bom_for_issue_275_components-1.2.json.bin index 8fc7cf7e..b4eef0f9 100644 --- a/tests/fixtures/json/1.2/bom_issue_275_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.2.json.bin @@ -1,66 +1,66 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:e8a76c00-84d4-447e-8bc5-d8a3cefd01f0", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.651650+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "library", - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "name": "app", - "version": "1.0.0" - } - }, "components": [ { - "type": "library", "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", "name": "comp_a", + "type": "library", "version": "1.0.0" }, { - "type": "library", "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "name": "comp_b", - "version": "1.0.0", "components": [ { - "type": "library", "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", "name": "comp_c", + "type": "library", "version": "1.0.0" } - ] + ], + "name": "comp_b", + "type": "library", + "version": "1.0.0" } ], "dependencies": [ { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", "dependsOn": [ - "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - ] + "cd3e9c95-9d41-49e7-9924-8cf0465ae789" + ], + "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" }, { "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" }, { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", "dependsOn": [ - "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - ] + "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" + ], + "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" }, { "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "name": "app", + "type": "library", + "version": "1.0.0" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_275_components-1.2.xml.bin b/tests/_data/snapshots/get_bom_for_issue_275_components-1.2.xml.bin new file mode 100644 index 00000000..e9568f56 --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.2.xml.bin @@ -0,0 +1,44 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + 1.0.0 + + + + + comp_a + 1.0.0 + + + comp_b + 1.0.0 + + + comp_c + 1.0.0 + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_issue_275_components.json b/tests/_data/snapshots/get_bom_for_issue_275_components-1.3.json.bin similarity index 79% rename from tests/fixtures/json/1.3/bom_issue_275_components.json rename to tests/_data/snapshots/get_bom_for_issue_275_components-1.3.json.bin index f1f7596d..b57b1676 100644 --- a/tests/fixtures/json/1.3/bom_issue_275_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.3.json.bin @@ -1,66 +1,66 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:4d8c5007-3d0b-4556-bbda-e9902c183b82", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.962469+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "library", - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "name": "app", - "version": "1.0.0" - } - }, "components": [ { - "type": "library", "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", "name": "comp_a", + "type": "library", "version": "1.0.0" }, { - "type": "library", "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "name": "comp_b", - "version": "1.0.0", "components": [ { - "type": "library", "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", "name": "comp_c", + "type": "library", "version": "1.0.0" } - ] + ], + "name": "comp_b", + "type": "library", + "version": "1.0.0" } ], "dependencies": [ { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", "dependsOn": [ - "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - ] + "cd3e9c95-9d41-49e7-9924-8cf0465ae789" + ], + "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" }, { "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" }, { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", "dependsOn": [ - "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - ] + "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" + ], + "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" }, { "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "name": "app", + "type": "library", + "version": "1.0.0" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_275_components-1.3.xml.bin b/tests/_data/snapshots/get_bom_for_issue_275_components-1.3.xml.bin new file mode 100644 index 00000000..c77704fc --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.3.xml.bin @@ -0,0 +1,44 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + 1.0.0 + + + + + comp_a + 1.0.0 + + + comp_b + 1.0.0 + + + comp_c + 1.0.0 + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_issue_275_components.json b/tests/_data/snapshots/get_bom_for_issue_275_components-1.4.json.bin similarity index 71% rename from tests/fixtures/json/1.4/bom_issue_275_components.json rename to tests/_data/snapshots/get_bom_for_issue_275_components-1.4.json.bin index 6826b7a1..32f27cdd 100644 --- a/tests/fixtures/json/1.4/bom_issue_275_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.4.json.bin @@ -1,100 +1,100 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:75d08821-33b4-4f66-8577-6caa2fc718ac", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:58.871481+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ], - "component": { - "type": "library", - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "name": "app", - "version": "1.0.0" - } - }, "components": [ { - "type": "library", "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", "name": "comp_a", + "type": "library", "version": "1.0.0" }, { - "type": "library", "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "name": "comp_b", - "version": "1.0.0", "components": [ { - "type": "library", "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", "name": "comp_c", + "type": "library", "version": "1.0.0" } - ] + ], + "name": "comp_b", + "type": "library", + "version": "1.0.0" } ], "dependencies": [ { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", "dependsOn": [ - "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - ] + "cd3e9c95-9d41-49e7-9924-8cf0465ae789" + ], + "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" }, { "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" }, { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", "dependsOn": [ - "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - ] + "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" + ], + "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" }, { "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "name": "app", + "type": "library", + "version": "1.0.0" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_275_components-1.4.xml.bin b/tests/_data/snapshots/get_bom_for_issue_275_components-1.4.xml.bin new file mode 100644 index 00000000..dcd23b6a --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_275_components-1.4.xml.bin @@ -0,0 +1,70 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + app + 1.0.0 + + + + + comp_a + 1.0.0 + + + comp_b + 1.0.0 + + + comp_c + 1.0.0 + + + + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_for_issue_328_components-1.0.xml.bin b/tests/_data/snapshots/get_bom_for_issue_328_components-1.0.xml.bin new file mode 100644 index 00000000..8f2aeebc --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.0.xml.bin @@ -0,0 +1,24 @@ + + + + + A + 0.1 + false + + + B + 1.0 + false + + + C + 1.0 + false + + + + + + + diff --git a/tests/_data/snapshots/get_bom_for_issue_328_components-1.1.xml.bin b/tests/_data/snapshots/get_bom_for_issue_328_components-1.1.xml.bin new file mode 100644 index 00000000..210e36e9 --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.1.xml.bin @@ -0,0 +1,21 @@ + + + + + A + 0.1 + + + B + 1.0 + + + C + 1.0 + + + + + + + diff --git a/tests/fixtures/json/1.2/bom_issue_328_components.json b/tests/_data/snapshots/get_bom_for_issue_328_components-1.2.json.bin similarity index 72% rename from tests/fixtures/json/1.2/bom_issue_328_components.json rename to tests/_data/snapshots/get_bom_for_issue_328_components-1.2.json.bin index 1ad1cce2..80f814fa 100644 --- a/tests/fixtures/json/1.2/bom_issue_328_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.2.json.bin @@ -1,71 +1,70 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:0e7ce694-c130-4965-8716-85015b42c729", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:52:27.732107+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "application", - "bom-ref": "my-project", - "name": "my-project", - "version": "1" - } - }, "components": [ { - "type": "library", "bom-ref": "component-A", - "name": "A", - "version": "0.1", "components": [ { - "type": "library", "bom-ref": "component-B", - "name": "B", - "version": "1.0", "components": [ { - "type": "library", "bom-ref": "component-C", "name": "C", + "type": "library", "version": "1.0" } - ] + ], + "name": "B", + "type": "library", + "version": "1.0" } - ] + ], + "name": "A", + "type": "library", + "version": "0.1" } ], "dependencies": [ { - "ref": "my-project", - "dependsOn": [ - "component-A" - ] - }, - { - "ref": "component-A", "dependsOn": [ "component-B" - ] + ], + "ref": "component-A" }, { - "ref": "component-B", "dependsOn": [ "component-C" - ] + ], + "ref": "component-B" }, { - "ref": "component-C", - "dependsOn": [] + "ref": "component-C" + }, + { + "dependsOn": [ + "component-A" + ], + "ref": "my-project" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "my-project", + "name": "my-project", + "type": "application", + "version": "1" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_328_components-1.2.xml.bin b/tests/_data/snapshots/get_bom_for_issue_328_components-1.2.xml.bin new file mode 100644 index 00000000..4e712c8c --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.2.xml.bin @@ -0,0 +1,47 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + my-project + 1 + + + + + A + 0.1 + + + B + 1.0 + + + C + 1.0 + + + + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_issue_328_components.json b/tests/_data/snapshots/get_bom_for_issue_328_components-1.3.json.bin similarity index 72% rename from tests/fixtures/json/1.3/bom_issue_328_components.json rename to tests/_data/snapshots/get_bom_for_issue_328_components-1.3.json.bin index 7d515941..a4dce742 100644 --- a/tests/fixtures/json/1.3/bom_issue_328_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.3.json.bin @@ -1,71 +1,70 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d59b94a8-25bc-4876-a1ae-c21a73fecd2c", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:52:28.562184+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "application", - "bom-ref": "my-project", - "name": "my-project", - "version": "1" - } - }, "components": [ { - "type": "library", "bom-ref": "component-A", - "name": "A", - "version": "0.1", "components": [ { - "type": "library", "bom-ref": "component-B", - "name": "B", - "version": "1.0", "components": [ { - "type": "library", "bom-ref": "component-C", "name": "C", + "type": "library", "version": "1.0" } - ] + ], + "name": "B", + "type": "library", + "version": "1.0" } - ] + ], + "name": "A", + "type": "library", + "version": "0.1" } ], "dependencies": [ { - "ref": "my-project", - "dependsOn": [ - "component-A" - ] - }, - { - "ref": "component-A", "dependsOn": [ "component-B" - ] + ], + "ref": "component-A" }, { - "ref": "component-B", "dependsOn": [ "component-C" - ] + ], + "ref": "component-B" }, { - "ref": "component-C", - "dependsOn": [] + "ref": "component-C" + }, + { + "dependsOn": [ + "component-A" + ], + "ref": "my-project" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "my-project", + "name": "my-project", + "type": "application", + "version": "1" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_328_components-1.3.xml.bin b/tests/_data/snapshots/get_bom_for_issue_328_components-1.3.xml.bin new file mode 100644 index 00000000..022354c0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.3.xml.bin @@ -0,0 +1,47 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + my-project + 1 + + + + + A + 0.1 + + + B + 1.0 + + + C + 1.0 + + + + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_issue_328_components.json b/tests/_data/snapshots/get_bom_for_issue_328_components-1.4.json.bin similarity index 66% rename from tests/fixtures/json/1.4/bom_issue_328_components.json rename to tests/_data/snapshots/get_bom_for_issue_328_components-1.4.json.bin index 27872223..a1ee1181 100644 --- a/tests/fixtures/json/1.4/bom_issue_328_components.json +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.4.json.bin @@ -1,105 +1,104 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:282ec6f4-455e-4b07-b4b8-561bad2010c5", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:52:30.247202+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ], - "component": { - "type": "application", - "bom-ref": "my-project", - "name": "my-project", - "version": "1" - } - }, "components": [ { - "type": "library", "bom-ref": "component-A", - "name": "A", - "version": "0.1", "components": [ { - "type": "library", "bom-ref": "component-B", - "name": "B", - "version": "1.0", "components": [ { - "type": "library", "bom-ref": "component-C", "name": "C", + "type": "library", "version": "1.0" } - ] + ], + "name": "B", + "type": "library", + "version": "1.0" } - ] + ], + "name": "A", + "type": "library", + "version": "0.1" } ], "dependencies": [ { - "ref": "my-project", - "dependsOn": [ - "component-A" - ] - }, - { - "ref": "component-A", "dependsOn": [ "component-B" - ] + ], + "ref": "component-A" }, { - "ref": "component-B", "dependsOn": [ "component-C" - ] + ], + "ref": "component-B" + }, + { + "ref": "component-C" }, { - "ref": "component-C", - "dependsOn": [] + "dependsOn": [ + "component-A" + ], + "ref": "my-project" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "my-project", + "name": "my-project", + "type": "application", + "version": "1" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_for_issue_328_components-1.4.xml.bin b/tests/_data/snapshots/get_bom_for_issue_328_components-1.4.xml.bin new file mode 100644 index 00000000..d646d17d --- /dev/null +++ b/tests/_data/snapshots/get_bom_for_issue_328_components-1.4.xml.bin @@ -0,0 +1,73 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + my-project + 1 + + + + + A + 0.1 + + + B + 1.0 + + + C + 1.0 + + + + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/xml/1.0/bom_empty.xml b/tests/_data/snapshots/get_bom_just_complete_metadata-1.0.xml.bin similarity index 54% rename from tests/fixtures/xml/1.0/bom_empty.xml rename to tests/_data/snapshots/get_bom_just_complete_metadata-1.0.xml.bin index a803aa60..acb06612 100644 --- a/tests/fixtures/xml/1.0/bom_empty.xml +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.0.xml.bin @@ -1,4 +1,4 @@ - + - + diff --git a/tests/_data/snapshots/get_bom_just_complete_metadata-1.1.xml.bin b/tests/_data/snapshots/get_bom_just_complete_metadata-1.1.xml.bin new file mode 100644 index 00000000..55ef5cda --- /dev/null +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/fixtures/json/1.2/bom_with_full_metadata.json b/tests/_data/snapshots/get_bom_just_complete_metadata-1.2.json.bin similarity index 76% rename from tests/fixtures/json/1.2/bom_with_full_metadata.json rename to tests/_data/snapshots/get_bom_just_complete_metadata-1.2.json.bin index d24684c6..4d184212 100644 --- a/tests/fixtures/json/1.2/bom_with_full_metadata.json +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.2.json.bin @@ -1,262 +1,274 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-dings" + } + ], "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], "authors": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "component": { - "type": "library", - "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ { - "expression": "MIT License" + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "copyright": "Apache 2.0 baby!", "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "description": "This component is awesome", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" } - }, + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], + "name": "toml", "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], + "name": "toml", "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] + "type": "library", + "version": "0.10.2" } - ], - "commits": [ + ] + }, + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "scope": "required", + "supplier": { + "contact": [ { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, { - "type": "backport" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], - "notes": "Some notes here please" + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] }, - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ], - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" }, "manufacture": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, "supplier": { - "name": "Cyclone DX", - "url": [ - "https://cyclonedx.org/" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" } + ], + "name": "Cyclone DX", + "url": [ + "https://cyclonedx.org/" ] - } + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] }, - "dependencies": [ - { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_just_complete_metadata-1.2.xml.bin b/tests/_data/snapshots/get_bom_just_complete_metadata-1.2.xml.bin new file mode 100644 index 00000000..9e4a71e0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.2.xml.bin @@ -0,0 +1,204 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + Cyclone DX + https://cyclonedx.org/ + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_with_full_metadata.json b/tests/_data/snapshots/get_bom_just_complete_metadata-1.3.json.bin similarity index 80% rename from tests/fixtures/json/1.3/bom_with_full_metadata.json rename to tests/_data/snapshots/get_bom_just_complete_metadata-1.3.json.bin index 9cd5271c..4028367c 100644 --- a/tests/fixtures/json/1.3/bom_with_full_metadata.json +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.3.json.bin @@ -1,210 +1,233 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-dings" + } + ], "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], "authors": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "component": { - "type": "library", - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ + "author": "Test Author", + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "copyright": "Apache 2.0 baby!", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", + "description": "This component is awesome", + "evidence": { + "copyright": [ { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + "text": "Commercial" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "text": "Commercial 2" } ] }, - "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "externalReferences": [ { - "expression": "MIT License" + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], - "copyright": "Apache 2.0 baby!", - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "licenses": [ + { + "license": { + "id": "MIT" + } } - }, + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] - } - ], - "commits": [ - { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ - { - "type": "backport" + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } - ], - "notes": "Some notes here please" + ] }, - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ], "properties": [ { "name": "key1", @@ -215,101 +238,69 @@ "value": "val2" } ], - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - }, - { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ] - } - ], - "evidence": { - "copyright": [ + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "scope": "required", + "supplier": { + "contact": [ { - "text": "Commercial" + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" }, { - "text": "Commercial 2" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] - } - }, - "manufacture": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + }, + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "supplier": { - "name": "Cyclone DX", - "url": [ - "https://cyclonedx.org/" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" }, "licenses": [ { "license": { "id": "Apache-2.0", "text": { + "content": "VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=", "contentType": "text/plain", - "encoding": "base64", - "content": "VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=" + "encoding": "base64" }, "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" } } ], + "manufacture": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, "properties": [ { "name": "key1", @@ -319,11 +310,32 @@ "name": "key2", "value": "val2" } + ], + "supplier": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + } + ], + "name": "Cyclone DX", + "url": [ + "https://cyclonedx.org/" + ] + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } ] }, - "dependencies": [ - { - "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_just_complete_metadata-1.3.xml.bin b/tests/_data/snapshots/get_bom_just_complete_metadata-1.3.xml.bin new file mode 100644 index 00000000..a657ab39 --- /dev/null +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.3.xml.bin @@ -0,0 +1,237 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + Cyclone DX + https://cyclonedx.org/ + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + + + Apache-2.0 + VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + val1 + val2 + + + + + + diff --git a/tests/fixtures/json/1.4/bom_with_full_metadata.json b/tests/_data/snapshots/get_bom_just_complete_metadata-1.4.json.bin similarity index 79% rename from tests/fixtures/json/1.4/bom_with_full_metadata.json rename to tests/_data/snapshots/get_bom_just_complete_metadata-1.4.json.bin index 0fab3971..1c5a5e40 100644 --- a/tests/fixtures/json/1.4/bom_with_full_metadata.json +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.4.json.bin @@ -1,242 +1,231 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-dings" + } + ], "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ], "authors": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "component": { - "type": "library", - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ + "author": "Test Author", + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "copyright": "Apache 2.0 baby!", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", + "description": "This component is awesome", + "evidence": { + "copyright": [ { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + "text": "Commercial" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "text": "Commercial 2" } ] }, - "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "externalReferences": [ { - "expression": "MIT License" + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], - "copyright": "Apache 2.0 baby!", - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "licenses": [ + { + "license": { + "id": "MIT" + } } - }, + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] - } - ], - "commits": [ - { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ - { - "type": "backport" + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } - ], - "notes": "Some notes here please" + ] }, - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ], "properties": [ { "name": "key1", @@ -247,103 +236,30 @@ "value": "val2" } ], - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - }, - { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ] - } - ], - "evidence": { - "copyright": [ - { - "text": "Commercial" - }, - { - "text": "Commercial 2" - } - ] - }, + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "releaseNotes": { - "type": "major", - "title": "Release Notes Title", - "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", - "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", - "description": "This release is a test release", - "timestamp": "2021-12-31T10:00:00+00:00", "aliases": [ "First Test Release" ], - "tags": [ - "alpha", - "test" - ], - "resolves": [ - { - "type": "security", - "id": "CVE-2021-44228", - "name": "Apache Log3Shell", - "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" - }, - "references": [ - "https://central.sonatype.org/news/20211213_log4shell_help", - "https://logging.apache.org/log4j/2.x/security.html" - ] - } - ], + "description": "This release is a test release", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", "notes": [ { + "locale": "en-GB", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-GB" + } }, { + "locale": "en-US", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-US" + } } ], "properties": [ @@ -355,52 +271,93 @@ "name": "key2", "value": "val2" } + ], + "resolves": [ + { + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "references": [ + "https://central.sonatype.org/news/20211213_log4shell_help", + "https://logging.apache.org/log4j/2.x/security.html" + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "type": "security" + } + ], + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "tags": [ + "alpha", + "test" + ], + "timestamp": "2023-08-15T01:23:45.678900+00:00", + "title": "Release Notes Title", + "type": "major" + }, + "scope": "required", + "supplier": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] - } - }, - "manufacture": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + }, + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "supplier": { - "name": "Cyclone DX", - "url": [ - "https://cyclonedx.org/" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" }, "licenses": [ { "license": { "id": "Apache-2.0", "text": { + "content": "VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=", "contentType": "text/plain", - "encoding": "base64", - "content": "VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE=" + "encoding": "base64" }, "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" } } ], + "manufacture": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, "properties": [ { "name": "key1", @@ -410,11 +367,66 @@ "name": "key2", "value": "val2" } + ], + "supplier": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + } + ], + "name": "Cyclone DX", + "url": [ + "https://cyclonedx.org/" + ] + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } ] }, - "dependencies": [ - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_just_complete_metadata-1.4.xml.bin b/tests/_data/snapshots/get_bom_just_complete_metadata-1.4.xml.bin new file mode 100644 index 00000000..886b439a --- /dev/null +++ b/tests/_data/snapshots/get_bom_just_complete_metadata-1.4.xml.bin @@ -0,0 +1,305 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2023-08-15T01:23:45.678900+00:00 + + First Test Release + + + alpha + test + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://central.sonatype.org/news/20211213_log4shell_help + https://logging.apache.org/log4j/2.x/security.html + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + Cyclone DX + https://cyclonedx.org/ + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + + + Apache-2.0 + VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + val1 + val2 + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.0.xml.bin new file mode 100644 index 00000000..961bb479 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.0.xml.bin @@ -0,0 +1,11 @@ + + + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.1.xml.bin new file mode 100644 index 00000000..ba1ca960 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.1.xml.bin @@ -0,0 +1,15 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + diff --git a/tests/fixtures/json/1.2/bom_setuptools.json b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.json.bin similarity index 73% rename from tests/fixtures/json/1.2/bom_setuptools.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.json.bin index 961c69d9..2f146446 100644 --- a/tests/fixtures/json/1.2/bom_setuptools.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.json.bin @@ -1,37 +1,39 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.xml.bin new file mode 100644 index 00000000..cb29e5ba --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.2.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.3/bom_setuptools.json b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.json.bin similarity index 73% rename from tests/fixtures/json/1.3/bom_setuptools.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.json.bin index 33d6d399..a075deb2 100644 --- a/tests/fixtures/json/1.3/bom_setuptools.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.json.bin @@ -1,37 +1,39 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.xml.bin new file mode 100644 index 00000000..76ce40a0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.3.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools.json b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.json.bin similarity index 65% rename from tests/fixtures/json/1.4/bom_setuptools.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.json.bin index 4fd30cac..70616689 100644 --- a/tests/fixtures/json/1.4/bom_setuptools.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.json.bin @@ -1,71 +1,73 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.xml.bin new file mode 100644 index 00000000..586abf6a --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_basic-1.4.xml.bin @@ -0,0 +1,55 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.0.xml.bin new file mode 100644 index 00000000..dc8f7332 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.0.xml.bin @@ -0,0 +1,33 @@ + + + + + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.1.xml.bin new file mode 100644 index 00000000..851c9d9b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.1.xml.bin @@ -0,0 +1,135 @@ + + + + + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + a-random-uid + A commit message + + + Some notes here please + + + + https://cyclonedx.org + No comment + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + diff --git a/tests/fixtures/json/1.2/bom_setuptools_complete.json b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.json.bin similarity index 75% rename from tests/fixtures/json/1.2/bom_setuptools_complete.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.json.bin index 1bfc41dc..952801f9 100644 --- a/tests/fixtures/json/1.2/bom_setuptools_complete.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.json.bin @@ -1,223 +1,235 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - }, - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - } - ] - }, "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, { - "expression": "MIT License" + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "copyright": "Apache 2.0 baby!", "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "description": "This component is awesome", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" } - }, + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment" - } - ] + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ + "author": "Test Author", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", + "licenses": [ { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + "license": { + "id": "MIT" + } } ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", "externalReferences": [ { + "comment": "No comment", "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment" + "url": "https://cyclonedx.org" } - ] - }, - { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ + ], + "hashes": [ { - "expression": "MIT License" + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } - ], - "commits": [ + ] + }, + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "scope": "required", + "supplier": { + "contact": [ { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, { - "type": "backport" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], - "notes": "Some notes here please" + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] }, - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment" - } - ], - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment" - } - ] - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" + "ref": "my-specific-bom-ref-for-dings" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.xml.bin new file mode 100644 index 00000000..ab648c16 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.2.xml.bin @@ -0,0 +1,173 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_setuptools_complete.json b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.json.bin similarity index 79% rename from tests/fixtures/json/1.3/bom_setuptools_complete.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.json.bin index d32d0200..d974b195 100644 --- a/tests/fixtures/json/1.3/bom_setuptools_complete.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.json.bin @@ -1,267 +1,279 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ + "author": "Test Author", + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "copyright": "Apache 2.0 baby!", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", + "description": "This component is awesome", + "evidence": { + "copyright": [ { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "text": "Commercial" }, { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + "text": "Commercial 2" } ] }, - "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "externalReferences": [ { - "expression": "MIT License" + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], - "copyright": "Apache 2.0 baby!", - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "licenses": [ + { + "license": { + "id": "MIT" + } } - }, + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], "externalReferences": [ { - "type": "distribution", - "url": "https://cyclonedx.org", "comment": "No comment", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ + "author": "Test Author", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", + "licenses": [ { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + "license": { + "id": "MIT" + } } ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", "externalReferences": [ { - "type": "distribution", - "url": "https://cyclonedx.org", "comment": "No comment", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] - }, - { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ + ], + "hashes": [ { - "expression": "MIT License" + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], - "commits": [ - { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ - { - "type": "backport" + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } - ], - "notes": "Some notes here please" + ] }, - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ], - "components": [ + "properties": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "key1", + "value": "val1" }, { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ] + "name": "key2", + "value": "val2" } ], - "evidence": { - "copyright": [ + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "scope": "required", + "supplier": { + "contact": [ { - "text": "Commercial" + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" }, { - "text": "Commercial 2" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, - "properties": [ - { - "name": "key1", - "value": "val1" + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "name": "key2", - "value": "val2" - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" + "ref": "my-specific-bom-ref-for-dings" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.xml.bin new file mode 100644 index 00000000..27861fd1 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.3.xml.bin @@ -0,0 +1,195 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools_complete.json b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.json.bin similarity index 81% rename from tests/fixtures/json/1.4/bom_setuptools_complete.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.json.bin index ceb5903c..c19e9908 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_complete.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.json.bin @@ -1,329 +1,248 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "type": "build-system", - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" - }, - { - "type": "distribution", - "url": "https://pypi.org/project/cyclonedx-python-lib/" - }, - { - "type": "documentation", - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" - }, - { - "type": "issue-tracker", - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" - }, - { - "type": "license", - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" - }, - { - "type": "release-notes", - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" - }, - { - "type": "vcs", - "url": "https://github.com/CycloneDX/cyclonedx-python-lib" - }, - { - "type": "website", - "url": "https://cyclonedx.org" - } - ] - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "supplier": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ + "author": "Test Author", + "bom-ref": "my-specific-bom-ref-for-dings", + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "copyright": "Apache 2.0 baby!", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", + "description": "This component is awesome", + "evidence": { + "copyright": [ { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "text": "Commercial" }, { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" + "text": "Commercial 2" } ] }, - "author": "Test Author", - "publisher": "CycloneDX", - "name": "setuptools", - "version": "50.3.2", - "description": "This component is awesome", - "scope": "required", - "licenses": [ + "externalReferences": [ { - "expression": "MIT License" + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], - "copyright": "Apache 2.0 baby!", - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "swid": { - "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", - "name": "Test Application", - "version": "3.4.5", - "text": { - "contentType": "text/xml", - "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "licenses": [ + { + "license": { + "id": "MIT" + } } - }, + ], + "name": "setuptools", "pedigree": { "ancestors": [ { - "type": "library", - "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "ccc8d7ee-4b9c-4750-aee0-a72585152291", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", - "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", - "name": "setuptools", + "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library" + } + ], + "commits": [ + { + "message": "A commit message", + "uid": "a-random-uid" } ], "descendants": [ { - "type": "library", - "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", - "name": "setuptools", + "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library" }, { - "type": "library", "bom-ref": "555ca729-93c6-48f3-956e-bdaa4a2f0bfa", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], "externalReferences": [ { - "type": "distribution", - "url": "https://cyclonedx.org", "comment": "No comment", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "notes": "Some notes here please", + "patches": [ + { + "type": "backport" } ], "variants": [ { - "type": "library", - "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ + "author": "Test Author", + "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", + "licenses": [ { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + "license": { + "id": "MIT" + } } ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66", "externalReferences": [ { - "type": "distribution", - "url": "https://cyclonedx.org", "comment": "No comment", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] - }, - { - "type": "library", - "bom-ref": "ded1d73e-1fca-4302-b520-f1bc53979958", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ + ], + "hashes": [ { - "expression": "MIT License" + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], - "commits": [ - { - "uid": "a-random-uid", - "message": "A commit message" - } - ], - "patches": [ - { - "type": "backport" + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } - ], - "notes": "Some notes here please" + ] }, - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ], - "components": [ + "properties": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "key1", + "value": "val1" }, { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "externalReferences": [ - { - "type": "distribution", - "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ] + "name": "key2", + "value": "val2" } ], - "evidence": { - "copyright": [ - { - "text": "Commercial" - }, - { - "text": "Commercial 2" - } - ] - }, + "publisher": "CycloneDX", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "releaseNotes": { - "type": "major", - "title": "Release Notes Title", - "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", - "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", - "description": "This release is a test release", - "timestamp": "2021-12-31T10:00:00+00:00", "aliases": [ "First Test Release" ], - "tags": [ - "test", - "alpha" - ], - "resolves": [ - { - "type": "security", - "id": "CVE-2021-44228", - "name": "Apache Log3Shell", - "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" - }, - "references": [ - "https://logging.apache.org/log4j/2.x/security.html", - "https://central.sonatype.org/news/20211213_log4shell_help" - ] - } - ], + "description": "This release is a test release", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", "notes": [ { "locale": "en-GB", "text": { + "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", - "encoding": "base64", - "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==" + "encoding": "base64" } }, { "locale": "en-US", "text": { + "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", - "encoding": "base64", - "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==" + "encoding": "base64" } } ], @@ -336,23 +255,116 @@ "name": "key2", "value": "val2" } + ], + "resolves": [ + { + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "references": [ + "https://central.sonatype.org/news/20211213_log4shell_help", + "https://logging.apache.org/log4j/2.x/security.html" + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "type": "security" + } + ], + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "tags": [ + "alpha", + "test" + ], + "timestamp": "2023-08-15T01:23:45.678900+00:00", + "title": "Release Notes Title", + "type": "major" + }, + "scope": "required", + "supplier": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, - "properties": [ - { - "name": "key1", - "value": "val1" + "swid": { + "name": "Test Application", + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "text": { + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==", + "contentType": "text/xml", + "encoding": "base64" }, - { - "name": "key2", - "value": "val2" - } - ] + "version": "3.4.5" + }, + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" + "ref": "my-specific-bom-ref-for-dings" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.xml.bin new file mode 100644 index 00000000..02676140 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_complete-1.4.xml.bin @@ -0,0 +1,263 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + Test Author + CycloneDX + setuptools + 50.3.2 + This component is awesome + required + + + MIT + + + Apache 2.0 baby! + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + Test Author + setuptools + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + Test Author + setuptools + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + a-random-uid + A commit message + + + + + + Some notes here please + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2023-08-15T01:23:45.678900+00:00 + + First Test Release + + + alpha + test + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://central.sonatype.org/news/20211213_log4shell_help + https://logging.apache.org/log4j/2.x/security.html + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.0.xml.bin new file mode 100644 index 00000000..19b807ce --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.0.xml.bin @@ -0,0 +1,11 @@ + + + + + setuptools + + pkg:pypi/setuptools?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.1.xml.bin new file mode 100644 index 00000000..5bc27d5b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.1.xml.bin @@ -0,0 +1,15 @@ + + + + + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + diff --git a/tests/fixtures/json/1.2/bom_setuptools_no_version.json b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.json.bin similarity index 73% rename from tests/fixtures/json/1.2/bom_setuptools_no_version.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.json.bin index 8fb2dd78..556f871e 100644 --- a/tests/fixtures/json/1.2/bom_setuptools_no_version.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.json.bin @@ -1,37 +1,39 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:77d15ab9-5602-4cca-8ed2-59ae579aafd3", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.xml.bin new file mode 100644 index 00000000..39e16bf4 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.2.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.3/bom_setuptools_no_version.json b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.json.bin similarity index 73% rename from tests/fixtures/json/1.3/bom_setuptools_no_version.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.json.bin index c59f067e..0d3f3547 100644 --- a/tests/fixtures/json/1.3/bom_setuptools_no_version.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.json.bin @@ -1,37 +1,39 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:77d15ab9-5602-4cca-8ed2-59ae579aafd3", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "", + "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library", + "version": "" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.xml.bin new file mode 100644 index 00000000..b1198c98 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.3.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools_no_version.json b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.json.bin similarity index 64% rename from tests/fixtures/json/1.4/bom_setuptools_no_version.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.json.bin index ea3bb5d6..a8f2ac87 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_no_version.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.json.bin @@ -1,70 +1,72 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:77d15ab9-5602-4cca-8ed2-59ae579aafd3", - "version": 1, + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools?extension=tar.gz", + "type": "library" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools?extension=tar.gz" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools?extension=tar.gz" - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/setuptools?extension=tar.gz" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.xml.bin new file mode 100644 index 00000000..558c9be7 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_no_component_version-1.4.xml.bin @@ -0,0 +1,54 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + + + MIT + + + pkg:pypi/setuptools?extension=tar.gz + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.0.xml.bin new file mode 100644 index 00000000..79dbb1af --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.0.xml.bin @@ -0,0 +1,12 @@ + + + + + setuptools + 50.3.2 + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.1.xml.bin new file mode 100644 index 00000000..21439ea9 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.1.xml.bin @@ -0,0 +1,16 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + diff --git a/tests/fixtures/json/1.2/bom_setuptools_with_cpe.json b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.json.bin similarity index 74% rename from tests/fixtures/json/1.2/bom_setuptools_with_cpe.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.json.bin index 0d7e9b9e..f9282117 100644 --- a/tests/fixtures/json/1.2/bom_setuptools_with_cpe.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.json.bin @@ -1,38 +1,40 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.xml.bin new file mode 100644 index 00000000..f8b4fd27 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.2.xml.bin @@ -0,0 +1,30 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.3/bom_setuptools_with_cpe.json b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.json.bin similarity index 74% rename from tests/fixtures/json/1.3/bom_setuptools_with_cpe.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.json.bin index baf80bcc..8ad7c766 100644 --- a/tests/fixtures/json/1.3/bom_setuptools_with_cpe.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.json.bin @@ -1,38 +1,40 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.xml.bin new file mode 100644 index 00000000..457d800b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.3.xml.bin @@ -0,0 +1,30 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools_with_cpe.json b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.json.bin similarity index 66% rename from tests/fixtures/json/1.4/bom_setuptools_with_cpe.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.json.bin index 7ad22406..17799868 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_with_cpe.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.json.bin @@ -1,72 +1,74 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.xml.bin new file mode 100644 index 00000000..1cf91295 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_cpe-1.4.xml.bin @@ -0,0 +1,56 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.0.xml.bin new file mode 100644 index 00000000..961bb479 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.0.xml.bin @@ -0,0 +1,11 @@ + + + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.1.xml.bin new file mode 100644 index 00000000..ba1ca960 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.1.xml.bin @@ -0,0 +1,15 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.json.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.json.bin new file mode 100644 index 00000000..2f146446 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.json.bin @@ -0,0 +1,39 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.xml.bin new file mode 100644 index 00000000..cb29e5ba --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.2.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.json.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.json.bin new file mode 100644 index 00000000..a075deb2 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.json.bin @@ -0,0 +1,39 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.xml.bin new file mode 100644 index 00000000..76ce40a0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.3.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools_with_release_notes.json b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.json.bin similarity index 77% rename from tests/fixtures/json/1.4/bom_setuptools_with_release_notes.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.json.bin index 492be373..492ecc0b 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_with_release_notes.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.json.bin @@ -1,112 +1,39 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], + "name": "setuptools", "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "releaseNotes": { - "type": "major", - "title": "Release Notes Title", - "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", - "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", - "description": "This release is a test release", - "timestamp": "2021-12-31T10:00:00+00:00", "aliases": [ "First Test Release" ], - "tags": [ - "alpha", - "test" - ], - "resolves": [ - { - "type": "security", - "id": "CVE-2021-44228", - "name": "Apache Log3Shell", - "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" - }, - "references": [ - "https://central.sonatype.org/news/20211213_log4shell_help", - "https://logging.apache.org/log4j/2.x/security.html" - ] - } - ], + "description": "This release is a test release", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", "notes": [ { + "locale": "en-GB", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-GB" + } }, { + "locale": "en-US", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-US" + } } ], "properties": [ @@ -118,13 +45,88 @@ "name": "key2", "value": "val2" } - ] - } + ], + "resolves": [ + { + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "references": [ + "https://central.sonatype.org/news/20211213_log4shell_help", + "https://logging.apache.org/log4j/2.x/security.html" + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "type": "security" + } + ], + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "tags": [ + "alpha", + "test" + ], + "timestamp": "2023-08-15T01:23:45.678900+00:00", + "title": "Release Notes Title", + "type": "major" + }, + "type": "library", + "version": "50.3.2" } ], "dependencies": [ { "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.xml.bin new file mode 100644 index 00000000..70852442 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_release_notes-1.4.xml.bin @@ -0,0 +1,99 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2023-08-15T01:23:45.678900+00:00 + + First Test Release + + + alpha + test + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://central.sonatype.org/news/20211213_log4shell_help + https://logging.apache.org/log4j/2.x/security.html + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.0.xml.bin new file mode 100644 index 00000000..961bb479 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.0.xml.bin @@ -0,0 +1,11 @@ + + + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.1.xml.bin new file mode 100644 index 00000000..ba1ca960 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.1.xml.bin @@ -0,0 +1,15 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.json.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.json.bin new file mode 100644 index 00000000..2f146446 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.json.bin @@ -0,0 +1,39 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.xml.bin new file mode 100644 index 00000000..cb29e5ba --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.2.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.json.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.json.bin new file mode 100644 index 00000000..a075deb2 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.json.bin @@ -0,0 +1,39 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.xml.bin new file mode 100644 index 00000000..76ce40a0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.3.xml.bin @@ -0,0 +1,29 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + diff --git a/tests/fixtures/json/1.4/bom_setuptools_with_vulnerabilities.json b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.json.bin similarity index 76% rename from tests/fixtures/json/1.4/bom_setuptools_with_vulnerabilities.json rename to tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.json.bin index c7c0ed05..c1b42b96 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_with_vulnerabilities.json +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.json.bin @@ -1,121 +1,74 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, + "components": [ + { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - ], + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, "vulnerabilities": [ { - "bom-ref": "my-vuln-ref-1", - "id": "CVE-2018-7489", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489" - }, - "references": [ - { - "id": "SOME-OTHER-ID", - "source": { - "name": "OSS Index", - "url": "https://ossindex.sonatype.org/component/pkg:pypi/setuptools" - } - } - ], - "ratings": [ - { - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489" - }, - "score": 9.8, - "severity": "critical", - "method": "CVSSv3", - "vector": "AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", - "justification": "Some justification" - }, - { - "source": { - "name": "OWASP", - "url": "https://owasp.org" - }, - "score": 2.7, - "severity": "low", - "method": "CVSSv3", - "vector": "AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N", - "justification": "Some other justification" - } - ], - "cwes": [ - 22, - 33 - ], - "description": "A description here", - "detail": "Some detail here", - "recommendation": "Upgrade", "advisories": [ { "url": "http://www.securitytracker.com/id/1040693" @@ -124,62 +77,62 @@ "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489" } ], + "affects": [ + { + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "versions": [ + { + "range": "49.0.0 - 54.0.0", + "status": "affected" + } + ] + } + ], + "analysis": { + "detail": "Some extra detail", + "justification": "requires_environment", + "response": [ + "can_not_fix" + ], + "state": "exploitable" + }, + "bom-ref": "my-vuln-ref-1", "created": "2021-09-01T10:50:42.051979+00:00", - "published": "2021-09-02T10:50:42.051979+00:00", - "updated": "2021-09-03T10:50:42.051979+00:00", "credits": { + "individuals": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + } + ], "organizations": [ { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] } - ], - "individuals": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - } ] }, - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib" - } - ], - "analysis": { - "state": "exploitable", - "justification": "requires_environment", - "response": [ - "can_not_fix" - ], - "detail": "Some extra detail" - }, - "affects": [ - { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "versions": [ - { - "range": "49.0.0 - 54.0.0", - "status": "affected" - } - ] - } + "cwes": [ + 22, + 33 ], + "description": "A description here", + "detail": "Some detail here", + "id": "CVE-2018-7489", "properties": [ { "name": "key1", @@ -189,7 +142,56 @@ "name": "key2", "value": "val2" } - ] + ], + "published": "2021-09-02T10:50:42.051979+00:00", + "ratings": [ + { + "justification": "Some justification", + "method": "CVSSv3", + "score": 9.8, + "severity": "critical", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489" + }, + "vector": "AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + }, + { + "justification": "Some other justification", + "method": "CVSSv3", + "score": 2.7, + "severity": "low", + "source": { + "name": "OWASP", + "url": "https://owasp.org" + }, + "vector": "AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N" + } + ], + "recommendation": "Upgrade", + "references": [ + { + "id": "SOME-OTHER-ID", + "source": { + "name": "OSS Index", + "url": "https://ossindex.sonatype.org/component/pkg:pypi/setuptools" + } + } + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489" + }, + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX" + } + ], + "updated": "2021-09-03T10:50:42.051979+00:00" } - ] -} + ], + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.xml.bin new file mode 100644 index 00000000..3326f3f9 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.4.xml.bin @@ -0,0 +1,168 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + + + + CVE-2018-7489 + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2018-7489 + + + + SOME-OTHER-ID + + OSS Index + https://ossindex.sonatype.org/component/pkg:pypi/setuptools + + + + + + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2018-7489 + + 9.8 + critical + CVSSv3 + AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H + Some justification + + + + OWASP + https://owasp.org + + 2.7 + low + CVSSv3 + AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N + Some other justification + + + + 22 + 33 + + A description here + Some detail here + Upgrade + + + http://www.securitytracker.com/id/1040693 + + + https://nvd.nist.gov/vuln/detail/CVE-2018-7489 + + + 2021-09-01T10:50:42.051979+00:00 + 2021-09-02T10:50:42.051979+00:00 + 2021-09-03T10:50:42.051979+00:00 + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + + + + CycloneDX + cyclonedx-python-lib + + + + exploitable + requires_environment + + can_not_fix + + Some extra detail + + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + 49.0.0 - 54.0.0 + affected + + + + + + val1 + val2 + + + + diff --git a/tests/_data/snapshots/get_bom_with_component_toml_1-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_component_toml_1-1.0.xml.bin new file mode 100644 index 00000000..7355c2ca --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.0.xml.bin @@ -0,0 +1,14 @@ + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_component_toml_1-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_component_toml_1-1.1.xml.bin new file mode 100644 index 00000000..7f5932c1 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.1.xml.bin @@ -0,0 +1,19 @@ + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + diff --git a/tests/fixtures/json/1.2/bom_toml_1.json b/tests/_data/snapshots/get_bom_with_component_toml_1-1.2.json.bin similarity index 80% rename from tests/fixtures/json/1.2/bom_toml_1.json rename to tests/_data/snapshots/get_bom_with_component_toml_1-1.2.json.bin index 4180b39b..8e170b99 100644 --- a/tests/fixtures/json/1.2/bom_toml_1.json +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.2.json.bin @@ -1,44 +1,44 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:6f266d1c-760f-4552-ae3b-41a9b74232fa", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], + "name": "toml", "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_toml_1-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_component_toml_1-1.2.xml.bin new file mode 100644 index 00000000..ef97c383 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.2.xml.bin @@ -0,0 +1,32 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_toml_1.json b/tests/_data/snapshots/get_bom_with_component_toml_1-1.3.json.bin similarity index 85% rename from tests/fixtures/json/1.3/bom_toml_1.json rename to tests/_data/snapshots/get_bom_with_component_toml_1-1.3.json.bin index 2ec92274..aefb94a1 100644 --- a/tests/fixtures/json/1.3/bom_toml_1.json +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.3.json.bin @@ -1,50 +1,50 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:6f266d1c-760f-4552-ae3b-41a9b74232fa", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_toml_1-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_component_toml_1-1.3.xml.bin new file mode 100644 index 00000000..a9417823 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.3.xml.bin @@ -0,0 +1,35 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_toml_1.json b/tests/_data/snapshots/get_bom_with_component_toml_1-1.4.json.bin similarity index 72% rename from tests/fixtures/json/1.4/bom_toml_1.json rename to tests/_data/snapshots/get_bom_with_component_toml_1-1.4.json.bin index 80fe0ae3..1b883559 100644 --- a/tests/fixtures/json/1.4/bom_toml_1.json +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.4.json.bin @@ -1,84 +1,84 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:6f266d1c-760f-4552-ae3b-41a9b74232fa", - "version": 1, + "components": [ + { + "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "components": [ - { - "type": "library", - "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - } - ] - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_component_toml_1-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_component_toml_1-1.4.xml.bin new file mode 100644 index 00000000..a17f8a46 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_component_toml_1-1.4.xml.bin @@ -0,0 +1,61 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.0.xml.bin new file mode 100644 index 00000000..d0259a8a --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.0.xml.bin @@ -0,0 +1,20 @@ + + + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.1.xml.bin new file mode 100644 index 00000000..2a2038c3 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.1.xml.bin @@ -0,0 +1,29 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.json.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.json.bin new file mode 100644 index 00000000..6dc68f3d --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.json.bin @@ -0,0 +1,74 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "setuptools", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "toml", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "ref": "root-component" + }, + { + "dependsOn": [ + "toml" + ], + "ref": "setuptools" + }, + { + "ref": "toml" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "name": "rootComponent", + "type": "application", + "version": "" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 23, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.xml.bin new file mode 100644 index 00000000..39df1a3b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.2.xml.bin @@ -0,0 +1,51 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + rootComponent + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_with_dependencies_hanging.json b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.json.bin similarity index 72% rename from tests/fixtures/json/1.4/bom_with_dependencies_hanging.json rename to tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.json.bin index 92cf9405..20919e4f 100644 --- a/tests/fixtures/json/1.4/bom_with_dependencies_hanging.json +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.json.bin @@ -1,24 +1,13 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:12345678-395b-41f5-a30f-1234567890ab", - "version": 23, - "metadata": { - "component": { - "bom-ref": "root-component", - "name": "rootComponent", - "type": "application" - }, - "timestamp": "2023-06-01T03:03:07+00:00" - }, "components": [ { "author": "Test Author", "bom-ref": "setuptools", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], "name": "setuptools", @@ -58,13 +47,34 @@ "ref": "root-component" }, { - "ref": "setuptools", "dependsOn": [ "toml" - ] + ], + "ref": "setuptools" }, { "ref": "toml" } - ] -} + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "name": "rootComponent", + "type": "application", + "version": "" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 23, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.xml.bin new file mode 100644 index 00000000..cb19113f --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.3.xml.bin @@ -0,0 +1,54 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + rootComponent + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.json.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.json.bin new file mode 100644 index 00000000..e860d1fb --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.json.bin @@ -0,0 +1,113 @@ +{ + "components": [ + { + "author": "Test Author", + "bom-ref": "setuptools", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + { + "bom-ref": "toml", + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "ref": "root-component" + }, + { + "dependsOn": [ + "toml" + ], + "ref": "setuptools" + }, + { + "ref": "toml" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "name": "rootComponent", + "type": "application" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 23, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.xml.bin new file mode 100644 index 00000000..d13eaf18 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_hanging-1.4.xml.bin @@ -0,0 +1,79 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + rootComponent + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_valid-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.0.xml.bin new file mode 100644 index 00000000..9d0e55d4 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.0.xml.bin @@ -0,0 +1,20 @@ + + + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_dependencies_valid-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.1.xml.bin new file mode 100644 index 00000000..9d446f67 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.1.xml.bin @@ -0,0 +1,29 @@ + + + + + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + diff --git a/tests/fixtures/json/1.2/bom_dependencies.json b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.json.bin similarity index 69% rename from tests/fixtures/json/1.2/bom_dependencies.json rename to tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.json.bin index 8f54fe4a..44bde82b 100644 --- a/tests/fixtures/json/1.2/bom_dependencies.json +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.json.bin @@ -1,63 +1,65 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:6dc366e9-89eb-48cc-9ae8-49a810ce3dcb", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.575599+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], + "name": "toml", "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.xml.bin new file mode 100644 index 00000000..45734322 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.2.xml.bin @@ -0,0 +1,46 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_dependencies.json b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.json.bin similarity index 74% rename from tests/fixtures/json/1.3/bom_dependencies.json rename to tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.json.bin index afd36d07..945582d8 100644 --- a/tests/fixtures/json/1.3/bom_dependencies.json +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.json.bin @@ -1,69 +1,71 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d2ef50e0-27c7-4776-9e6f-9bbb3614d6de", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.875727+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.xml.bin new file mode 100644 index 00000000..0ac9a56b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.3.xml.bin @@ -0,0 +1,49 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_dependencies.json b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.json.bin similarity index 70% rename from tests/fixtures/json/1.4/bom_dependencies.json rename to tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.json.bin index 02c34960..4c0d4031 100644 --- a/tests/fixtures/json/1.4/bom_dependencies.json +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.json.bin @@ -1,103 +1,105 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ] - }, "components": [ { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "licenses": [ { - "expression": "MIT License" + "license": { + "id": "MIT" + } } ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" }, { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.xml.bin new file mode 100644 index 00000000..10868bec --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_dependencies_valid-1.4.xml.bin @@ -0,0 +1,75 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_external_references-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_external_references-1.0.xml.bin new file mode 100644 index 00000000..acb06612 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_external_references-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_external_references-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_external_references-1.1.xml.bin new file mode 100644 index 00000000..0a260e81 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_external_references-1.1.xml.bin @@ -0,0 +1,13 @@ + + + + + + https://cyclonedx.org + No comment + + + https://cyclonedx.org + + + diff --git a/tests/fixtures/json/1.2/bom_external_references.json b/tests/_data/snapshots/get_bom_with_external_references-1.2.json.bin similarity index 64% rename from tests/fixtures/json/1.2/bom_external_references.json rename to tests/_data/snapshots/get_bom_with_external_references-1.2.json.bin index fb370e06..0808ac13 100644 --- a/tests/fixtures/json/1.2/bom_external_references.json +++ b/tests/_data/snapshots/get_bom_with_external_references-1.2.json.bin @@ -1,28 +1,28 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } ] }, - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_external_references-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_external_references-1.2.xml.bin new file mode 100644 index 00000000..052f94d0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_external_references-1.2.xml.bin @@ -0,0 +1,22 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + https://cyclonedx.org + No comment + + + https://cyclonedx.org + + + diff --git a/tests/fixtures/json/1.3/bom_external_references.json b/tests/_data/snapshots/get_bom_with_external_references-1.3.json.bin similarity index 74% rename from tests/fixtures/json/1.3/bom_external_references.json rename to tests/_data/snapshots/get_bom_with_external_references-1.3.json.bin index a4d4d9fd..4f455662 100644 --- a/tests/fixtures/json/1.3/bom_external_references.json +++ b/tests/_data/snapshots/get_bom_with_external_references-1.3.json.bin @@ -1,34 +1,34 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:44:32.312678+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ] - }, "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] -} + ], + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_external_references-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_external_references-1.3.xml.bin new file mode 100644 index 00000000..b82483a0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_external_references-1.3.xml.bin @@ -0,0 +1,25 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + https://cyclonedx.org + + + diff --git a/tests/fixtures/json/1.4/bom_external_references.json b/tests/_data/snapshots/get_bom_with_external_references-1.4.json.bin similarity index 65% rename from tests/fixtures/json/1.4/bom_external_references.json rename to tests/_data/snapshots/get_bom_with_external_references-1.4.json.bin index 2f961c7b..6608b637 100644 --- a/tests/fixtures/json/1.4/bom_external_references.json +++ b/tests/_data/snapshots/get_bom_with_external_references-1.4.json.bin @@ -1,68 +1,68 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, + "externalReferences": [ + { + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "type": "distribution", + "url": "https://cyclonedx.org" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], "metadata": { "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } ] }, - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] -} + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_external_references-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_external_references-1.4.xml.bin new file mode 100644 index 00000000..877f4c95 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_external_references-1.4.xml.bin @@ -0,0 +1,51 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + https://cyclonedx.org + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_licenses-1.0.xml.bin new file mode 100644 index 00000000..1b308eaf --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.0.xml.bin @@ -0,0 +1,20 @@ + + + + + c-with-SPDX + + false + + + c-with-expression + + false + + + c-with-name + + false + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_licenses-1.1.xml.bin new file mode 100644 index 00000000..97aa8eb3 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.1.xml.bin @@ -0,0 +1,30 @@ + + + + + c-with-SPDX + + + + Apache-2.0 + + + + + c-with-expression + + + Apache-2.0 OR MIT + + + + c-with-name + + + + (c) ACME Inc. + + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.2.json.bin b/tests/_data/snapshots/get_bom_with_licenses-1.2.json.bin new file mode 100644 index 00000000..848073cd --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.2.json.bin @@ -0,0 +1,125 @@ +{ + "components": [ + { + "bom-ref": "C2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "c-with-SPDX", + "type": "library", + "version": "" + }, + { + "bom-ref": "C1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "c-with-expression", + "type": "library", + "version": "" + }, + { + "bom-ref": "C3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "c-with-name", + "type": "library", + "version": "" + } + ], + "dependencies": [ + { + "ref": "C1" + }, + { + "ref": "C2" + }, + { + "ref": "C3" + }, + { + "ref": "S1" + }, + { + "ref": "S2" + }, + { + "ref": "S3" + }, + { + "ref": "my-app" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "name": "proprietary" + } + } + ], + "name": "app", + "type": "application", + "version": "" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "S2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "s-with-SPDX" + }, + { + "bom-ref": "S1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "s-with-expression" + }, + { + "bom-ref": "S3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "s-with-name" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_licenses-1.2.xml.bin new file mode 100644 index 00000000..3f67d83c --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.2.xml.bin @@ -0,0 +1,82 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + + + + proprietary + + + + + + + c-with-SPDX + + + + Apache-2.0 + + + + + c-with-expression + + + Apache-2.0 OR MIT + + + + c-with-name + + + + (c) ACME Inc. + + + + + + + s-with-SPDX + + + Apache-2.0 + + + + + s-with-expression + + Apache-2.0 OR MIT + + + + s-with-name + + + (c) ACME Inc. + + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.3.json.bin b/tests/_data/snapshots/get_bom_with_licenses-1.3.json.bin new file mode 100644 index 00000000..143c48ba --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.3.json.bin @@ -0,0 +1,132 @@ +{ + "components": [ + { + "bom-ref": "C2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "c-with-SPDX", + "type": "library", + "version": "" + }, + { + "bom-ref": "C1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "c-with-expression", + "type": "library", + "version": "" + }, + { + "bom-ref": "C3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "c-with-name", + "type": "library", + "version": "" + } + ], + "dependencies": [ + { + "ref": "C1" + }, + { + "ref": "C2" + }, + { + "ref": "C3" + }, + { + "ref": "S1" + }, + { + "ref": "S2" + }, + { + "ref": "S3" + }, + { + "ref": "my-app" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "name": "proprietary" + } + } + ], + "name": "app", + "type": "application", + "version": "" + }, + "licenses": [ + { + "license": { + "id": "CC-BY-1.0" + } + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "S2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "s-with-SPDX" + }, + { + "bom-ref": "S1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "s-with-expression" + }, + { + "bom-ref": "S3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "s-with-name" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_licenses-1.3.xml.bin new file mode 100644 index 00000000..89792211 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.3.xml.bin @@ -0,0 +1,87 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + + + + proprietary + + + + + + CC-BY-1.0 + + + + + + c-with-SPDX + + + + Apache-2.0 + + + + + c-with-expression + + + Apache-2.0 OR MIT + + + + c-with-name + + + + (c) ACME Inc. + + + + + + + s-with-SPDX + + + Apache-2.0 + + + + + s-with-expression + + Apache-2.0 OR MIT + + + + s-with-name + + + (c) ACME Inc. + + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.4.json.bin b/tests/_data/snapshots/get_bom_with_licenses-1.4.json.bin new file mode 100644 index 00000000..a4965e69 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.4.json.bin @@ -0,0 +1,162 @@ +{ + "components": [ + { + "bom-ref": "C2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "c-with-SPDX", + "type": "library" + }, + { + "bom-ref": "C1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "c-with-expression", + "type": "library" + }, + { + "bom-ref": "C3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "c-with-name", + "type": "library" + } + ], + "dependencies": [ + { + "ref": "C1" + }, + { + "ref": "C2" + }, + { + "ref": "C3" + }, + { + "ref": "S1" + }, + { + "ref": "S2" + }, + { + "ref": "S3" + }, + { + "ref": "my-app" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "name": "proprietary" + } + } + ], + "name": "app", + "type": "application" + }, + "licenses": [ + { + "license": { + "id": "CC-BY-1.0" + } + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "S2", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "s-with-SPDX" + }, + { + "bom-ref": "S1", + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "s-with-expression" + }, + { + "bom-ref": "S3", + "licenses": [ + { + "license": { + "name": "(c) ACME Inc." + } + } + ], + "name": "s-with-name" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_licenses-1.4.xml.bin new file mode 100644 index 00000000..2afc522a --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses-1.4.xml.bin @@ -0,0 +1,109 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + app + + + proprietary + + + + + + CC-BY-1.0 + + + + + + c-with-SPDX + + + Apache-2.0 + + + + + c-with-expression + + Apache-2.0 OR MIT + + + + c-with-name + + + (c) ACME Inc. + + + + + + + s-with-SPDX + + + Apache-2.0 + + + + + s-with-expression + + Apache-2.0 OR MIT + + + + s-with-name + + + (c) ACME Inc. + + + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.0.xml.bin new file mode 100644 index 00000000..acb06612 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.1.xml.bin new file mode 100644 index 00000000..55ef5cda --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.json.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.json.bin new file mode 100644 index 00000000..1165e037 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.json.bin @@ -0,0 +1,17 @@ +{ + "metadata": { + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.xml.bin new file mode 100644 index 00000000..bc36ede0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.2.xml.bin @@ -0,0 +1,13 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.json.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.json.bin new file mode 100644 index 00000000..1d765cdb --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.json.bin @@ -0,0 +1,22 @@ +{ + "metadata": { + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.xml.bin new file mode 100644 index 00000000..bb16ef4f --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.3.xml.bin @@ -0,0 +1,16 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + Apache-2.0 OR MIT + + + diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.json.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.json.bin new file mode 100644 index 00000000..d484276f --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.json.bin @@ -0,0 +1,56 @@ +{ + "metadata": { + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.xml.bin new file mode 100644 index 00000000..0361c11f --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_licenses_expression-1.4.xml.bin @@ -0,0 +1,42 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + Apache-2.0 OR MIT + + + diff --git a/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.0.xml.bin new file mode 100644 index 00000000..7355c2ca --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.0.xml.bin @@ -0,0 +1,14 @@ + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + + diff --git a/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.1.xml.bin new file mode 100644 index 00000000..7f5932c1 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.1.xml.bin @@ -0,0 +1,19 @@ + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + diff --git a/tests/fixtures/json/1.2/bom_dependencies_component.json b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.json.bin similarity index 69% rename from tests/fixtures/json/1.2/bom_dependencies_component.json rename to tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.json.bin index dd6b880e..8e1ad38b 100644 --- a/tests/fixtures/json/1.2/bom_dependencies_component.json +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.json.bin @@ -1,63 +1,65 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:fae7d0a5-648d-4058-be92-774ed4f974eb", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.597300+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - }, "components": [ { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } ], + "name": "toml", "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "externalReferences": [ - { - "url": "https://cyclonedx.org", - "comment": "No comment", - "type": "distribution" - } - ] + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "component": { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.xml.bin new file mode 100644 index 00000000..9f181dd3 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.2.xml.bin @@ -0,0 +1,46 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_dependencies_component.json b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.json.bin similarity index 73% rename from tests/fixtures/json/1.3/bom_dependencies_component.json rename to tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.json.bin index 1820acbd..44d8a573 100644 --- a/tests/fixtures/json/1.3/bom_dependencies_component.json +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.json.bin @@ -1,69 +1,71 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:f1ab7398-e797-4ac1-8fdd-f2901bd5059d", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:57.901622+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING" - } - ], - "component": { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - }, "components": [ { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } - ] + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "component": { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.xml.bin new file mode 100644 index 00000000..6a0e37c3 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.3.xml.bin @@ -0,0 +1,49 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_dependencies_component.json b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.json.bin similarity index 67% rename from tests/fixtures/json/1.4/bom_dependencies_component.json rename to tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.json.bin index df8cc3b7..6852fd3b 100644 --- a/tests/fixtures/json/1.4/bom_dependencies_component.json +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.json.bin @@ -1,103 +1,105 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:890c2dff-1e2c-4133-a0b1-ee23d93737af", - "version": 1, - "metadata": { - "timestamp": "2023-01-07T13:45:58.782058+00:00", - "tools": [ - { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", - "externalReferences": [ - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" - }, - { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" - }, - { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" - }, - { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" - }, - { - "url": "https://cyclonedx.org", - "type": "website" - } - ] - } - ], - "component": { - "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", - "author": "Test Author", - "name": "setuptools", - "version": "50.3.2", - "licenses": [ - { - "expression": "MIT License" - } - ], - "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" - } - }, "components": [ { - "type": "library", "bom-ref": "pkg:pypi/toml@0.10.2?extension=tar.gz", - "name": "toml", - "version": "0.10.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ], - "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2?extension=tar.gz", + "type": "library", + "version": "0.10.2" } ], "dependencies": [ { - "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "dependsOn": [ "pkg:pypi/toml@0.10.2?extension=tar.gz" - ] + ], + "ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz" }, { "ref": "pkg:pypi/toml@0.10.2?extension=tar.gz" } - ] -} + ], + "metadata": { + "component": { + "author": "Test Author", + "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "setuptools", + "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "type": "library", + "version": "50.3.2" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.xml.bin new file mode 100644 index 00000000..38c9e479 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_metadata_component_and_dependencies-1.4.xml.bin @@ -0,0 +1,75 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + Test Author + setuptools + 50.3.2 + + + MIT + + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.0.xml.bin new file mode 100644 index 00000000..13a20245 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.0.xml.bin @@ -0,0 +1,10 @@ + + + + + comp + + false + + + diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.1.xml.bin new file mode 100644 index 00000000..27b2bce0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.1.xml.bin @@ -0,0 +1,17 @@ + + + + + comp + + + + MIT + + + foo license + + + + + diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.json.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.json.bin new file mode 100644 index 00000000..19aadbf1 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.json.bin @@ -0,0 +1,84 @@ +{ + "components": [ + { + "bom-ref": "my-compo", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "comp", + "type": "library", + "version": "" + } + ], + "dependencies": [ + { + "ref": "my-app" + }, + { + "ref": "my-compo" + }, + { + "ref": "my-serv" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "app", + "type": "application", + "version": "" + }, + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "my-serv", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "serv" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.xml.bin new file mode 100644 index 00000000..df26741d --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.2.xml.bin @@ -0,0 +1,57 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + + + + MIT + + + foo license + + + + + + + comp + + + + MIT + + + foo license + + + + + + + serv + + + MIT + + + foo license + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.json.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.json.bin new file mode 100644 index 00000000..1a6eba50 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.json.bin @@ -0,0 +1,96 @@ +{ + "components": [ + { + "bom-ref": "my-compo", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "comp", + "type": "library", + "version": "" + } + ], + "dependencies": [ + { + "ref": "my-app" + }, + { + "ref": "my-compo" + }, + { + "ref": "my-serv" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "app", + "type": "application", + "version": "" + }, + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "my-serv", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "serv" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.xml.bin new file mode 100644 index 00000000..1bb3e0ab --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.3.xml.bin @@ -0,0 +1,65 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + app + + + + MIT + + + foo license + + + + + + MIT + + + foo license + + + + + + comp + + + + MIT + + + foo license + + + + + + + serv + + + MIT + + + foo license + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.json.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.json.bin new file mode 100644 index 00000000..b8751bb0 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.json.bin @@ -0,0 +1,128 @@ +{ + "components": [ + { + "bom-ref": "my-compo", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "comp", + "type": "library" + } + ], + "dependencies": [ + { + "ref": "my-app" + }, + { + "ref": "my-compo" + }, + { + "ref": "my-serv" + } + ], + "metadata": { + "component": { + "bom-ref": "my-app", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "app", + "type": "application" + }, + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "timestamp": "2023-01-07T13:44:32.312678+00:00", + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://cyclonedx.org" + } + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" + } + ] + }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", + "services": [ + { + "bom-ref": "my-serv", + "licenses": [ + { + "license": { + "id": "MIT" + } + }, + { + "license": { + "name": "foo license" + } + } + ], + "name": "serv" + } + ], + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.xml.bin new file mode 100644 index 00000000..7afbd2d7 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_multiple_licenses-1.4.xml.bin @@ -0,0 +1,89 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + app + + + MIT + + + foo license + + + + + + MIT + + + foo license + + + + + + comp + + + MIT + + + foo license + + + + + + + serv + + + MIT + + + foo license + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_nested_services-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_nested_services-1.0.xml.bin new file mode 100644 index 00000000..acb06612 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_nested_services-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_nested_services-1.1.xml.bin new file mode 100644 index 00000000..55ef5cda --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/fixtures/json/1.2/bom_services_nested.json b/tests/_data/snapshots/get_bom_with_nested_services-1.2.json.bin similarity index 86% rename from tests/fixtures/json/1.2/bom_services_nested.json rename to tests/_data/snapshots/get_bom_with_nested_services-1.2.json.bin index f927f9d7..e5ca79e9 100644 --- a/tests/fixtures/json/1.2/bom_services_nested.json +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.2.json.bin @@ -1,9 +1,18 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { "component": { - "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", + "bom-ref": "my-specific-bom-ref-for-cpl", "name": "cyclonedx-python-lib", "type": "library", "version": "1.0.0" @@ -17,7 +26,7 @@ } ] }, - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { "authenticated": false, @@ -43,20 +52,22 @@ "group": "a-group", "licenses": [ { - "expression": "Commercial" + "license": { + "name": "Commercial" + } } ], "name": "my-first-service", "provider": { "contact": [ - { - "email": "paul.horton@owasp.org", - "name": "Paul Horton" - }, { "email": "someone@somewhere.tld", "name": "A N Other", "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "name": "CycloneDX", @@ -65,10 +76,6 @@ ] }, "services": [ - { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "name": "first-nested-service" - }, { "authenticated": true, "bom-ref": "my-specific-bom-ref-for-second-nested-service", @@ -76,14 +83,14 @@ "name": "second-nested-service", "provider": { "contact": [ - { - "email": "paul.horton@owasp.org", - "name": "Paul Horton" - }, { "email": "someone@somewhere.tld", "name": "A N Other", "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "name": "CycloneDX", @@ -93,29 +100,33 @@ }, "version": "3.2.1", "x-trust-boundary": false + }, + { + "bom-ref": "my-specific-bom-ref-for-first-nested-service", + "name": "first-nested-service" } ], "version": "1.2.3", "x-trust-boundary": true }, { - "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service", "services": [ { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "00000000-0000-4000-8000-000000000003", "group": "what-group", "name": "yet-another-nested-service", "provider": { "contact": [ - { - "email": "paul.horton@owasp.org", - "name": "Paul Horton" - }, { "email": "someone@somewhere.tld", "name": "A N Other", "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "name": "CycloneDX", @@ -132,17 +143,8 @@ ] } ], - "specVersion": "1.2", "version": 1, - "dependencies": [ - { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" - }, - { - "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - }, - { - "ref": "my-specific-bom-ref-for-my-first-service" - } - ] -} + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_nested_services-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_nested_services-1.2.xml.bin new file mode 100644 index 00000000..84fd1409 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.2.xml.bin @@ -0,0 +1,114 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + no-group + second-nested-service + 3.2.1 + true + false + + + first-nested-service + + + + + my-second-service + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + what-group + yet-another-nested-service + 6.5.4 + + + another-nested-service + + + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_services_nested.json b/tests/_data/snapshots/get_bom_with_nested_services-1.3.json.bin similarity index 77% rename from tests/fixtures/json/1.3/bom_services_nested.json rename to tests/_data/snapshots/get_bom_with_nested_services-1.3.json.bin index 82e9e187..9b89174d 100644 --- a/tests/fixtures/json/1.3/bom_services_nested.json +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.3.json.bin @@ -1,146 +1,155 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "my-specific-bom-ref-for-my-first-service", - "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "group": "a-group", - "name": "my-first-service", - "version": "1.2.3", - "description": "Description goes here", - "endpoints": [ - "/api/thing/1", - "/api/thing/2" - ], "authenticated": false, - "x-trust-boundary": true, + "bom-ref": "my-specific-bom-ref-for-my-first-service", "data": [ { - "flow": "outbound", - "classification": "public" + "classification": "public", + "flow": "outbound" } ], - "licenses": [ - { - "expression": "Commercial" - } + "description": "Description goes here", + "endpoints": [ + "/api/thing/1", + "/api/thing/2" ], "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "group": "a-group", + "licenses": [ + { + "license": { + "name": "Commercial" + } + } + ], + "name": "my-first-service", + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" } ], + "provider": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, "services": [ { + "authenticated": true, "bom-ref": "my-specific-bom-ref-for-second-nested-service", + "group": "no-group", + "name": "second-nested-service", "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, - "group": "no-group", - "name": "second-nested-service", "version": "3.2.1", - "authenticated": true, "x-trust-boundary": false }, { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-first-nested-service", "name": "first-nested-service" } ], - "properties": [ - { - "name": "key1", - "value": "val1" - }, - { - "name": "key2", - "value": "val2" - } - ] + "version": "1.2.3", + "x-trust-boundary": true }, { - "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service", "services": [ { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "00000000-0000-4000-8000-000000000002", + "group": "what-group", + "name": "yet-another-nested-service", "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, - "group": "what-group", - "name": "yet-another-nested-service", "version": "6.5.4" }, { @@ -150,15 +159,8 @@ ] } ], - "dependencies": [ - { - "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - }, - { - "ref": "my-specific-bom-ref-for-my-first-service" - }, - { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_nested_services-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_nested_services-1.3.xml.bin new file mode 100644 index 00000000..29b5d27b --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.3.xml.bin @@ -0,0 +1,121 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + no-group + second-nested-service + 3.2.1 + true + false + + + first-nested-service + + + + + my-second-service + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + what-group + yet-another-nested-service + 6.5.4 + + + another-nested-service + + + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_services_nested.json b/tests/_data/snapshots/get_bom_with_nested_services-1.4.json.bin similarity index 77% rename from tests/fixtures/json/1.4/bom_services_nested.json rename to tests/_data/snapshots/get_bom_with_nested_services-1.4.json.bin index 3c674682..f11014a5 100644 --- a/tests/fixtures/json/1.4/bom_services_nested.json +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.4.json.bin @@ -1,190 +1,152 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "my-specific-bom-ref-for-my-first-service", - "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "group": "a-group", - "name": "my-first-service", - "version": "1.2.3", - "description": "Description goes here", - "endpoints": [ - "/api/thing/1", - "/api/thing/2" - ], "authenticated": false, - "x-trust-boundary": true, + "bom-ref": "my-specific-bom-ref-for-my-first-service", "data": [ { - "flow": "outbound", - "classification": "public" + "classification": "public", + "flow": "outbound" } ], - "licenses": [ - { - "expression": "Commercial" - } + "description": "Description goes here", + "endpoints": [ + "/api/thing/1", + "/api/thing/2" ], "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], - "services": [ + "group": "a-group", + "licenses": [ { - "bom-ref": "my-specific-bom-ref-for-second-nested-service", - "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "group": "no-group", - "name": "second-nested-service", - "version": "3.2.1", - "authenticated": true, - "x-trust-boundary": false + "license": { + "name": "Commercial" + } + } + ], + "name": "my-first-service", + "properties": [ + { + "name": "key1", + "value": "val1" }, { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", - "name": "first-nested-service" + "name": "key2", + "value": "val2" } ], + "provider": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, "releaseNotes": { - "type": "major", - "title": "Release Notes Title", - "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", - "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", - "description": "This release is a test release", - "timestamp": "2021-12-31T10:00:00+00:00", "aliases": [ "First Test Release" ], - "tags": [ - "alpha", - "test" - ], - "resolves": [ - { - "type": "security", - "id": "CVE-2021-44228", - "name": "Apache Log3Shell", - "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" - }, - "references": [ - "https://central.sonatype.org/news/20211213_log4shell_help", - "https://logging.apache.org/log4j/2.x/security.html" - ] - } - ], + "description": "This release is a test release", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", "notes": [ { + "locale": "en-GB", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-GB" + } }, { + "locale": "en-US", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-US" + } } ], "properties": [ @@ -196,44 +158,91 @@ "name": "key2", "value": "val2" } - ] + ], + "resolves": [ + { + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "references": [ + "https://central.sonatype.org/news/20211213_log4shell_help", + "https://logging.apache.org/log4j/2.x/security.html" + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "type": "security" + } + ], + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "tags": [ + "alpha", + "test" + ], + "timestamp": "2023-08-15T01:23:45.678900+00:00", + "title": "Release Notes Title", + "type": "major" }, - "properties": [ + "services": [ { - "name": "key1", - "value": "val1" + "authenticated": true, + "bom-ref": "my-specific-bom-ref-for-second-nested-service", + "group": "no-group", + "name": "second-nested-service", + "provider": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, + "version": "3.2.1", + "x-trust-boundary": false }, { - "name": "key2", - "value": "val2" + "bom-ref": "my-specific-bom-ref-for-first-nested-service", + "name": "first-nested-service" } - ] + ], + "version": "1.2.3", + "x-trust-boundary": true }, { - "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service", "services": [ { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "00000000-0000-4000-8000-000000000001", + "group": "what-group", + "name": "yet-another-nested-service", "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], "contact": [ { - "name": "A N Other", "email": "someone@somewhere.tld", + "name": "A N Other", "phone": "+44 (0)1234 567890" }, { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" ] }, - "group": "what-group", - "name": "yet-another-nested-service", "version": "6.5.4" }, { @@ -243,15 +252,8 @@ ] } ], - "dependencies": [ - { - "ref": "my-specific-bom-ref-for-my-first-service" - }, - { - "ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857" - }, - { - "ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_nested_services-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_nested_services-1.4.xml.bin new file mode 100644 index 00000000..78c93eed --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_nested_services-1.4.xml.bin @@ -0,0 +1,191 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + no-group + second-nested-service + 3.2.1 + true + false + + + first-nested-service + + + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2023-08-15T01:23:45.678900+00:00 + + First Test Release + + + alpha + test + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://central.sonatype.org/news/20211213_log4shell_help + https://logging.apache.org/log4j/2.x/security.html + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + + + + my-second-service + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + what-group + yet-another-nested-service + 6.5.4 + + + another-nested-service + + + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_services_complex-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_services_complex-1.0.xml.bin new file mode 100644 index 00000000..acb06612 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_services_complex-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_services_complex-1.1.xml.bin new file mode 100644 index 00000000..55ef5cda --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/fixtures/json/1.2/bom_services_complex.json b/tests/_data/snapshots/get_bom_with_services_complex-1.2.json.bin similarity index 79% rename from tests/fixtures/json/1.2/bom_services_complex.json rename to tests/_data/snapshots/get_bom_with_services_complex-1.2.json.bin index 2caa9876..d66fe485 100644 --- a/tests/fixtures/json/1.2/bom_services_complex.json +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.2.json.bin @@ -1,38 +1,73 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { + "authenticated": false, "bom-ref": "my-specific-bom-ref-for-my-first-service", + "data": [ + { + "classification": "public", + "flow": "outbound" + } + ], + "description": "Description goes here", + "endpoints": [ + "/api/thing/1", + "/api/thing/2" + ], + "externalReferences": [ + { + "comment": "No comment", + "type": "distribution", + "url": "https://cyclonedx.org" + } + ], + "group": "a-group", + "licenses": [ + { + "license": { + "name": "Commercial" + } + } + ], + "name": "my-first-service", "provider": { "contact": [ - { - "email": "paul.horton@owasp.org", - "name": "Paul Horton" - }, { "email": "someone@somewhere.tld", "name": "A N Other", "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" } ], "name": "CycloneDX", @@ -40,49 +75,16 @@ "https://cyclonedx.org" ] }, - "group": "a-group", - "name": "my-first-service", "version": "1.2.3", - "description": "Description goes here", - "endpoints": [ - "/api/thing/1", - "/api/thing/2" - ], - "authenticated": false, - "x-trust-boundary": true, - "data": [ - { - "classification": "public", - "flow": "outbound" - } - ], - "licenses": [ - { - "expression": "Commercial" - } - ], - "externalReferences": [ - { - "comment": "No comment", - "type": "distribution", - "url": "https://cyclonedx.org" - } - ] + "x-trust-boundary": true }, { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655" - }, - { - "ref": "my-specific-bom-ref-for-my-first-service" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_complex-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_services_complex-1.2.xml.bin new file mode 100644 index 00000000..d03f661e --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.2.xml.bin @@ -0,0 +1,66 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + + + + my-second-service + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_services_complex.json b/tests/_data/snapshots/get_bom_with_services_complex-1.3.json.bin similarity index 74% rename from tests/fixtures/json/1.3/bom_services_complex.json rename to tests/_data/snapshots/get_bom_with_services_complex-1.3.json.bin index f222cd50..a4827614 100644 --- a/tests/fixtures/json/1.3/bom_services_complex.json +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.3.json.bin @@ -1,79 +1,69 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "my-specific-bom-ref-for-my-first-service", - "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "group": "a-group", - "name": "my-first-service", - "version": "1.2.3", - "description": "Description goes here", - "endpoints": [ - "/api/thing/1", - "/api/thing/2" - ], "authenticated": false, - "x-trust-boundary": true, + "bom-ref": "my-specific-bom-ref-for-my-first-service", "data": [ { - "flow": "outbound", - "classification": "public" + "classification": "public", + "flow": "outbound" } ], - "licenses": [ - { - "expression": "Commercial" - } + "description": "Description goes here", + "endpoints": [ + "/api/thing/1", + "/api/thing/2" ], "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], + "group": "a-group", + "licenses": [ + { + "license": { + "name": "Commercial" + } + } + ], + "name": "my-first-service", "properties": [ { "name": "key1", @@ -83,22 +73,34 @@ "name": "key2", "value": "val2" } - ] + ], + "provider": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, + "version": "1.2.3", + "x-trust-boundary": true }, { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "my-specific-bom-ref-for-my-first-service" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - }, - { - "ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_complex-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_services_complex-1.3.xml.bin new file mode 100644 index 00000000..136d59a1 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.3.xml.bin @@ -0,0 +1,73 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + my-second-service + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_services_complex.json b/tests/_data/snapshots/get_bom_with_services_complex-1.4.json.bin similarity index 75% rename from tests/fixtures/json/1.4/bom_services_complex.json rename to tests/_data/snapshots/get_bom_with_services_complex-1.4.json.bin index d4d80b06..52ae938d 100644 --- a/tests/fixtures/json/1.4/bom_services_complex.json +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.4.json.bin @@ -1,159 +1,152 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "my-specific-bom-ref-for-my-first-service", - "provider": { - "name": "CycloneDX", - "url": [ - "https://cyclonedx.org" - ], - "contact": [ - { - "name": "A N Other", - "email": "someone@somewhere.tld", - "phone": "+44 (0)1234 567890" - }, - { - "name": "Paul Horton", - "email": "paul.horton@owasp.org" - } - ] - }, - "group": "a-group", - "name": "my-first-service", - "version": "1.2.3", - "description": "Description goes here", - "endpoints": [ - "/api/thing/1", - "/api/thing/2" - ], "authenticated": false, - "x-trust-boundary": true, + "bom-ref": "my-specific-bom-ref-for-my-first-service", "data": [ { - "flow": "outbound", - "classification": "public" + "classification": "public", + "flow": "outbound" } ], - "licenses": [ - { - "expression": "Commercial" - } + "description": "Description goes here", + "endpoints": [ + "/api/thing/1", + "/api/thing/2" ], "externalReferences": [ { - "url": "https://cyclonedx.org", "comment": "No comment", - "type": "distribution", "hashes": [ { "alg": "SHA-256", "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" } - ] + ], + "type": "distribution", + "url": "https://cyclonedx.org" } ], + "group": "a-group", + "licenses": [ + { + "license": { + "name": "Commercial" + } + } + ], + "name": "my-first-service", + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ], + "provider": { + "contact": [ + { + "email": "someone@somewhere.tld", + "name": "A N Other", + "phone": "+44 (0)1234 567890" + }, + { + "email": "paul.horton@owasp.org", + "name": "Paul Horton" + } + ], + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ] + }, "releaseNotes": { - "type": "major", - "title": "Release Notes Title", - "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", - "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", - "description": "This release is a test release", - "timestamp": "2021-12-31T10:00:00+00:00", "aliases": [ "First Test Release" ], - "tags": [ - "alpha", - "test" - ], - "resolves": [ - { - "type": "security", - "id": "CVE-2021-44228", - "name": "Apache Log3Shell", - "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", - "source": { - "name": "NVD", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" - }, - "references": [ - "https://central.sonatype.org/news/20211213_log4shell_help", - "https://logging.apache.org/log4j/2.x/security.html" - ] - } - ], + "description": "This release is a test release", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", "notes": [ { + "locale": "en-GB", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-GB" + } }, { + "locale": "en-US", "text": { "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==", "contentType": "text/plain; charset=UTF-8", "encoding": "base64" - }, - "locale": "en-US" + } } ], "properties": [ @@ -165,33 +158,42 @@ "name": "key2", "value": "val2" } - ] + ], + "resolves": [ + { + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "references": [ + "https://central.sonatype.org/news/20211213_log4shell_help", + "https://logging.apache.org/log4j/2.x/security.html" + ], + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "type": "security" + } + ], + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "tags": [ + "alpha", + "test" + ], + "timestamp": "2023-08-15T01:23:45.678900+00:00", + "title": "Release Notes Title", + "type": "major" }, - "properties": [ - { - "name": "key1", - "value": "val1" - }, - { - "name": "key2", - "value": "val2" - } - ] + "version": "1.2.3", + "x-trust-boundary": true }, { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655" - }, - { - "ref": "my-specific-bom-ref-for-my-first-service" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_complex-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_services_complex-1.4.xml.bin new file mode 100644 index 00000000..3c9b6dbe --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_complex-1.4.xml.bin @@ -0,0 +1,143 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + cyclonedx-python-lib + 1.0.0 + + + + + + CycloneDX + https://cyclonedx.org + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + + Paul Horton + paul.horton@owasp.org + + + a-group + my-first-service + 1.2.3 + Description goes here + + /api/thing/1 + /api/thing/2 + + false + true + + public + + + + Commercial + + + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2023-08-15T01:23:45.678900+00:00 + + First Test Release + + + alpha + test + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://central.sonatype.org/news/20211213_log4shell_help + https://logging.apache.org/log4j/2.x/security.html + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + + + + my-second-service + + + + + + + + diff --git a/tests/_data/snapshots/get_bom_with_services_simple-1.0.xml.bin b/tests/_data/snapshots/get_bom_with_services_simple-1.0.xml.bin new file mode 100644 index 00000000..acb06612 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.0.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/_data/snapshots/get_bom_with_services_simple-1.1.xml.bin b/tests/_data/snapshots/get_bom_with_services_simple-1.1.xml.bin new file mode 100644 index 00000000..55ef5cda --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.1.xml.bin @@ -0,0 +1,4 @@ + + + + diff --git a/tests/fixtures/json/1.2/bom_services_simple.json b/tests/_data/snapshots/get_bom_with_services_simple-1.2.json.bin similarity index 57% rename from tests/fixtures/json/1.2/bom_services_simple.json rename to tests/_data/snapshots/get_bom_with_services_simple-1.2.json.bin index 198bfadd..e7562ceb 100644 --- a/tests/fixtures/json/1.2/bom_services_simple.json +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.2.json.bin @@ -1,44 +1,44 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.2", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-first-service", "name": "my-first-service" }, { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - }, - { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_simple-1.2.xml.bin b/tests/_data/snapshots/get_bom_with_services_simple-1.2.xml.bin new file mode 100644 index 00000000..60db211e --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.2.xml.bin @@ -0,0 +1,30 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + my-first-service + + + my-second-service + + + + + + + + diff --git a/tests/fixtures/json/1.3/bom_services_simple.json b/tests/_data/snapshots/get_bom_with_services_simple-1.3.json.bin similarity index 57% rename from tests/fixtures/json/1.3/bom_services_simple.json rename to tests/_data/snapshots/get_bom_with_services_simple-1.3.json.bin index a18e31cb..4c2ea8b2 100644 --- a/tests/fixtures/json/1.3/bom_services_simple.json +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.3.json.bin @@ -1,44 +1,44 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.3", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-first-service", "name": "my-first-service" }, { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - }, - { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_simple-1.3.xml.bin b/tests/_data/snapshots/get_bom_with_services_simple-1.3.xml.bin new file mode 100644 index 00000000..08fcc576 --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.3.xml.bin @@ -0,0 +1,30 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + + cyclonedx-python-lib + 1.0.0 + + + + + my-first-service + + + my-second-service + + + + + + + + diff --git a/tests/fixtures/json/1.4/bom_services_simple.json b/tests/_data/snapshots/get_bom_with_services_simple-1.4.json.bin similarity index 58% rename from tests/fixtures/json/1.4/bom_services_simple.json rename to tests/_data/snapshots/get_bom_with_services_simple-1.4.json.bin index 38c71422..78ab5848 100644 --- a/tests/fixtures/json/1.4/bom_services_simple.json +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.4.json.bin @@ -1,78 +1,78 @@ { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:d0b24ba4-102b-497e-b31f-4fdc3f0a3005", - "version": 1, + "dependencies": [ + { + "ref": "my-specific-bom-ref-for-cpl" + }, + { + "ref": "my-specific-bom-ref-for-my-first-service" + }, + { + "ref": "my-specific-bom-ref-for-my-second-service" + } + ], "metadata": { + "component": { + "bom-ref": "my-specific-bom-ref-for-cpl", + "name": "cyclonedx-python-lib", + "type": "library", + "version": "1.0.0" + }, "timestamp": "2023-01-07T13:44:32.312678+00:00", "tools": [ { - "vendor": "CycloneDX", - "name": "cyclonedx-python-lib", - "version": "TESTING", "externalReferences": [ { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions", - "type": "build-system" + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" }, { - "url": "https://pypi.org/project/cyclonedx-python-lib/", - "type": "distribution" + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" }, { - "url": "https://cyclonedx.github.io/cyclonedx-python-lib/", - "type": "documentation" + "type": "documentation", + "url": "https://cyclonedx.github.io/cyclonedx-python-lib/" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues", - "type": "issue-tracker" + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE", - "type": "license" + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md", - "type": "release-notes" + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" }, { - "url": "https://github.com/CycloneDX/cyclonedx-python-lib", - "type": "vcs" + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" }, { - "url": "https://cyclonedx.org", - "type": "website" + "type": "website", + "url": "https://cyclonedx.org" } - ] + ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "TESTING" } - ], - "component": { - "type": "library", - "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", - "name": "cyclonedx-python-lib", - "version": "1.0.0" - } + ] }, + "serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac", "services": [ { - "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", + "bom-ref": "my-specific-bom-ref-for-my-first-service", "name": "my-first-service" }, { - "bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda", + "bom-ref": "my-specific-bom-ref-for-my-second-service", "name": "my-second-service" } ], - "dependencies": [ - { - "ref": "df70b5f1-8f53-47a4-be48-669ae78795e6" - }, - { - "ref": "be2c6502-7e9a-47db-9a66-e34f729810a3" - }, - { - "ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda" - } - ] -} + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/get_bom_with_services_simple-1.4.xml.bin b/tests/_data/snapshots/get_bom_with_services_simple-1.4.xml.bin new file mode 100644 index 00000000..ed0a032d --- /dev/null +++ b/tests/_data/snapshots/get_bom_with_services_simple-1.4.xml.bin @@ -0,0 +1,56 @@ + + + + 2023-01-07T13:44:32.312678+00:00 + + + CycloneDX + cyclonedx-python-lib + TESTING + + + https://github.com/CycloneDX/cyclonedx-python-lib/actions + + + https://pypi.org/project/cyclonedx-python-lib/ + + + https://cyclonedx.github.io/cyclonedx-python-lib/ + + + https://github.com/CycloneDX/cyclonedx-python-lib/issues + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python-lib + + + https://cyclonedx.org + + + + + + cyclonedx-python-lib + 1.0.0 + + + + + my-first-service + + + my-second-service + + + + + + + + diff --git a/tests/base.py b/tests/base.py deleted file mode 100644 index c844396c..00000000 --- a/tests/base.py +++ /dev/null @@ -1,148 +0,0 @@ -# encoding: utf-8 - -# This file is part of CycloneDX Python Lib -# -# 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. - -import io -import json -import os -import sys -import xml.etree.ElementTree -from datetime import datetime, timezone -from typing import Any -from unittest import TestCase -from uuid import uuid4 - -from lxml import etree -from lxml.etree import DocumentInvalid -from xmldiff import main -from xmldiff.actions import MoveNode - -from cyclonedx.output import SchemaVersion - -if sys.version_info >= (3, 7): - from jsonschema import ValidationError, validate as json_validate - -from . import CDX_SCHEMA_DIRECTORY - -single_uuid: str = 'urn:uuid:{}'.format(uuid4()) - - -class BaseJsonTestCase(TestCase): - - def assertValidAgainstSchema(self, bom_json: str, schema_version: SchemaVersion) -> None: - if sys.version_info >= (3, 7): - schema_fn = os.path.join( - CDX_SCHEMA_DIRECTORY, - f'bom-{schema_version.name.replace("_", ".").replace("V", "")}.schema.json' - ) - with open(schema_fn) as schema_fd: - schema_doc = json.load(schema_fd) - - try: - json_validate(instance=json.loads(bom_json), schema=schema_doc) - except ValidationError as e: - self.assertTrue(False, f'Failed to validate SBOM against JSON schema: {str(e)}') - - self.assertTrue(True) - else: - self.assertTrue(True, 'JSON Schema Validation is not possible in Python < 3.7') - - @staticmethod - def _sort_json_dict(item: object) -> Any: - if isinstance(item, dict): - return sorted((key, BaseJsonTestCase._sort_json_dict(values)) for key, values in item.items()) - if isinstance(item, list): - return sorted(BaseJsonTestCase._sort_json_dict(x) for x in item) - else: - return item - - def assertEqualJson(self, a: str, b: str) -> None: - self.assertEqual( - BaseJsonTestCase._sort_json_dict(json.loads(a)), - BaseJsonTestCase._sort_json_dict(json.loads(b)) - ) - - def assertEqualJsonBom(self, a: str, b: str) -> None: - """ - Remove UUID before comparison as this will be unique to each generation - """ - ab = json.loads(a) - bb = json.loads(b) - - # Null serialNumbers - ab['serialNumber'] = single_uuid - bb['serialNumber'] = single_uuid - - # Unify timestamps to ensure they will compare - now = datetime.now(tz=timezone.utc) - if 'metadata' in ab.keys(): - ab['metadata']['timestamp'] = now.isoformat() - if 'metadata' in bb.keys(): - bb['metadata']['timestamp'] = now.isoformat() - - self.assertEqualJson(json.dumps(ab), json.dumps(bb)) - - -class BaseXmlTestCase(TestCase): - - def assertValidAgainstSchema(self, bom_xml: str, schema_version: SchemaVersion) -> None: - xsd_fn = os.path.join(CDX_SCHEMA_DIRECTORY, f'bom-{schema_version.name.replace("_", ".").replace("V", "")}.xsd') - with open(xsd_fn) as xsd_fd: - xsd_doc = etree.parse(xsd_fd) - - xml_schema = etree.XMLSchema(xsd_doc) - schema_validates = False - try: - schema_validates = xml_schema.validate(etree.parse(io.BytesIO(bytes(bom_xml, 'ascii')))) - except DocumentInvalid as e: - print(f'Failed to validate SBOM against schema: {str(e)}') - - if not schema_validates: - print(xml_schema.error_log.last_error) - self.assertTrue(schema_validates, f'Failed to validate Generated SBOM against XSD Schema:' - f'{bom_xml}') - - def assertEqualXml(self, a: str, b: str) -> None: - diff_results = main.diff_texts(a, b, diff_options={'F': 0.5}) - diff_results = list(filter(lambda o: not isinstance(o, MoveNode), diff_results)) - self.assertEqual(len(diff_results), 0, f'There are XML differences: {diff_results}\n- {a}\n+ {b}') - - def assertEqualXmlBom(self, a: str, b: str, namespace: str) -> None: - """ - Sanitise some fields such as timestamps which cannot have their values directly compared for equality. - """ - ba = xml.etree.ElementTree.fromstring(a, etree.XMLParser(remove_blank_text=True, remove_comments=True)) - bb = xml.etree.ElementTree.fromstring(b, etree.XMLParser(remove_blank_text=True, remove_comments=True)) - - # Align serialNumbers - ba.set('serialNumber', single_uuid) - bb.set('serialNumber', single_uuid) - - # Align timestamps in metadata - now = datetime.now(tz=timezone.utc) - metadata_ts_a = ba.find('./{{{}}}metadata/{{{}}}timestamp'.format(namespace, namespace)) - if metadata_ts_a is not None: - metadata_ts_a.text = now.isoformat() - metadata_ts_b = bb.find('./{{{}}}metadata/{{{}}}timestamp'.format(namespace, namespace)) - if metadata_ts_b is not None: - metadata_ts_b.text = now.isoformat() - - self.assertEqualXml( - xml.etree.ElementTree.tostring(ba, 'unicode'), - xml.etree.ElementTree.tostring(bb, 'unicode') - ) diff --git a/tests/fixtures/xml/1.0/bom_issue_275_components.xml b/tests/fixtures/xml/1.0/bom_issue_275_components.xml deleted file mode 100644 index c7c26afb..00000000 --- a/tests/fixtures/xml/1.0/bom_issue_275_components.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - comp_a - 1.0.0 - false - - - comp_b - 1.0.0 - false - - - comp_c - 1.0.0 - false - - - - - diff --git a/tests/fixtures/xml/1.0/bom_issue_328_components.xml b/tests/fixtures/xml/1.0/bom_issue_328_components.xml deleted file mode 100644 index 3d2dc7ab..00000000 --- a/tests/fixtures/xml/1.0/bom_issue_328_components.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - A - 0.1 - false - - - B - 1.0 - false - - - C - 1.0 - false - - - - - - - diff --git a/tests/fixtures/xml/1.0/bom_setuptools.xml b/tests/fixtures/xml/1.0/bom_setuptools.xml deleted file mode 100644 index a8823214..00000000 --- a/tests/fixtures/xml/1.0/bom_setuptools.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - setuptools - 50.3.2 - pkg:pypi/setuptools@50.3.2?extension=tar.gz - false - - - diff --git a/tests/fixtures/xml/1.0/bom_setuptools_complete.xml b/tests/fixtures/xml/1.0/bom_setuptools_complete.xml deleted file mode 100644 index 796fce00..00000000 --- a/tests/fixtures/xml/1.0/bom_setuptools_complete.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - false - - - setuptools - 50.3.2 - pkg:pypi/setuptools@50.3.2?extension=tar.gz - false - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - false - - - - - diff --git a/tests/fixtures/xml/1.0/bom_setuptools_no_version.xml b/tests/fixtures/xml/1.0/bom_setuptools_no_version.xml deleted file mode 100644 index 2871e097..00000000 --- a/tests/fixtures/xml/1.0/bom_setuptools_no_version.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - setuptools - - pkg:pypi/setuptools?extension=tar.gz - false - - - diff --git a/tests/fixtures/xml/1.0/bom_setuptools_with_cpe.xml b/tests/fixtures/xml/1.0/bom_setuptools_with_cpe.xml deleted file mode 100644 index 0b7982ae..00000000 --- a/tests/fixtures/xml/1.0/bom_setuptools_with_cpe.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - setuptools - 50.3.2 - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - false - - - diff --git a/tests/fixtures/xml/1.0/bom_toml_hashes_and_references.xml b/tests/fixtures/xml/1.0/bom_toml_hashes_and_references.xml deleted file mode 100644 index 04b1faa6..00000000 --- a/tests/fixtures/xml/1.0/bom_toml_hashes_and_references.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - false - - - diff --git a/tests/fixtures/xml/1.1/bom_dependencies.xml b/tests/fixtures/xml/1.1/bom_dependencies.xml deleted file mode 100644 index 44cb1a8d..00000000 --- a/tests/fixtures/xml/1.1/bom_dependencies.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - diff --git a/tests/fixtures/xml/1.1/bom_empty.xml b/tests/fixtures/xml/1.1/bom_empty.xml deleted file mode 100644 index 07db9157..00000000 --- a/tests/fixtures/xml/1.1/bom_empty.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/tests/fixtures/xml/1.1/bom_external_references.xml b/tests/fixtures/xml/1.1/bom_external_references.xml deleted file mode 100644 index 1100a3e8..00000000 --- a/tests/fixtures/xml/1.1/bom_external_references.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - https://cyclonedx.org - No comment - - - https://cyclonedx.org - - - diff --git a/tests/fixtures/xml/1.1/bom_issue_275_components.xml b/tests/fixtures/xml/1.1/bom_issue_275_components.xml deleted file mode 100644 index 19b2b357..00000000 --- a/tests/fixtures/xml/1.1/bom_issue_275_components.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - comp_a - 1.0.0 - - - comp_b - 1.0.0 - - - comp_c - 1.0.0 - - - - - diff --git a/tests/fixtures/xml/1.1/bom_issue_328_components.xml b/tests/fixtures/xml/1.1/bom_issue_328_components.xml deleted file mode 100644 index b72c3bcc..00000000 --- a/tests/fixtures/xml/1.1/bom_issue_328_components.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - A - 0.1 - - - B - 1.0 - - - C - 1.0 - - - - - - - diff --git a/tests/fixtures/xml/1.1/bom_setuptools.xml b/tests/fixtures/xml/1.1/bom_setuptools.xml deleted file mode 100644 index 74c050f1..00000000 --- a/tests/fixtures/xml/1.1/bom_setuptools.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - diff --git a/tests/fixtures/xml/1.1/bom_setuptools_complete.xml b/tests/fixtures/xml/1.1/bom_setuptools_complete.xml deleted file mode 100644 index b18d1d36..00000000 --- a/tests/fixtures/xml/1.1/bom_setuptools_complete.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - a-random-uid - A commit message - - - Some notes here please - - - - https://cyclonedx.org - No comment - - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - diff --git a/tests/fixtures/xml/1.1/bom_setuptools_no_version.xml b/tests/fixtures/xml/1.1/bom_setuptools_no_version.xml deleted file mode 100644 index 2a24f4bc..00000000 --- a/tests/fixtures/xml/1.1/bom_setuptools_no_version.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - diff --git a/tests/fixtures/xml/1.1/bom_setuptools_with_cpe.xml b/tests/fixtures/xml/1.1/bom_setuptools_with_cpe.xml deleted file mode 100644 index b8e9cf15..00000000 --- a/tests/fixtures/xml/1.1/bom_setuptools_with_cpe.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - setuptools - 50.3.2 - - MIT License - - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - diff --git a/tests/fixtures/xml/1.1/bom_setuptools_with_vulnerabilities.xml b/tests/fixtures/xml/1.1/bom_setuptools_with_vulnerabilities.xml deleted file mode 100644 index 555d4186..00000000 --- a/tests/fixtures/xml/1.1/bom_setuptools_with_vulnerabilities.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - CVE-2018-7489 - - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - 9.8 - - Critical - CVSSv3 - AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - - - - 2.7 - - Low - CVSSv3 - AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N - - - - 22 - 33 - - A description here - - Upgrade - - - http://www.securitytracker.com/id/1040693 - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - - diff --git a/tests/fixtures/xml/1.1/bom_toml_hashes_and_references.xml b/tests/fixtures/xml/1.1/bom_toml_hashes_and_references.xml deleted file mode 100644 index 4020f6fe..00000000 --- a/tests/fixtures/xml/1.1/bom_toml_hashes_and_references.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - diff --git a/tests/fixtures/xml/1.2/bom_dependencies.xml b/tests/fixtures/xml/1.2/bom_dependencies.xml deleted file mode 100644 index a3a52dc7..00000000 --- a/tests/fixtures/xml/1.2/bom_dependencies.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_dependencies_component.xml b/tests/fixtures/xml/1.2/bom_dependencies_component.xml deleted file mode 100644 index b301d92c..00000000 --- a/tests/fixtures/xml/1.2/bom_dependencies_component.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_external_references.xml b/tests/fixtures/xml/1.2/bom_external_references.xml deleted file mode 100644 index 3187c7a9..00000000 --- a/tests/fixtures/xml/1.2/bom_external_references.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - https://cyclonedx.org - No comment - - - https://cyclonedx.org - - - diff --git a/tests/fixtures/xml/1.2/bom_issue_275_components.xml b/tests/fixtures/xml/1.2/bom_issue_275_components.xml deleted file mode 100644 index 2c0584bc..00000000 --- a/tests/fixtures/xml/1.2/bom_issue_275_components.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - app - 1.0.0 - - - - - comp_a - 1.0.0 - - - comp_b - 1.0.0 - - - comp_c - 1.0.0 - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_issue_328_components.xml b/tests/fixtures/xml/1.2/bom_issue_328_components.xml deleted file mode 100644 index b5093aae..00000000 --- a/tests/fixtures/xml/1.2/bom_issue_328_components.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - 2023-01-07T13:52:31.865875+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - my-project - 1 - - - - - A - 0.1 - - - B - 1.0 - - - C - 1.0 - - - - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_services_complex.xml b/tests/fixtures/xml/1.2/bom_services_complex.xml deleted file mode 100644 index fb379dd2..00000000 --- a/tests/fixtures/xml/1.2/bom_services_complex.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_services_nested.xml b/tests/fixtures/xml/1.2/bom_services_nested.xml deleted file mode 100644 index b3fce989..00000000 --- a/tests/fixtures/xml/1.2/bom_services_nested.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - no-group - second-nested-service - 3.2.1 - true - false - - - first-nested-service - - - - - my-second-service - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - what-group - yet-another-nested-service - 6.5.4 - - - another-nested-service - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_services_simple.xml b/tests/fixtures/xml/1.2/bom_services_simple.xml deleted file mode 100644 index 7595971a..00000000 --- a/tests/fixtures/xml/1.2/bom_services_simple.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - my-first-service - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_setuptools.xml b/tests/fixtures/xml/1.2/bom_setuptools.xml deleted file mode 100644 index ffdfcc42..00000000 --- a/tests/fixtures/xml/1.2/bom_setuptools.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_setuptools_complete.xml b/tests/fixtures/xml/1.2/bom_setuptools_complete.xml deleted file mode 100644 index 4a16c92c..00000000 --- a/tests/fixtures/xml/1.2/bom_setuptools_complete.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_setuptools_no_version.xml b/tests/fixtures/xml/1.2/bom_setuptools_no_version.xml deleted file mode 100644 index c80352ac..00000000 --- a/tests/fixtures/xml/1.2/bom_setuptools_no_version.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_setuptools_with_cpe.xml b/tests/fixtures/xml/1.2/bom_setuptools_with_cpe.xml deleted file mode 100644 index f143d86e..00000000 --- a/tests/fixtures/xml/1.2/bom_setuptools_with_cpe.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_setuptools_with_vulnerabilities.xml b/tests/fixtures/xml/1.2/bom_setuptools_with_vulnerabilities.xml deleted file mode 100644 index 39e4c53c..00000000 --- a/tests/fixtures/xml/1.2/bom_setuptools_with_vulnerabilities.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - 2023-01-07T13:44:32.626402+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - CVE-2018-7489 - - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - 9.8 - - Critical - CVSSv3 - AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - - - - 2.7 - - Low - CVSSv3 - AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N - - - - 22 - 33 - - A description here - - Upgrade - - - http://www.securitytracker.com/id/1040693 - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_toml_hashes_and_references.xml b/tests/fixtures/xml/1.2/bom_toml_hashes_and_references.xml deleted file mode 100644 index 30cf691b..00000000 --- a/tests/fixtures/xml/1.2/bom_toml_hashes_and_references.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - - diff --git a/tests/fixtures/xml/1.2/bom_with_full_metadata.xml b/tests/fixtures/xml/1.2/bom_with_full_metadata.xml deleted file mode 100644 index 056af173..00000000 --- a/tests/fixtures/xml/1.2/bom_with_full_metadata.xml +++ /dev/null @@ -1,193 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - Cyclone DX - https://cyclonedx.org/ - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_dependencies.xml b/tests/fixtures/xml/1.3/bom_dependencies.xml deleted file mode 100644 index 3685ff84..00000000 --- a/tests/fixtures/xml/1.3/bom_dependencies.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_dependencies_component.xml b/tests/fixtures/xml/1.3/bom_dependencies_component.xml deleted file mode 100644 index bbe61960..00000000 --- a/tests/fixtures/xml/1.3/bom_dependencies_component.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_external_references.xml b/tests/fixtures/xml/1.3/bom_external_references.xml deleted file mode 100644 index 443d36cc..00000000 --- a/tests/fixtures/xml/1.3/bom_external_references.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - https://cyclonedx.org - - - diff --git a/tests/fixtures/xml/1.3/bom_issue_275_components.xml b/tests/fixtures/xml/1.3/bom_issue_275_components.xml deleted file mode 100644 index d41ae90b..00000000 --- a/tests/fixtures/xml/1.3/bom_issue_275_components.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - app - 1.0.0 - - - - - comp_a - 1.0.0 - - - comp_b - 1.0.0 - - - comp_c - 1.0.0 - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_issue_328_components.xml b/tests/fixtures/xml/1.3/bom_issue_328_components.xml deleted file mode 100644 index ad5e6258..00000000 --- a/tests/fixtures/xml/1.3/bom_issue_328_components.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - 2023-01-07T13:52:32.198166+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - my-project - 1 - - - - - A - 0.1 - - - B - 1.0 - - - C - 1.0 - - - - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_services_complex.xml b/tests/fixtures/xml/1.3/bom_services_complex.xml deleted file mode 100644 index f62058f0..00000000 --- a/tests/fixtures/xml/1.3/bom_services_complex.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_services_nested.xml b/tests/fixtures/xml/1.3/bom_services_nested.xml deleted file mode 100644 index ccb0684d..00000000 --- a/tests/fixtures/xml/1.3/bom_services_nested.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - no-group - second-nested-service - 3.2.1 - true - false - - - first-nested-service - - - - - my-second-service - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - what-group - yet-another-nested-service - 6.5.4 - - - another-nested-service - - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_services_simple.xml b/tests/fixtures/xml/1.3/bom_services_simple.xml deleted file mode 100644 index 7eaaaa6a..00000000 --- a/tests/fixtures/xml/1.3/bom_services_simple.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - cyclonedx-python-lib - 1.0.0 - - - - - my-first-service - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_setuptools.xml b/tests/fixtures/xml/1.3/bom_setuptools.xml deleted file mode 100644 index dbe2a157..00000000 --- a/tests/fixtures/xml/1.3/bom_setuptools.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_setuptools_complete.xml b/tests/fixtures/xml/1.3/bom_setuptools_complete.xml deleted file mode 100644 index f9ac65f0..00000000 --- a/tests/fixtures/xml/1.3/bom_setuptools_complete.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Commercial - Commercial 2 - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_setuptools_no_version.xml b/tests/fixtures/xml/1.3/bom_setuptools_no_version.xml deleted file mode 100644 index 9fe15036..00000000 --- a/tests/fixtures/xml/1.3/bom_setuptools_no_version.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_setuptools_with_cpe.xml b/tests/fixtures/xml/1.3/bom_setuptools_with_cpe.xml deleted file mode 100644 index 27abd9b2..00000000 --- a/tests/fixtures/xml/1.3/bom_setuptools_with_cpe.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_setuptools_with_vulnerabilities.xml b/tests/fixtures/xml/1.3/bom_setuptools_with_vulnerabilities.xml deleted file mode 100644 index 6cce456e..00000000 --- a/tests/fixtures/xml/1.3/bom_setuptools_with_vulnerabilities.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - 2023-01-07T13:44:32.964601+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - CVE-2018-7489 - - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - 9.8 - - Critical - CVSSv3 - AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - - - - 2.7 - - Low - CVSSv3 - AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N - - - - 22 - 33 - - A description here - - Upgrade - - - http://www.securitytracker.com/id/1040693 - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_toml_hashes_and_references.xml b/tests/fixtures/xml/1.3/bom_toml_hashes_and_references.xml deleted file mode 100644 index 3e3c02bc..00000000 --- a/tests/fixtures/xml/1.3/bom_toml_hashes_and_references.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - diff --git a/tests/fixtures/xml/1.3/bom_with_full_metadata.xml b/tests/fixtures/xml/1.3/bom_with_full_metadata.xml deleted file mode 100644 index 434dd66c..00000000 --- a/tests/fixtures/xml/1.3/bom_with_full_metadata.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Commercial - Commercial 2 - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - Cyclone DX - https://cyclonedx.org/ - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - - - Apache-2.0 - VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE= - https://www.apache.org/licenses/LICENSE-2.0.txt - - - - val1 - val2 - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_dependencies.xml b/tests/fixtures/xml/1.4/bom_dependencies.xml deleted file mode 100644 index ecdb150c..00000000 --- a/tests/fixtures/xml/1.4/bom_dependencies.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_dependencies_component.xml b/tests/fixtures/xml/1.4/bom_dependencies_component.xml deleted file mode 100644 index 0aadc91a..00000000 --- a/tests/fixtures/xml/1.4/bom_dependencies_component.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_external_references.xml b/tests/fixtures/xml/1.4/bom_external_references.xml deleted file mode 100644 index 146497d3..00000000 --- a/tests/fixtures/xml/1.4/bom_external_references.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - https://cyclonedx.org - - - diff --git a/tests/fixtures/xml/1.4/bom_issue_275_components.xml b/tests/fixtures/xml/1.4/bom_issue_275_components.xml deleted file mode 100644 index 7d6924a8..00000000 --- a/tests/fixtures/xml/1.4/bom_issue_275_components.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - app - 1.0.0 - - - - - comp_a - 1.0.0 - - - comp_b - 1.0.0 - - - comp_c - 1.0.0 - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_issue_328_components.xml b/tests/fixtures/xml/1.4/bom_issue_328_components.xml deleted file mode 100644 index 004ce30d..00000000 --- a/tests/fixtures/xml/1.4/bom_issue_328_components.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - my-project - 1 - - - - - A - 0.1 - - - B - 1.0 - - - C - 1.0 - - - - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_services_complex.xml b/tests/fixtures/xml/1.4/bom_services_complex.xml deleted file mode 100644 index 03d2c460..00000000 --- a/tests/fixtures/xml/1.4/bom_services_complex.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - major - Release Notes Title - https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png - https://cyclonedx.org/cyclonedx-icon.png - This release is a test release - 2021-12-31T10:00:00+00:00 - - First Test Release - - - alpha - test - - - - CVE-2021-44228 - Apache Log3Shell - Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2021-44228 - - - https://central.sonatype.org/news/20211213_log4shell_help - https://logging.apache.org/log4j/2.x/security.html - - - - - - en-GB - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - en-US - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - - val1 - val2 - - - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_services_nested.xml b/tests/fixtures/xml/1.4/bom_services_nested.xml deleted file mode 100644 index a0cc89ec..00000000 --- a/tests/fixtures/xml/1.4/bom_services_nested.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - cyclonedx-python-lib - 1.0.0 - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - a-group - my-first-service - 1.2.3 - Description goes here - - /api/thing/1 - /api/thing/2 - - false - true - - public - - - Commercial - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - no-group - second-nested-service - 3.2.1 - true - false - - - first-nested-service - - - - major - Release Notes Title - https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png - https://cyclonedx.org/cyclonedx-icon.png - This release is a test release - 2021-12-31T10:00:00+00:00 - - First Test Release - - - alpha - test - - - - CVE-2021-44228 - Apache Log3Shell - Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2021-44228 - - - https://central.sonatype.org/news/20211213_log4shell_help - https://logging.apache.org/log4j/2.x/security.html - - - - - - en-GB - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - en-US - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - - val1 - val2 - - - - - my-second-service - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - what-group - yet-another-nested-service - 6.5.4 - - - another-nested-service - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_services_simple.xml b/tests/fixtures/xml/1.4/bom_services_simple.xml deleted file mode 100644 index a8c80c9e..00000000 --- a/tests/fixtures/xml/1.4/bom_services_simple.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - cyclonedx-python-lib - 1.0.0 - - - - - my-first-service - - - my-second-service - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_setuptools_complete.xml b/tests/fixtures/xml/1.4/bom_setuptools_complete.xml deleted file mode 100644 index 61ba8689..00000000 --- a/tests/fixtures/xml/1.4/bom_setuptools_complete.xml +++ /dev/null @@ -1,252 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Commercial - Commercial 2 - - - - major - Release Notes Title - https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png - https://cyclonedx.org/cyclonedx-icon.png - This release is a test release - 2021-12-31T10:00:00+00:00 - - First Test Release - - - alpha - test - - - - CVE-2021-44228 - Apache Log3Shell - Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2021-44228 - - - https://central.sonatype.org/news/20211213_log4shell_help - https://logging.apache.org/log4j/2.x/security.html - - - - - - en-GB - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - en-US - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - - val1 - val2 - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_setuptools_no_version.xml b/tests/fixtures/xml/1.4/bom_setuptools_no_version.xml deleted file mode 100644 index 73becdb0..00000000 --- a/tests/fixtures/xml/1.4/bom_setuptools_no_version.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - Test Author - setuptools - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_setuptools_with_cpe.xml b/tests/fixtures/xml/1.4/bom_setuptools_with_cpe.xml deleted file mode 100644 index db986987..00000000 --- a/tests/fixtures/xml/1.4/bom_setuptools_with_cpe.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_setuptools_with_release_notes.xml b/tests/fixtures/xml/1.4/bom_setuptools_with_release_notes.xml deleted file mode 100644 index 5467da42..00000000 --- a/tests/fixtures/xml/1.4/bom_setuptools_with_release_notes.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - major - Release Notes Title - https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png - https://cyclonedx.org/cyclonedx-icon.png - This release is a test release - 2021-12-31T10:00:00+00:00 - - First Test Release - - - alpha - test - - - - CVE-2021-44228 - Apache Log3Shell - Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2021-44228 - - - https://central.sonatype.org/news/20211213_log4shell_help - https://logging.apache.org/log4j/2.x/security.html - - - - - - en-GB - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - en-US - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - - val1 - val2 - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_setuptools_with_vulnerabilities.xml b/tests/fixtures/xml/1.4/bom_setuptools_with_vulnerabilities.xml deleted file mode 100644 index 1936e286..00000000 --- a/tests/fixtures/xml/1.4/bom_setuptools_with_vulnerabilities.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - - - - - - CVE-2018-7489 - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - - SOME-OTHER-ID - - OSS Index - https://ossindex.sonatype.org/component/pkg:pypi/setuptools - - - - - - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - 9.8 - critical - CVSSv3 - AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Some justification - - - - OWASP - https://owasp.org - - 2.7 - low - CVSSv3 - AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N - Some other justification - - - - 22 - 33 - - A description here - Some detail here - Upgrade - - - http://www.securitytracker.com/id/1040693 - - - https://nvd.nist.gov/vuln/detail/CVE-2018-7489 - - - 2021-09-01T10:50:42.051979+00:00 - 2021-09-02T10:50:42.051979+00:00 - 2021-09-03T10:50:42.051979+00:00 - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - - - - CycloneDX - cyclonedx-python-lib - - - - exploitable - requires_environment - - can_not_fix - - Some extra detail - - - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - 49.0.0 - 54.0.0 - affected - - - - - - val1 - val2 - - - - diff --git a/tests/fixtures/xml/1.4/bom_toml_hashes_and_references.xml b/tests/fixtures/xml/1.4/bom_toml_hashes_and_references.xml deleted file mode 100644 index 3ead1df9..00000000 --- a/tests/fixtures/xml/1.4/bom_toml_hashes_and_references.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_with_dependencies_hanging.xml b/tests/fixtures/xml/1.4/bom_with_dependencies_hanging.xml deleted file mode 100644 index 29395f60..00000000 --- a/tests/fixtures/xml/1.4/bom_with_dependencies_hanging.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - 2023-06-01T03:03:07+00:00 - - rootComponent - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - - - - - - - diff --git a/tests/fixtures/xml/1.4/bom_with_full_metadata.xml b/tests/fixtures/xml/1.4/bom_with_full_metadata.xml deleted file mode 100644 index 24ee7aa0..00000000 --- a/tests/fixtures/xml/1.4/bom_with_full_metadata.xml +++ /dev/null @@ -1,294 +0,0 @@ - - - - 2023-01-07T13:44:32.312678+00:00 - - - CycloneDX - cyclonedx-python-lib - TESTING - - - https://github.com/CycloneDX/cyclonedx-python-lib/actions - - - https://pypi.org/project/cyclonedx-python-lib/ - - - https://cyclonedx.github.io/cyclonedx-python-lib/ - - - https://github.com/CycloneDX/cyclonedx-python-lib/issues - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE - - - https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md - - - https://github.com/CycloneDX/cyclonedx-python-lib - - - https://cyclonedx.org - - - - - - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - Test Author - CycloneDX - setuptools - 50.3.2 - This component is awesome - required - - MIT License - - Apache 2.0 baby! - cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - Test Author - setuptools - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - - - Test Author - setuptools - - MIT License - - pkg:pypi/setuptools?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - a-random-uid - A commit message - - - - - - Some notes here please - - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - val1 - val2 - - - - Test Author - setuptools - 50.3.2 - - MIT License - - pkg:pypi/setuptools@50.3.2?extension=tar.gz - - - toml - 0.10.2 - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - pkg:pypi/toml@0.10.2?extension=tar.gz - - - https://cyclonedx.org - No comment - - 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - - - - - - - - Commercial - Commercial 2 - - - - major - Release Notes Title - https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png - https://cyclonedx.org/cyclonedx-icon.png - This release is a test release - 2021-12-31T10:00:00+00:00 - - First Test Release - - - alpha - test - - - - CVE-2021-44228 - Apache Log3Shell - Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2021-44228 - - - https://central.sonatype.org/news/20211213_log4shell_help - https://logging.apache.org/log4j/2.x/security.html - - - - - - en-GB - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - en-US - U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== - - - - val1 - val2 - - - - - CycloneDX - https://cyclonedx.org - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - Paul Horton - paul.horton@owasp.org - - - - Cyclone DX - https://cyclonedx.org/ - - A N Other - someone@somewhere.tld - +44 (0)1234 567890 - - - - - Apache-2.0 - VGVzdCBjb250ZW50IC0gdGhpcyBpcyBub3QgdGhlIEFwYWNoZSAyLjAgbGljZW5zZSE= - https://www.apache.org/licenses/LICENSE-2.0.txt - - - - val1 - val2 - - - - - - diff --git a/tests/test_component.py b/tests/test_component.py index d1cf3dfc..e20be7ae 100644 --- a/tests/test_component.py +++ b/tests/test_component.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +15,7 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from os.path import dirname, join +from os.path import join from unittest import TestCase # See https://github.com/package-url/packageurl-python/issues/65 @@ -25,10 +23,8 @@ from cyclonedx.model import sha1sum from cyclonedx.model.component import Component - -from .data import get_component_setuptools_simple - -FIXTURES_DIRECTORY = join('fixtures', 'xml', '1.4') +from tests import OWN_DATA_DIRECTORY +from tests._data.models import get_component_setuptools_simple class TestComponent(TestCase): @@ -66,11 +62,11 @@ def test_purl_incorrect_name(self) -> None: self.assertEqual(purl.version, '50.3.2') self.assertEqual(purl.qualifiers, {'extension': 'tar.gz'}) - def test_from_file_with_path_for_bom(self) -> None: - test_file = join(dirname(__file__), FIXTURES_DIRECTORY, 'bom_setuptools.xml') + def test_from_xml_file_with_path_for_bom(self) -> None: + test_file = join(OWN_DATA_DIRECTORY, 'xml', '1.4', 'bom_setuptools.xml') c = Component.for_file(absolute_file_path=test_file, path_for_bom='fixtures/bom_setuptools.xml') sha1_hash: str = sha1sum(filename=test_file) - expected_version = '0.0.0-{}'.format(sha1_hash[0:12]) + expected_version = f'0.0.0-{sha1_hash[0:12]}' self.assertEqual(c.name, 'fixtures/bom_setuptools.xml') self.assertEqual(c.version, expected_version) purl = PackageURL( diff --git a/tests/test_deserialize_json.py b/tests/test_deserialize_json.py index 8962ee51..c3b670d0 100644 --- a/tests/test_deserialize_json.py +++ b/tests/test_deserialize_json.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,416 +15,60 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -import json -from datetime import datetime -from os.path import dirname, join -from typing import cast -from unittest.mock import Mock, patch -from uuid import UUID - -from cyclonedx.model.bom import Bom -from cyclonedx.output import LATEST_SUPPORTED_SCHEMA_VERSION, OutputFormat, SchemaVersion, get_instance -from tests.base import BaseJsonTestCase -from tests.data import ( - MOCK_BOM_UUID_1, - MOCK_BOM_UUID_2, - MOCK_UUID_1, - MOCK_UUID_2, - MOCK_UUID_3, - MOCK_UUID_4, - MOCK_UUID_5, - MOCK_UUID_6, - MOCK_UUID_7, - MOCK_UUID_8, - TEST_UUIDS, - get_bom_just_complete_metadata, - get_bom_with_component_setuptools_basic, - get_bom_with_component_setuptools_complete, - get_bom_with_component_setuptools_no_component_version, - get_bom_with_component_setuptools_with_cpe, - get_bom_with_component_setuptools_with_release_notes, - get_bom_with_component_setuptools_with_vulnerability, - get_bom_with_component_toml_1, - get_bom_with_dependencies_valid, - get_bom_with_external_references, - get_bom_with_nested_services, - get_bom_with_services_complex, - get_bom_with_services_simple, -) - - -def fixed_date_time() -> datetime: - return datetime.fromisoformat('2023-01-07 13:44:32.312678+00:00') - - -@patch('cyclonedx.model.ThisTool._version', 'TESTING') -@patch('cyclonedx.model.bom.get_now_utc', fixed_date_time) -class TestOutputJson(BaseJsonTestCase): - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_4(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_4, - fixture='bom_external_references.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_3(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_3, - fixture='bom_external_references.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_2(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_2, - fixture='bom_external_references.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_4(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_3(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_2(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_4_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_cpe.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_3_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_with_cpe.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_2_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_with_cpe.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_4_full_component(self, mock1: Mock, mock2: Mock) -> None: - self.maxDiff = None - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_complete.json' - ) - mock1.assert_called() - mock2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_3_full_component(self, mock1: Mock, mock2: Mock) -> None: - self.maxDiff = None - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_complete.json' - ) - mock1.assert_called() - mock2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_2_full_component(self, mock1: Mock, mock2: Mock) -> None: - self.maxDiff = None - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_complete.json' - ) - mock1.assert_called() - mock2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_7) - def test_bom_v1_4_component_hashes_external_references(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_4, - fixture='bom_toml_1.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_7) - def test_bom_v1_3_component_hashes_external_references(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_3, - fixture='bom_toml_1.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_7) - def test_bom_v1_2_component_hashes_external_references(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_2, - fixture='bom_toml_1.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_8) - def test_bom_v1_4_no_component_version(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_no_version.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_8) - def test_bom_v1_3_no_component_version(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_no_version.json' - ) - mock_1.assert_called() - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_UUID_8) - def test_bom_v1_2_no_component_version(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_no_version.json' - ) - mock_1.assert_called() +from json import loads as json_loads +from os.path import join +from typing import Any, Callable +from unittest import TestCase +from unittest.mock import patch - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_component_with_release_notes(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_release_notes.json' - ) - mock_1.assert_called() +from ddt import data, ddt, named_data - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_component_with_release_notes(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_component_with_vulnerability(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_vulnerabilities.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_component_with_vulnerability(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - mock_1.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_1)) - def test_bom_v1_4_with_metadata_component(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_full_metadata.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_2)) - def test_bom_v1_3_with_metadata_component(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3, - fixture='bom_with_full_metadata.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - def test_bom_v1_2_with_metadata_component(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2, - fixture='bom_with_full_metadata.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_2) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_dependencies(self, mock_1: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies.json' - ) - mock_1.assert_called() - # -- - - # Helper methods - def _validate_json_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None: - bom.metadata.timestamp = fixed_date_time() - bom.validate() - - if schema_version != LATEST_SUPPORTED_SCHEMA_VERSION: - # Rewind the BOM to only have data supported by the SchemaVersion in question - outputter = get_instance(bom=bom, output_format=OutputFormat.JSON, schema_version=schema_version) - bom = cast(Bom, Bom.from_json(data=json.loads(outputter.output_as_string()))) - - with open( - join(dirname(__file__), f'fixtures/json/{schema_version.to_version()}/{fixture}')) as input_json: - deserialized_bom = cast(Bom, Bom.from_json(data=json.loads(input_json.read()))) - - self.assertEqual(bom.metadata, deserialized_bom.metadata) - - # This comparison fails for Dependencies despite the SortedSet's being identical - # self.assertEqual(bom.dependencies, deserialized_bom.dependencies) - self.assertSetEqual(set(bom.dependencies), set(deserialized_bom.dependencies)) - - self.assertEqual(bom.vulnerabilities, deserialized_bom.vulnerabilities) - - self.assertEqual(bom, deserialized_bom) +from cyclonedx.model.bom import Bom +from cyclonedx.model.license import DisjunctiveLicense, LicenseExpression, LicenseRepository +from cyclonedx.schema import OutputFormat, SchemaVersion +from tests import OWN_DATA_DIRECTORY, DeepCompareMixin, SnapshotMixin, mksname, uuid_generator +from tests._data.models import all_get_bom_funct_valid, all_get_bom_funct_with_incomplete_deps + + +@ddt +class TestDeserializeJson(TestCase, SnapshotMixin, DeepCompareMixin): + + @named_data(*all_get_bom_funct_valid) + @patch('cyclonedx.model.ThisTool._version', 'TESTING') + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(0, version=4)) + def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: + # only latest schema will have all data populated in serialized form + snapshot_name = mksname(get_bom, SchemaVersion.V1_4, OutputFormat.JSON) + expected = get_bom() + json = json_loads(self.readSnapshot(snapshot_name)) + bom = Bom.from_json(json) + self.assertBomDeepEqual(expected, bom, + fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps) + + @data(SchemaVersion.V1_4, SchemaVersion.V1_3, SchemaVersion.V1_2) + def test_mixed_licenses_before15(self, sv: SchemaVersion) -> None: + # before CDX 1.5 it was allowed to mix `expression` and `license` + def test(ls: LicenseRepository) -> None: + self.assertEqual(3, len(ls)) + expression: LicenseExpression = next(( + li for li in ls if isinstance(li, LicenseExpression) + ), None) + with_id: DisjunctiveLicense = next(( + li for li in ls if isinstance(li, DisjunctiveLicense) and li.id is not None + ), None) + with_name: DisjunctiveLicense = next(( + li for li in ls if isinstance(li, DisjunctiveLicense) and li.name is not None + ), None) + self.assertEqual('MIT OR Apache-2.0', expression.value) + self.assertEqual('MIT', with_id.id) + self.assertEqual('foo license', with_name.name) + + json_file = join(OWN_DATA_DIRECTORY, 'json', sv.to_version(), 'bom_with_mixed_licenses.json') + with open(json_file) as f: + json = json_loads(f.read()) + bom: Bom = Bom.from_json(json) + test(bom.metadata.licenses) + test(bom.metadata.component.licenses) + test(list(bom.components)[0].licenses) + test(list(bom.services)[0].licenses) diff --git a/tests/test_deserialize_xml.py b/tests/test_deserialize_xml.py index 81b174f5..d4c5688a 100644 --- a/tests/test_deserialize_xml.py +++ b/tests/test_deserialize_xml.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,686 +15,30 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from datetime import datetime -from os.path import dirname, join -from typing import cast -from unittest.mock import Mock, patch -from uuid import UUID -from xml.etree import ElementTree - -from cyclonedx.model.bom import Bom -from cyclonedx.output import LATEST_SUPPORTED_SCHEMA_VERSION, SchemaVersion, get_instance -from cyclonedx.schema import OutputFormat -from tests.base import BaseXmlTestCase -from tests.data import ( - MOCK_BOM_UUID_1, - MOCK_UUID_2, - MOCK_UUID_3, - MOCK_UUID_4, - MOCK_UUID_5, - MOCK_UUID_6, - TEST_UUIDS, - get_bom_for_issue_275_components, - get_bom_just_complete_metadata, - get_bom_with_component_setuptools_basic, - get_bom_with_component_setuptools_complete, - get_bom_with_component_setuptools_no_component_version, - get_bom_with_component_setuptools_with_cpe, - get_bom_with_component_setuptools_with_release_notes, - get_bom_with_component_setuptools_with_vulnerability, - get_bom_with_component_toml_1, - get_bom_with_dependencies_valid, - get_bom_with_external_references, - get_bom_with_metadata_component_and_dependencies, - get_bom_with_nested_services, - get_bom_with_services_complex, - get_bom_with_services_simple, -) - - -def fixed_date_time() -> datetime: - return datetime.fromisoformat('2023-01-07 13:44:32.312678+00:00') - - -@patch('cyclonedx.model.ThisTool._version', 'TESTING') -@patch('cyclonedx.model.bom.get_now_utc', fixed_date_time) -class TestDeserializeXml(BaseXmlTestCase): - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_4(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_4, - fixture='bom_external_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_3(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_3, - fixture='bom_external_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_2(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_2, - fixture='bom_external_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_1(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_1, - fixture='bom_external_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_external_references_v1_0(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_4(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_3(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_2(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_1(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_0(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_4_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_cpe.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_3_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_with_cpe.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_2_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_with_cpe.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_1_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_with_cpe.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_simple_bom_v1_0_with_cpe(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_with_cpe.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_4_full_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_complete.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - def test_bom_v1_3_full_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_complete.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_2)) - def test_bom_v1_2_full_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_complete.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_1_full_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_complete.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_0_full_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_complete.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_component_hashes_external_references(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_4, - fixture='bom_toml_hashes_and_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_component_hashes_external_references(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_3, - fixture='bom_toml_hashes_and_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_component_hashes_external_references(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_2, - fixture='bom_toml_hashes_and_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_1_component_hashes_external_references(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_1, - fixture='bom_toml_hashes_and_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_0_component_hashes_external_references(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_0, - fixture='bom_toml_hashes_and_references.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_no_component_version(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_no_version.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_no_component_version(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_no_version.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_no_component_version(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_no_version.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_1_no_component_version(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_no_version.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_0_no_component_version(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_no_version.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_component_with_release_notes(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_release_notes.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_component_with_release_notes(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_component_with_vulnerability(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_vulnerabilities.xml' - ) - mock_uuid.assert_called() +from typing import Any, Callable +from unittest import TestCase +from unittest.mock import patch - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_component_with_vulnerability(self, mock_uuid: Mock) -> None: - with self.assertRaises(ValueError): - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_with_vulnerabilities.xml' - ) - mock_uuid.assert_called() +from ddt import ddt, named_data - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_component_with_vulnerability(self, mock_uuid: Mock) -> None: - with self.assertRaises(ValueError): - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_with_vulnerabilities.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_1_component_with_vulnerability(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_0_component_with_vulnerability(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_4_with_metadata_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_full_metadata.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - def test_bom_v1_3_with_metadata_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3, - fixture='bom_with_full_metadata.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_2_with_metadata_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2, - fixture='bom_with_full_metadata.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_1_with_metadata_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_0_with_metadata_component(self, mock_bom_uuid: Mock, mock_bom_ref_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - mock_bom_uuid.assert_called() - mock_bom_ref_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_1_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_0_services_simple(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_1_services_complex(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_nested(self, mock_1: Mock, mock_2: Mock, mock_3: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - mock_3.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_dependencies(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_dependencies(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_dependencies(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_1_dependencies(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_1, - fixture='bom_dependencies.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_dependencies_for_bom_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies_component.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_dependencies_for_bom_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies_component.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_dependencies_for_bom_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies_component.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_4_issue_275_components(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_4, - fixture='bom_issue_275_components.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_3_issue_275_components(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_3, - fixture='bom_issue_275_components.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_2_issue_275_components(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_2, - fixture='bom_issue_275_components.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_1_issue_275_components(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_1, - fixture='bom_issue_275_components.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=MOCK_BOM_UUID_1) - def test_bom_v1_0_issue_275_components(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_0, - fixture='bom_issue_275_components.xml' - ) - mock_uuid.assert_called() - - # Helper methods - def _validate_xml_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None: - bom.metadata.timestamp = fixed_date_time() - bom.validate() - - if schema_version != LATEST_SUPPORTED_SCHEMA_VERSION: - # Rewind the BOM to only have data supported by the SchemaVersion in question - outputter = get_instance(bom=bom, output_format=OutputFormat.XML, schema_version=schema_version) - bom = cast(Bom, Bom.from_xml(data=ElementTree.fromstring(outputter.output_as_string()))) - - with open(join(dirname(__file__), f'fixtures/xml/{schema_version.to_version()}/{fixture}')) as input_xml: - xml = input_xml.read() - deserialized_bom = cast(Bom, Bom.from_xml(data=ElementTree.fromstring(xml))) - - self.assertEqual(bom.metadata, deserialized_bom.metadata) - - # This comparison fails for Dependencies despite the SortedSet's being identical - # print(bom.dependencies.difference(deserialized_bom.dependencies)) - # self.assertEqual(bom.dependencies, deserialized_bom.dependencies) - # self.assertSetEqual(set(bom.dependencies), set(deserialized_bom.dependencies)) - - self.assertEqual(bom.vulnerabilities, deserialized_bom.vulnerabilities) - self.assertEqual(bom, deserialized_bom) +from cyclonedx.model.bom import Bom +from cyclonedx.schema import OutputFormat, SchemaVersion +from tests import DeepCompareMixin, SnapshotMixin, mksname, uuid_generator +from tests._data.models import all_get_bom_funct_valid, all_get_bom_funct_with_incomplete_deps + + +@ddt +class TestDeserializeXml(TestCase, SnapshotMixin, DeepCompareMixin): + + @named_data(*all_get_bom_funct_valid) + @patch('cyclonedx.model.ThisTool._version', 'TESTING') + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(0, version=4)) + def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None: + # only latest schema will have all data populated in serialized form + snapshot_name = mksname(get_bom, SchemaVersion.V1_4, OutputFormat.XML) + expected = get_bom() + with open(self.getSnapshotFile(snapshot_name), 'r') as s: + bom = Bom.from_xml(s) + self.assertBomDeepEqual(expected, bom, + fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps) diff --git a/tests/test_e2e_environment.py b/tests/test_e2e_environment.py deleted file mode 100644 index 165fc9d9..00000000 --- a/tests/test_e2e_environment.py +++ /dev/null @@ -1,82 +0,0 @@ -# encoding: utf-8 - -# This file is part of CycloneDX Python Lib -# -# 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. - -import json -from unittest import TestCase - -import pkg_resources -from lxml import etree -from packageurl import PackageURL - -from cyclonedx.model.bom import Bom -from cyclonedx.model.component import Component -from cyclonedx.output import OutputFormat, get_instance -from cyclonedx.output.json import Json -from cyclonedx.output.xml import Xml - -OUR_PACKAGE_NAME: str = 'cyclonedx-python-lib' -OUR_PACKAGE_VERSION: str = pkg_resources.get_distribution(OUR_PACKAGE_NAME).version -OUR_PACKAGE_AUTHOR: str = 'Paul Horton' - - -class TestE2EEnvironment(TestCase): - - @classmethod - def setUpClass(cls) -> None: - cls.bom: Bom = Bom() - cls.bom.components.add( - Component( - name=OUR_PACKAGE_NAME, author=OUR_PACKAGE_AUTHOR, version=OUR_PACKAGE_VERSION, - purl=PackageURL(type='pypi', name=OUR_PACKAGE_NAME, version=OUR_PACKAGE_VERSION) - ) - ) - - def test_json_defaults(self) -> None: - outputter: Json = get_instance(bom=TestE2EEnvironment.bom, output_format=OutputFormat.JSON) - bom_json = json.loads(outputter.output_as_string()) - self.assertTrue('metadata' in bom_json) - self.assertFalse('component' in bom_json['metadata']) - component_this_library = next( - (x for x in bom_json['components'] if - x['purl'] == 'pkg:pypi/{}@{}'.format(OUR_PACKAGE_NAME, OUR_PACKAGE_VERSION)), None - ) - - self.assertTrue('author' in component_this_library.keys(), 'author is missing from JSON BOM') - self.assertEqual(component_this_library['author'], OUR_PACKAGE_AUTHOR) - self.assertEqual(component_this_library['name'], OUR_PACKAGE_NAME) - self.assertEqual(component_this_library['version'], OUR_PACKAGE_VERSION) - - def test_xml_defaults(self) -> None: - outputter: Xml = get_instance(bom=TestE2EEnvironment.bom) - - # Check we have cyclonedx-python-lib with Author, Name and Version - bom_xml_e: etree.ElementTree = etree.fromstring(bytes(outputter.output_as_string(), encoding='utf-8')) - component_this_library: etree.Element = bom_xml_e.xpath( - '/cdx:bom/cdx:components/cdx:component', - namespaces={ - 'cdx': outputter.get_target_namespace() - } - )[0] - for a in component_this_library: - if a.tag == 'author': - self.assertEqual(a.text, OUR_PACKAGE_AUTHOR) - if a.tag == 'name': - self.assertEqual(a.text, OUR_PACKAGE_NAME) - if a.tag == 'version': - self.assertEqual(a.text, OUR_PACKAGE_VERSION) diff --git a/tests/test_factory_license.py b/tests/test_factory_license.py index 00798967..7d21a1d3 100644 --- a/tests/test_factory_license.py +++ b/tests/test_factory_license.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,8 +19,9 @@ import unittest.mock from cyclonedx.exception.factory import InvalidLicenseExpressionException, InvalidSpdxLicenseException -from cyclonedx.factory.license import LicenseChoiceFactory, LicenseFactory -from cyclonedx.model import AttachedText, License, LicenseChoice, XsUri +from cyclonedx.factory.license import LicenseFactory +from cyclonedx.model import AttachedText, XsUri +from cyclonedx.model.license import DisjunctiveLicense, LicenseExpression class TestFactoryLicense(unittest.TestCase): @@ -30,27 +29,38 @@ class TestFactoryLicense(unittest.TestCase): def test_make_from_string_with_id(self) -> None: text = unittest.mock.NonCallableMock(spec=AttachedText) url = unittest.mock.NonCallableMock(spec=XsUri) - expected = License(id='bar', text=text, url=url) + expected = DisjunctiveLicense(id='bar', text=text, url=url) - with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value='bar'): - actual = LicenseFactory().make_from_string(name_or_spdx='foo', license_text=text, license_url=url) + with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value='bar'), \ + unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=True): + actual = LicenseFactory().make_from_string('foo', license_text=text, license_url=url) self.assertEqual(expected, actual) def test_make_from_string_with_name(self) -> None: text = unittest.mock.NonCallableMock(spec=AttachedText) url = unittest.mock.NonCallableMock(spec=XsUri) - expected = License(name='foo', text=text, url=url) + expected = DisjunctiveLicense(name='foo', text=text, url=url) + + with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value=None), \ + unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=False): + actual = LicenseFactory().make_from_string('foo', license_text=text, license_url=url) + + self.assertEqual(expected, actual) + + def test_make_from_string_with_expression(self) -> None: + expected = LicenseExpression('foo') - with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value=None): - actual = LicenseFactory().make_from_string(name_or_spdx='foo', license_text=text, license_url=url) + with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value=None), \ + unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=True): + actual = LicenseFactory().make_from_string('foo') self.assertEqual(expected, actual) def test_make_with_id(self) -> None: text = unittest.mock.NonCallableMock(spec=AttachedText) url = unittest.mock.NonCallableMock(spec=XsUri) - expected = License(id='bar', text=text, url=url) + expected = DisjunctiveLicense(id='bar', text=text, url=url) with unittest.mock.patch('cyclonedx.factory.license.spdx_fixup', return_value='bar'): actual = LicenseFactory().make_with_id(spdx_id='foo', text=text, url=url) @@ -65,80 +75,17 @@ def test_make_with_id_raises(self) -> None: def test_make_with_name(self) -> None: text = unittest.mock.NonCallableMock(spec=AttachedText) url = unittest.mock.NonCallableMock(spec=XsUri) - expected = License(name='foo', text=text, url=url) + expected = DisjunctiveLicense(name='foo', text=text, url=url) actual = LicenseFactory().make_with_name(name='foo', text=text, url=url) self.assertEqual(expected, actual) - -class TestFactoryLicenseChoice(unittest.TestCase): - - def test_make_from_string_with_license_id(self) -> None: - license_ = unittest.mock.NonCallableMock(spec=License) - expected = LicenseChoice(license=license_) - license_factory = unittest.mock.MagicMock(spec=LicenseFactory) - license_factory.make_with_id.return_value = license_ - factory = LicenseChoiceFactory(license_factory=license_factory) - - actual = factory.make_from_string('foo') - - self.assertEqual(expected, actual) - self.assertIs(license_, actual.license) - license_factory.make_with_id.assert_called_once_with('foo') - - def test_make_from_string_with_compound_expression(self) -> None: - expected = LicenseChoice(expression='foo') - license_factory = unittest.mock.MagicMock(spec=LicenseFactory) - license_factory.make_with_id.side_effect = InvalidSpdxLicenseException('foo') - factory = LicenseChoiceFactory(license_factory=license_factory) - + def test_make_with_expression(self) -> None: + expected = LicenseExpression('foo') with unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=True): - actual = factory.make_from_string('foo') - + actual = LicenseFactory().make_with_expression(expression='foo') self.assertEqual(expected, actual) - license_factory.make_with_id.assert_called_once_with('foo') - - def test_make_from_string_with_license_name(self) -> None: - license_ = unittest.mock.NonCallableMock(spec=License) - expected = LicenseChoice(license=license_) - license_factory = unittest.mock.MagicMock(spec=LicenseFactory) - license_factory.make_with_id.side_effect = InvalidSpdxLicenseException('foo') - license_factory.make_with_name.return_value = license_ - factory = LicenseChoiceFactory(license_factory=license_factory) - with unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=False): - actual = factory.make_from_string('foo') - - self.assertEqual(expected, actual) - self.assertIs(license_, actual.license) - license_factory.make_with_id.assert_called_once_with('foo') - license_factory.make_with_name.assert_called_once_with('foo') - - def test_make_with_compound_expression(self) -> None: - expected = LicenseChoice(expression='foo') - factory = LicenseChoiceFactory(license_factory=unittest.mock.MagicMock(spec=LicenseFactory)) - - with unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=True): - actual = factory.make_with_compound_expression('foo') - - self.assertEqual(expected, actual) - - def test_make_with_compound_expression_raises(self) -> None: - factory = LicenseChoiceFactory(license_factory=unittest.mock.MagicMock(spec=LicenseFactory)) - with unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=False): - with self.assertRaises(InvalidLicenseExpressionException, msg='foo'): - factory.make_with_compound_expression('foo') - - def test_make_with_license(self) -> None: - text = unittest.mock.NonCallableMock(spec=AttachedText) - url = unittest.mock.NonCallableMock(spec=XsUri) - license_ = unittest.mock.NonCallableMock(spec=License) - expected = LicenseChoice(license=license_) - license_factory = unittest.mock.MagicMock(spec=LicenseFactory) - license_factory.make_from_string.return_value = license_ - factory = LicenseChoiceFactory(license_factory=license_factory) - - actual = factory.make_with_license('foo', license_text=text, license_url=url) - - self.assertEqual(expected, actual) - self.assertIs(license_, actual.license) - license_factory.make_from_string.assert_called_once_with('foo', license_text=text, license_url=url) + def test_make_with_expression_raises(self) -> None: + with self.assertRaises(InvalidLicenseExpressionException, msg='foo'): + with unittest.mock.patch('cyclonedx.factory.license.is_spdx_compound_expression', return_value=False): + LicenseFactory().make_with_expression('foo') diff --git a/tests/test_model.py b/tests/test_model.py index 1b0558e5..75096f2a 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,8 +35,6 @@ HashAlgorithm, HashType, IdentifiableAction, - License, - LicenseChoice, Note, NoteText, OrganizationalContact, @@ -47,8 +43,7 @@ XsUri, ) from cyclonedx.model.issue import IssueClassification, IssueType, IssueTypeSource - -from .data import reorder +from tests import reorder class DummyStringEnum(str, Enum): @@ -135,6 +130,14 @@ def test_compare_last_item_none(self) -> None: self.assertNotEqual(tuple1, tuple2) self.assertNotEqual(tuple2, tuple1) + def test_compare_last_item_missing(self) -> None: + tuple1 = ComparableTuple((1, 2, 3, 4, 5)) + tuple2 = ComparableTuple((1, 2, 3, 4)) + self.assertLess(tuple1, tuple2) + self.assertGreater(tuple2, tuple1) + self.assertNotEqual(tuple1, tuple2) + self.assertNotEqual(tuple2, tuple1) + def test_compare_enum(self) -> None: tuple1 = ComparableTuple((DummyStringEnum.FIRST, )) tuple2 = ComparableTuple((DummyStringEnum.SECOND, )) @@ -152,41 +155,6 @@ def test_compare_enum_then_none(self) -> None: self.assertNotEqual(tuple2, tuple1) -class TestModelLicense(TestCase): - - def test_sort(self) -> None: - # expected sort order: ([id], [name]) - expected_order = [1, 0, 3, 2] - licenses = [ - License(id='MIT'), - License(id='Apache-2.0'), - License(name='MIT'), - License(name='Apache-2.0'), - ] - sorted_licenses = sorted(licenses) - expected_licenses = reorder(licenses, expected_order) - self.assertListEqual(sorted_licenses, expected_licenses) - - -class TestModelLicenseChoice(TestCase): - - def test_sort(self) -> None: - license_a = License(id='Apache-2.0') - license_b = License(id='MIT') - - # expected sort order: ([license], [expression]) - expected_order = [1, 0, 3, 2] - licenses = [ - LicenseChoice(license=license_b), - LicenseChoice(license=license_a), - LicenseChoice(expression='MIT'), - LicenseChoice(expression='Apache-2.0'), - ] - sorted_licenses = sorted(licenses) - expected_licenses = reorder(licenses, expected_order) - self.assertListEqual(sorted_licenses, expected_licenses) - - class TestModelCopyright(TestCase): def test_same(self) -> None: @@ -535,10 +503,10 @@ def test_sort(self) -> None: # expected sort order: (uri) expected_order = [2, 1, 3, 0] uris = [ - XsUri(uri="d"), - XsUri(uri="b"), - XsUri(uri="a"), - XsUri(uri="c"), + XsUri(uri='d'), + XsUri(uri='b'), + XsUri(uri='a'), + XsUri(uri='c'), ] sorted_uris = sorted(uris) expected_uris = reorder(uris, expected_order) diff --git a/tests/test_model_bom.py b/tests/test_model_bom.py index 6e702dd8..8336f58e 100644 --- a/tests/test_model_bom.py +++ b/tests/test_model_bom.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,24 +15,27 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. + +from typing import Callable from unittest import TestCase from uuid import uuid4 -from cyclonedx.model import ( - License, - LicenseChoice, - OrganizationalContact, - OrganizationalEntity, - Property, - ThisTool, - Tool, -) +from ddt import ddt, named_data + +from cyclonedx.exception.model import LicenseExpressionAlongWithOthersException +from cyclonedx.model import OrganizationalContact, OrganizationalEntity, Property, ThisTool, Tool from cyclonedx.model.bom import Bom, BomMetaData from cyclonedx.model.bom_ref import BomRef from cyclonedx.model.component import Component, ComponentType - -from .data import ( +from cyclonedx.model.license import DisjunctiveLicense +from tests._data.models import ( + get_bom_component_licenses_invalid, + get_bom_component_nested_licenses_invalid, get_bom_for_issue_275_components, + get_bom_metadata_component_licenses_invalid, + get_bom_metadata_component_nested_licenses_invalid, + get_bom_metadata_licenses_invalid, + get_bom_service_licenses_invalid, get_bom_with_component_setuptools_with_vulnerability, get_component_setuptools_simple, get_component_setuptools_simple_no_version, @@ -68,8 +69,8 @@ def test_basic_bom_metadata(self) -> None: manufacturer = OrganizationalEntity(name='test_manufacturer') supplier = OrganizationalEntity(name='test_supplier') licenses = [ - LicenseChoice(license=License(id='MIT')), - LicenseChoice(license=License(id='Apache-2.0')), + DisjunctiveLicense(id='MIT'), + DisjunctiveLicense(id='Apache-2.0'), ] properties = [ Property(name='property_1', value='value_1'), @@ -97,6 +98,7 @@ def test_basic_bom_metadata(self) -> None: self.assertTrue(tools[1] in metadata.tools) +@ddt class TestBom(TestCase): def test_bom_metadata_tool_this_tool(self) -> None: @@ -169,6 +171,19 @@ def test_bom_nested_components_issue_275(self) -> None: self.assertEqual(2, len(bom.components)) bom.validate() + @named_data( + ['metadata_licenses', get_bom_metadata_licenses_invalid], + ['metadata_component_licenses', get_bom_metadata_component_licenses_invalid], + ['metadata_component_nested_licenses', get_bom_metadata_component_nested_licenses_invalid], + ['component_licenses', get_bom_component_licenses_invalid], + ['component_nested_licenses', get_bom_component_nested_licenses_invalid], + ['service_licenses', get_bom_service_licenses_invalid], + ) + def test_validate_with_invalid_license_constellation_throws(self, get_bom: Callable[[], Bom]) -> None: + bom = get_bom() + with self.assertRaises(LicenseExpressionAlongWithOthersException): + bom.validate() + # def test_bom_nested_services_issue_275(self) -> None: # """regression test for issue #275 # see https://github.com/CycloneDX/cyclonedx-python-lib/issues/275 diff --git a/tests/test_model_bom_ref.py b/tests/test_model_bom_ref.py index ced649be..40c7cef1 100644 --- a/tests/test_model_bom_ref.py +++ b/tests/test_model_bom_ref.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,8 +18,7 @@ from unittest import TestCase from cyclonedx.model.bom_ref import BomRef - -from .data import reorder +from tests import reorder class TestBomRef(TestCase): diff --git a/tests/test_model_component.py b/tests/test_model_component.py index eeb2fda6..0333b46f 100644 --- a/tests/test_model_component.py +++ b/tests/test_model_component.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +16,9 @@ # Copyright (c) OWASP Foundation. All Rights Reserved. import datetime -from typing import List +from typing import Any, List from unittest import TestCase -from unittest.mock import Mock, patch +from unittest.mock import patch from cyclonedx.exception.model import NoPropertiesProvidedException from cyclonedx.model import ( @@ -44,8 +42,8 @@ Pedigree, ) from cyclonedx.model.issue import IssueClassification, IssueType -from tests.data import ( - MOCK_UUID_7, +from tests import reorder, uuid_generator +from tests._data.models import ( get_component_setuptools_simple, get_component_setuptools_simple_no_version, get_component_toml_with_hashes_with_references, @@ -54,7 +52,6 @@ get_pedigree_1, get_swid_1, get_swid_2, - reorder, ) @@ -66,16 +63,16 @@ def test_no_parameters(self) -> None: def test_same(self) -> None: ia_comitter = IdentifiableAction(timestamp=datetime.datetime.utcnow(), name='The Committer') - c1 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message="A commit message") - c2 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message="A commit message") + c1 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message='A commit message') + c2 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message='A commit message') self.assertEqual(hash(c1), hash(c2)) self.assertTrue(c1 == c2) def test_not_same(self) -> None: ia_author = IdentifiableAction(timestamp=datetime.datetime.utcnow(), name='The Author') ia_comitter = IdentifiableAction(timestamp=datetime.datetime.utcnow(), name='The Committer') - c1 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message="A commit message") - c2 = Commit(uid='a-random-uid', author=ia_author, committer=ia_comitter, message="A commit message") + c1 = Commit(uid='a-random-uid', author=ia_comitter, committer=ia_comitter, message='A commit message') + c2 = Commit(uid='a-random-uid', author=ia_author, committer=ia_comitter, message='A commit message') self.assertNotEqual(hash(c1), hash(c2)) self.assertFalse(c1 == c2) @@ -107,14 +104,13 @@ def test_sort(self) -> None: class TestModelComponent(TestCase): - @patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_7) - def test_empty_basic_component(self, mock_uuid: Mock) -> None: + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(version=4)) + def test_empty_basic_component(self, *_: Any, **__: Any) -> None: c = Component(name='test-component') - mock_uuid.assert_called() self.assertEqual(c.name, 'test-component') self.assertEqual(c.type, ComponentType.LIBRARY) self.assertIsNone(c.mime_type) - self.assertEqual(str(c.bom_ref), '6f266d1c-760f-4552-ae3b-41a9b74232fa') + self.assertEqual(str(c.bom_ref), '00000000-0000-4000-8000-000000000001') self.assertIsNone(c.supplier) self.assertIsNone(c.author) self.assertIsNone(c.publisher) @@ -132,8 +128,7 @@ def test_empty_basic_component(self, mock_uuid: Mock) -> None: self.assertEqual(len(c.components), 0) self.assertEqual(len(c.get_all_nested_components(include_self=True)), 1) - @patch('cyclonedx.model.component.uuid4', return_value=MOCK_UUID_7) - def test_multiple_basic_components(self, mock_uuid: Mock) -> None: + def test_multiple_basic_components(self) -> None: c1 = Component(name='test-component') self.assertEqual(c1.name, 'test-component') self.assertIsNone(c1.version) @@ -150,8 +145,6 @@ def test_multiple_basic_components(self, mock_uuid: Mock) -> None: self.assertNotEqual(c1, c2) - mock_uuid.assert_called() - def test_external_references(self) -> None: c = Component(name='test-component') c.external_references.add(ExternalReference( @@ -266,15 +259,15 @@ def test_sort(self) -> None: Component(name='component-a', type=ComponentType.LIBRARY, group='group-2'), Component(name='component-a', type=ComponentType.FILE), Component(name='component-b', type=ComponentType.FILE), - Component(name='component-a', type=ComponentType.FILE, version="1.0.0"), + Component(name='component-a', type=ComponentType.FILE, version='1.0.0'), ] sorted_components = sorted(components) expected_components = reorder(components, expected_order) self.assertListEqual(sorted_components, expected_components) def test_nested_components_1(self) -> None: - comp_b = Component(name="comp_b") - comp_c = Component(name="comp_c") + comp_b = Component(name='comp_b') + comp_c = Component(name='comp_c') comp_b.components.add(comp_c) self.assertEqual(1, len(comp_b.components)) @@ -282,9 +275,9 @@ def test_nested_components_1(self) -> None: self.assertEqual(1, len(comp_b.get_all_nested_components(include_self=False))) def test_nested_components_2(self) -> None: - comp_a = Component(name="comp_a") - comp_b = Component(name="comp_b") - comp_c = Component(name="comp_c") + comp_a = Component(name='comp_a') + comp_b = Component(name='comp_b') + comp_c = Component(name='comp_c') comp_b.components.add(comp_c) comp_b.components.add(comp_a) @@ -429,7 +422,7 @@ def test_sort(self) -> None: ] # expected sort order: (type, [diff], sorted(resolves)) - expected_order = [5, 4, 2, 3, 1, 0] + expected_order = [5, 4, 3, 2, 1, 0] patches = [ Patch(type=PatchClassification.MONKEY), Patch(type=PatchClassification.MONKEY, diff=diff_b), diff --git a/tests/test_model_dependency.py b/tests/test_model_dependency.py index 40186a70..1b0d2f64 100644 --- a/tests/test_model_dependency.py +++ b/tests/test_model_dependency.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,7 +19,7 @@ from cyclonedx.model.bom_ref import BomRef from cyclonedx.model.dependency import Dependency -from tests.data import reorder +from tests import reorder class TestDependency(TestCase): @@ -30,14 +28,14 @@ def test_sort(self) -> None: # expected sort order: (value) expected_order = [3, 2, 0, 1] deps = [ - Dependency(ref=BomRef(value="be2c6502-7e9a-47db-9a66-e34f729810a3"), dependencies=[ - Dependency(ref=BomRef(value="0b049d09-64c0-4490-a0f5-c84d9aacf857")), - Dependency(ref=BomRef(value="17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda")) + Dependency(ref=BomRef(value='be2c6502-7e9a-47db-9a66-e34f729810a3'), dependencies=[ + Dependency(ref=BomRef(value='0b049d09-64c0-4490-a0f5-c84d9aacf857')), + Dependency(ref=BomRef(value='17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda')) ]), - Dependency(ref=BomRef(value="cd3e9c95-9d41-49e7-9924-8cf0465ae789")), - Dependency(ref=BomRef(value="17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda")), - Dependency(ref=BomRef(value="0b049d09-64c0-4490-a0f5-c84d9aacf857"), dependencies=[ - Dependency(ref=BomRef(value="cd3e9c95-9d41-49e7-9924-8cf0465ae789")) + Dependency(ref=BomRef(value='cd3e9c95-9d41-49e7-9924-8cf0465ae789')), + Dependency(ref=BomRef(value='17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda')), + Dependency(ref=BomRef(value='0b049d09-64c0-4490-a0f5-c84d9aacf857'), dependencies=[ + Dependency(ref=BomRef(value='cd3e9c95-9d41-49e7-9924-8cf0465ae789')) ]) ] sorted_deps = sorted(deps) diff --git a/tests/test_model_issue.py b/tests/test_model_issue.py index 2d65d731..54816995 100644 --- a/tests/test_model_issue.py +++ b/tests/test_model_issue.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,8 +20,8 @@ from cyclonedx.exception.model import NoPropertiesProvidedException from cyclonedx.model import XsUri from cyclonedx.model.issue import IssueClassification, IssueType, IssueTypeSource - -from .data import get_issue_1, get_issue_2, reorder +from tests import reorder +from tests._data.models import get_issue_1, get_issue_2 class TestModelIssueType(TestCase): @@ -69,15 +67,15 @@ def test_no_params(self) -> None: IssueTypeSource() def test_same(self) -> None: - its_1 = IssueTypeSource(name="The Source", url=XsUri('https://cyclonedx.org')) - its_2 = IssueTypeSource(name="The Source", url=XsUri('https://cyclonedx.org')) + its_1 = IssueTypeSource(name='The Source', url=XsUri('https://cyclonedx.org')) + its_2 = IssueTypeSource(name='The Source', url=XsUri('https://cyclonedx.org')) self.assertNotEqual(id(its_1), id(its_2)) self.assertEqual(hash(its_1), hash(its_2)) self.assertTrue(its_1 == its_2) def test_not_same(self) -> None: - its_1 = IssueTypeSource(name="The Source", url=XsUri('https://cyclonedx.org')) - its_2 = IssueTypeSource(name="Not the Source", url=XsUri('https://cyclonedx.org')) + its_1 = IssueTypeSource(name='The Source', url=XsUri('https://cyclonedx.org')) + its_2 = IssueTypeSource(name='Not the Source', url=XsUri('https://cyclonedx.org')) self.assertNotEqual(id(its_1), id(its_2)) self.assertNotEqual(hash(its_1), hash(its_2)) self.assertFalse(its_1 == its_2) diff --git a/tests/test_model_license.py b/tests/test_model_license.py new file mode 100644 index 00000000..1ccfa534 --- /dev/null +++ b/tests/test_model_license.py @@ -0,0 +1,117 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + + +from random import shuffle +from unittest import TestCase +from unittest.mock import MagicMock + +from cyclonedx.exception.model import MutuallyExclusivePropertiesException +from cyclonedx.model import AttachedText, XsUri +from cyclonedx.model.license import DisjunctiveLicense, LicenseExpression +from tests import reorder + + +class TestModelDisjunctiveLicense(TestCase): + def test_create_complete_id(self) -> None: + text = MagicMock(spec=AttachedText) + url = MagicMock(spec=XsUri) + license = DisjunctiveLicense(id='foo', text=text, url=url) + self.assertEqual('foo', license.id) + self.assertIsNone(license.name) + self.assertIs(text, license.text) + self.assertIs(url, license.url) + + def test_update_id_name(self) -> None: + license = DisjunctiveLicense(id='foo') + self.assertEqual('foo', license.id) + self.assertIsNone(license.name) + license.name = 'bar' + self.assertIsNone(license.id) + self.assertEqual('bar', license.name) + + def test_create_complete_named(self) -> None: + text = MagicMock(spec=AttachedText) + url = MagicMock(spec=XsUri) + license = DisjunctiveLicense(name='foo', text=text, url=url) + self.assertIsNone(license.id) + self.assertEqual('foo', license.name) + self.assertIs(text, license.text) + self.assertIs(url, license.url) + + def test_update_name_id(self) -> None: + license = DisjunctiveLicense(name='foo') + self.assertEqual('foo', license.name) + self.assertIsNone(license.id) + license.id = 'bar' + self.assertIsNone(license.name) + self.assertEqual('bar', license.id) + + def test_throws_when_no_id_nor_name(self) -> None: + with self.assertRaises(MutuallyExclusivePropertiesException): + DisjunctiveLicense(id=None, name=None) + + def test_prefers_id_over_name(self) -> None: + with self.assertWarnsRegex( + RuntimeWarning, + 'Both `id` and `name` have been supplied - `name` will be ignored!'): + license = DisjunctiveLicense(id='foo', name='bar') + self.assertEqual('foo', license.id) + self.assertEqual(None, license.name) + + def test_equal(self) -> None: + a = DisjunctiveLicense(id='foo', name='bar') + b = DisjunctiveLicense(id='foo', name='bar') + c = DisjunctiveLicense(id='bar', name='foo') + self.assertEqual(a, b) + self.assertNotEqual(a, c) + self.assertNotEqual(a, 'foo') + + +class TestModelLicenseExpression(TestCase): + def test_create(self) -> None: + license = LicenseExpression('foo') + self.assertEqual('foo', license.value) + + def test_update(self) -> None: + license = LicenseExpression('foo') + self.assertEqual('foo', license.value) + license.value = 'bar' + self.assertEqual('bar', license.value) + + def test_equal(self) -> None: + a = LicenseExpression('foo') + b = LicenseExpression('foo') + c = LicenseExpression('bar') + self.assertEqual(a, b) + self.assertNotEqual(a, c) + self.assertNotEqual(a, 'foo') + + +class TestModelLicense(TestCase): + + def test_sort_mixed(self) -> None: + expected_order = [1, 2, 0] + licenses = [ + DisjunctiveLicense(name='my license'), + LicenseExpression(value='MIT or Apache-2.0'), + DisjunctiveLicense(id='MIT'), + ] + expected_licenses = reorder(licenses, expected_order) + shuffle(licenses) + sorted_licenses = sorted(licenses) + self.assertListEqual(sorted_licenses, expected_licenses) diff --git a/tests/test_model_release_note.py b/tests/test_model_release_note.py index a06025af..fbbb4e94 100644 --- a/tests/test_model_release_note.py +++ b/tests/test_model_release_note.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,18 +41,18 @@ def test_simple(self) -> None: def test_complete(self) -> None: timestamp: datetime.datetime = datetime.datetime.utcnow() rn = ReleaseNotes( - type='major', title="Release Notes Title", + type='major', title='Release Notes Title', featured_image=XsUri('https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png'), social_image=XsUri('https://cyclonedx.org/cyclonedx-icon.png'), - description="This release is a test release", timestamp=timestamp, + description='This release is a test release', timestamp=timestamp, aliases=[ - "First Test Release" + 'First Test Release' ], tags=['test', 'alpha'], resolves=[], notes=[] ) - rn.aliases.add("Release Alpha") + rn.aliases.add('Release Alpha') rn.tags.add('testing') self.assertEqual(rn.type, 'major') @@ -65,7 +63,7 @@ def test_complete(self) -> None: ) self.assertEqual(str(rn.social_image), 'https://cyclonedx.org/cyclonedx-icon.png') self.assertEqual(rn.description, 'This release is a test release') - self.assertSetEqual(rn.aliases, {"Release Alpha", "First Test Release"}) + self.assertSetEqual(rn.aliases, {'Release Alpha', 'First Test Release'}) self.assertSetEqual(rn.tags, {'test', 'testing', 'alpha'}) self.assertSetEqual(rn.resolves, set()) self.assertFalse(rn.notes) diff --git a/tests/test_model_service.py b/tests/test_model_service.py index 909aa2b1..3b677961 100644 --- a/tests/test_model_service.py +++ b/tests/test_model_service.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,22 +14,22 @@ # # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. - +from typing import Any from unittest import TestCase from unittest.mock import Mock, patch from cyclonedx.model.service import Service -from tests.data import MOCK_UUID_8, MOCK_UUID_9, reorder +from tests import reorder, uuid_generator class TestModelService(TestCase): - @patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_8) + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(version=4)) def test_minimal_service(self, mock_uuid: Mock) -> None: s = Service(name='my-test-service') mock_uuid.assert_called() self.assertEqual(s.name, 'my-test-service') - self.assertEqual(str(s.bom_ref), str(MOCK_UUID_8)) + self.assertEqual(str(s.bom_ref), '00000000-0000-4000-8000-000000000001') self.assertIsNone(s.provider) self.assertIsNone(s.group) self.assertIsNone(s.version) @@ -46,16 +44,15 @@ def test_minimal_service(self, mock_uuid: Mock) -> None: self.assertFalse(s.release_notes) self.assertFalse(s.properties) - @patch('cyclonedx.model.service.uuid4', return_value=MOCK_UUID_9) - def test_service_with_services(self, mock_uuid: Mock) -> None: + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(version=4)) + def test_service_with_services(self, *_: Any, **__: Any) -> None: parent_service = Service(name='parent-service') parent_service.services = [ Service(name='child-service-1'), - Service(name='child-service-2') + Service(name='child-service-2'), ] - mock_uuid.assert_called() self.assertEqual(parent_service.name, 'parent-service') - self.assertEqual(str(parent_service.bom_ref), str(MOCK_UUID_9)) + self.assertEqual(str(parent_service.bom_ref), '00000000-0000-4000-8000-000000000001') self.assertIsNone(parent_service.provider) self.assertIsNone(parent_service.group) self.assertIsNone(parent_service.version) diff --git a/tests/test_model_vulnerability.py b/tests/test_model_vulnerability.py index c3e33134..50a6c03f 100644 --- a/tests/test_model_vulnerability.py +++ b/tests/test_model_vulnerability.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,8 +17,9 @@ from datetime import datetime, timedelta from decimal import Decimal +from typing import Any from unittest import TestCase -from unittest.mock import Mock, patch +from unittest.mock import patch from cyclonedx.model import XsUri from cyclonedx.model.impact_analysis import ImpactAnalysisAffectedStatus @@ -35,7 +34,7 @@ VulnerabilitySeverity, VulnerabilitySource, ) -from tests.data import MOCK_UUID_10, reorder +from tests import reorder, uuid_generator class TestModelVulnerability(TestCase): @@ -169,11 +168,10 @@ def test_v_source_get_localised_vector_other_2(self) -> None: 'SOMETHING_OR_OTHER' ) - @patch('cyclonedx.model.vulnerability.uuid4', return_value=MOCK_UUID_10) - def test_empty_vulnerability(self, mock_uuid: Mock) -> None: + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(version=4)) + def test_empty_vulnerability(self, *_: Any, **__: Any) -> None: v = Vulnerability() - mock_uuid.assert_called() - self.assertEqual(str(v.bom_ref), str(MOCK_UUID_10)) + self.assertEqual(str(v.bom_ref), '00000000-0000-4000-8000-000000000001') self.assertIsNone(v.id) self.assertIsNone(v.source) self.assertFalse(v.references) diff --git a/tests/test_output.py b/tests/test_output.py new file mode 100644 index 00000000..bfacdda3 --- /dev/null +++ b/tests/test_output.py @@ -0,0 +1,51 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + + +from itertools import product +from typing import Tuple +from unittest import TestCase +from unittest.mock import Mock + +from ddt import data, ddt, named_data, unpack + +from cyclonedx.model.bom import Bom +from cyclonedx.output import make_outputter +from cyclonedx.schema import OutputFormat, SchemaVersion + + +@ddt +class TestTestGetInstance(TestCase): + + @named_data(*([f'{x[0].name} {x[1].name}', *x] for x in product(OutputFormat, SchemaVersion))) + @unpack + def test_as_expected(self, of: OutputFormat, sv: SchemaVersion) -> None: + bom = Mock(spec=Bom) + outputter = make_outputter(bom, of, sv) + self.assertIs(outputter.get_bom(), bom) + self.assertIs(outputter.output_format, of) + self.assertIs(outputter.schema_version, sv) + + @data( + *((of, 'foo', (ValueError, f"Unknown {of.name}/schema_version: 'foo'")) for of in OutputFormat), + *(('foo', sv, (ValueError, "Unexpected output_format: 'foo'")) for sv in SchemaVersion), + ) + @unpack + def test_fails_on_wrong_args(self, of: OutputFormat, sv: SchemaVersion, raises_regex: Tuple) -> None: + bom = Mock(spec=Bom) + with self.assertRaisesRegex(*raises_regex): + make_outputter(bom, of, sv) diff --git a/tests/test_output_generic.py b/tests/test_output_generic.py index 7325cbee..073ad642 100644 --- a/tests/test_output_generic.py +++ b/tests/test_output_generic.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +24,7 @@ from cyclonedx.schema import OutputFormat, SchemaVersion -class TestOutputGeneric(TestCase): +class TestGetInstanceGeneric(TestCase): @classmethod def setUpClass(cls) -> None: @@ -34,17 +32,17 @@ def setUpClass(cls) -> None: cls._bom.components.add(Component(name='setuptools')) def test_get_instance_default(self) -> None: - i = get_instance(bom=TestOutputGeneric._bom) + i = get_instance(self._bom) self.assertIsInstance(i, XmlV1Dot4) def test_get_instance_xml_default(self) -> None: - i = get_instance(bom=TestOutputGeneric._bom, output_format=OutputFormat.XML) + i = get_instance(bom=self._bom, output_format=OutputFormat.XML) self.assertIsInstance(i, XmlV1Dot4) def test_get_instance_xml_v1_3(self) -> None: - i = get_instance(bom=TestOutputGeneric._bom, output_format=OutputFormat.XML, schema_version=SchemaVersion.V1_3) + i = get_instance(bom=self._bom, output_format=OutputFormat.XML, schema_version=SchemaVersion.V1_3) self.assertIsInstance(i, XmlV1Dot3) def test_component_no_version_v1_3(self) -> None: - i = get_instance(bom=TestOutputGeneric._bom, schema_version=SchemaVersion.V1_3) + i = get_instance(bom=self._bom, schema_version=SchemaVersion.V1_3) self.assertIsInstance(i, XmlV1Dot3) diff --git a/tests/test_output_json.py b/tests/test_output_json.py index f853da18..02f68c1b 100644 --- a/tests/test_output_json.py +++ b/tests/test_output_json.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,398 +14,80 @@ # # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from os.path import dirname, join + +from typing import Any, Callable +from unittest import TestCase from unittest.mock import Mock, patch -from uuid import UUID +from ddt import data, ddt, idata, named_data, unpack + +from cyclonedx.exception import CycloneDxException, MissingOptionalDependencyException +from cyclonedx.exception.model import LicenseExpressionAlongWithOthersException, UnknownComponentDependencyException from cyclonedx.exception.output import FormatNotSupportedException from cyclonedx.model.bom import Bom -from cyclonedx.output import get_instance +from cyclonedx.output.json import BY_SCHEMA_VERSION, Json from cyclonedx.schema import OutputFormat, SchemaVersion -from tests.base import BaseJsonTestCase -from tests.data import ( - MOCK_UUID_1, - MOCK_UUID_2, - MOCK_UUID_3, - MOCK_UUID_4, - MOCK_UUID_5, - MOCK_UUID_6, - TEST_UUIDS, - get_bom_for_issue_275_components, - get_bom_just_complete_metadata, - get_bom_with_component_setuptools_basic, - get_bom_with_component_setuptools_complete, - get_bom_with_component_setuptools_no_component_version, - get_bom_with_component_setuptools_with_cpe, - get_bom_with_component_setuptools_with_release_notes, - get_bom_with_component_setuptools_with_vulnerability, - get_bom_with_component_toml_1, - get_bom_with_dependencies_hanging, - get_bom_with_dependencies_valid, - get_bom_with_external_references, - get_bom_with_metadata_component_and_dependencies, - get_bom_with_nested_services, - get_bom_with_services_complex, - get_bom_with_services_simple, -) - - -@patch('cyclonedx.model.ThisTool._version', 'TESTING') -class TestOutputJson(BaseJsonTestCase): - - def test_bom_external_references_v1_4(self) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_4, - fixture='bom_external_references.json' - ) - - def test_bom_external_references_v1_3(self) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_3, - fixture='bom_external_references.json' - ) - - def test_bom_external_references_v1_2(self) -> None: - self._validate_json_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_2, - fixture='bom_external_references.json' - ) - - def test_simple_bom_v1_4(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools.json' - ) - - def test_simple_bom_v1_3(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - - def test_simple_bom_v1_2(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools.json' - ) - - def test_simple_bom_v1_1(self) -> None: - self._validate_json_bom_not_supported( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_1 - ) - - def test_simple_bom_v1_0(self) -> None: - self._validate_json_bom_not_supported( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_0 - ) - - def test_simple_bom_v1_4_with_cpe(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_cpe.json' - ) - - def test_simple_bom_v1_3_with_cpe(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_with_cpe.json' - ) - - def test_simple_bom_v1_2_with_cpe(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_with_cpe.json' - ) - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_4_full_component(self, mock: Mock) -> None: - self.maxDiff = None - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_complete.json' - ) - mock.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_3_full_component(self, mock: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_complete.json' - ) - mock.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_2_full_component(self, mock: Mock) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_complete.json' - ) - mock.assert_called() - - def test_bom_v1_4_component_hashes_external_references(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_4, - fixture='bom_toml_1.json' - ) - - def test_bom_v1_3_component_hashes_external_references(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_3, - fixture='bom_toml_1.json' - ) - - def test_bom_v1_2_component_hashes_external_references(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_2, - fixture='bom_toml_1.json' - ) - - def test_bom_v1_1_component_hashes_external_references(self) -> None: - self._validate_json_bom_not_supported(bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_1) - - def test_bom_v1_0_component_hashes_external_references(self) -> None: - self._validate_json_bom_not_supported(bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_0) - - def test_bom_v1_4_no_component_version(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_no_version.json' - ) - - def test_bom_v1_3_no_component_version(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_no_version.json' - ) +from cyclonedx.validation.json import JsonStrictValidator +from tests import SnapshotMixin, mksname, uuid_generator +from tests._data.models import all_get_bom_funct_invalid, all_get_bom_funct_valid - def test_bom_v1_4_component_with_release_notes(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_release_notes.json' - ) +UNSUPPORTED_SV = frozenset((SchemaVersion.V1_1, SchemaVersion.V1_0,)) - def test_bom_v1_3_component_with_release_notes(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - def test_bom_v1_4_component_with_vulnerability(self) -> None: - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_vulnerabilities.json' - ) +@ddt +class TestOutputJson(TestCase, SnapshotMixin): - def test_bom_v1_3_component_with_vulnerability(self) -> None: - # Vulnerabilities not support in JSON < 1.4 - self._validate_json_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.json' - ) - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_1)) - def test_bom_v1_4_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_full_metadata.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_2)) - def test_bom_v1_3_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3, - fixture='bom_with_full_metadata.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - def test_bom_v1_2_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2, - fixture='bom_with_full_metadata.json' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_simple.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_complex.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_json_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_nested.json' - ) - mock_1.assert_called() - mock_2.assert_called() - - def test_bom_v1_4_dependencies(self) -> None: - self._validate_json_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies.json' - ) - - def test_bom_v1_3_dependencies(self) -> None: - self._validate_json_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies.json' - ) - - def test_bom_v1_2_dependencies(self) -> None: - self._validate_json_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies.json' - ) - - def test_bom_v1_4_dependencies_for_bom_component(self) -> None: - self._validate_json_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies_component.json' - ) - - def test_bom_v1_3_dependencies_for_bom_component(self) -> None: - self._validate_json_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies_component.json' - ) - - def test_bom_v1_2_dependencies_for_bom_component(self) -> None: - self._validate_json_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies_component.json' - ) - - def test_bom_v1_4_issue_275_components(self) -> None: - self._validate_json_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_4, - fixture='bom_issue_275_components.json' - ) - - def test_bom_v1_3_issue_275_components(self) -> None: - self._validate_json_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_3, - fixture='bom_issue_275_components.json' - ) - - def test_bom_v1_2_issue_275_components(self) -> None: - self._validate_json_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_2, - fixture='bom_issue_275_components.json' - ) - - def test_bom_v1_4_warn_dependencies(self) -> None: - with self.assertWarns(UserWarning): - # this data set is expected to throw this UserWarning. - # that is the while point of this test! - self._validate_json_bom( - bom=get_bom_with_dependencies_hanging(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_dependencies_hanging.json' - ) - - # region Helper methods - - def _validate_json_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None: - outputter = get_instance(bom=bom, output_format=OutputFormat.JSON, schema_version=schema_version) - self.assertEqual(outputter.schema_version, schema_version) - with open( - join(dirname(__file__), f'fixtures/json/{schema_version.to_version()}/{fixture}')) as expected_json: - output_as_string = outputter.output_as_string() - self.assertValidAgainstSchema(bom_json=output_as_string, schema_version=schema_version) - self.assertEqualJsonBom(expected_json.read(), output_as_string) - - def _validate_json_bom_not_supported(self, bom: Bom, schema_version: SchemaVersion) -> None: + @data(*UNSUPPORTED_SV) + def test_unsupported_schema_raises(self, sv: SchemaVersion) -> None: + outputter_class = BY_SCHEMA_VERSION[sv] + self.assertTrue(issubclass(outputter_class, Json)) + outputter = outputter_class(Mock(spec=Bom)) with self.assertRaises(FormatNotSupportedException): - outputter = get_instance(bom=bom, output_format=OutputFormat.JSON, schema_version=schema_version) outputter.output_as_string() - # endregion Helper methods + @named_data(*((f'{n}-{sv.to_version()}', gb, sv) + for n, gb in all_get_bom_funct_valid + for sv in SchemaVersion + if sv not in UNSUPPORTED_SV)) + @unpack + @patch('cyclonedx.model.ThisTool._version', 'TESTING') + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(0, version=4)) + def test_valid(self, get_bom: Callable[[], Bom], sv: SchemaVersion, *_: Any, **__: Any) -> None: + snapshot_name = mksname(get_bom, sv, OutputFormat.JSON) + bom = get_bom() + json = BY_SCHEMA_VERSION[sv](bom).output_as_string(indent=2) + try: + errors = JsonStrictValidator(sv).validate_str(json) + except MissingOptionalDependencyException: + errors = None # skipped validation + self.assertIsNone(errors) + self.assertEqualSnapshot(json, snapshot_name) + + @named_data(*((f'{n}-{sv.to_version()}', gb, sv) + for n, gb in all_get_bom_funct_invalid + for sv in SchemaVersion + if sv not in UNSUPPORTED_SV)) + @unpack + def test_invalid(self, get_bom: Callable[[], Bom], sv: SchemaVersion) -> None: + bom = get_bom() + outputter = BY_SCHEMA_VERSION[sv](bom) + with self.assertRaises(CycloneDxException) as error: + outputter.output_as_string() + if isinstance(error.exception, ( + LicenseExpressionAlongWithOthersException, + UnknownComponentDependencyException, + )): + return None # expected + raise error.exception + + +@ddt +class TestFunctionalBySchemaVersion(TestCase): + + @idata(SchemaVersion) + def test_get_outputter_expected(self, sv: SchemaVersion) -> None: + outputter_class = BY_SCHEMA_VERSION[sv] + self.assertTrue(issubclass(outputter_class, Json)) + outputter = outputter_class(Mock(spec=Bom)) + self.assertIs(outputter.schema_version, sv) + self.assertIs(outputter.output_format, OutputFormat.JSON) diff --git a/tests/test_output_xml.py b/tests/test_output_xml.py index 101ce952..6e580acc 100644 --- a/tests/test_output_xml.py +++ b/tests/test_output_xml.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,525 +14,68 @@ # # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -from os.path import dirname, join -from unittest.mock import Mock, patch -from uuid import UUID - -from cyclonedx.model.bom import Bom -from cyclonedx.output import get_instance -from cyclonedx.schema import SchemaVersion -from tests.base import BaseXmlTestCase -from tests.data import ( - MOCK_UUID_1, - MOCK_UUID_2, - MOCK_UUID_3, - MOCK_UUID_4, - MOCK_UUID_5, - MOCK_UUID_6, - TEST_UUIDS, - get_bom_for_issue_275_components, - get_bom_just_complete_metadata, - get_bom_with_component_setuptools_basic, - get_bom_with_component_setuptools_complete, - get_bom_with_component_setuptools_no_component_version, - get_bom_with_component_setuptools_with_cpe, - get_bom_with_component_setuptools_with_release_notes, - get_bom_with_component_setuptools_with_vulnerability, - get_bom_with_component_toml_1, - get_bom_with_dependencies_hanging, - get_bom_with_dependencies_valid, - get_bom_with_external_references, - get_bom_with_metadata_component_and_dependencies, - get_bom_with_nested_services, - get_bom_with_services_complex, - get_bom_with_services_simple, -) - - -@patch('cyclonedx.model.ThisTool._version', 'TESTING') -class TestOutputXml(BaseXmlTestCase): - - def test_bom_external_references_v1_4(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_4, - fixture='bom_external_references.xml' - ) - - def test_bom_external_references_v1_3(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_3, - fixture='bom_external_references.xml' - ) - - def test_bom_external_references_v1_2(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_2, - fixture='bom_external_references.xml' - ) - - def test_bom_external_references_v1_1(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_1, - fixture='bom_external_references.xml' - ) - - def test_bom_external_references_v1_0(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_external_references(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - - def test_simple_bom_v1_4(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools.xml' - ) - - def test_simple_bom_v1_3(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.xml' - ) - - def test_simple_bom_v1_2(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools.xml' - ) - - def test_simple_bom_v1_1(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools.xml' - ) - - def test_simple_bom_v1_0(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_basic(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools.xml' - ) - - def test_simple_bom_v1_4_with_cpe(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_cpe.xml' - ) - - def test_simple_bom_v1_3_with_cpe(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_with_cpe.xml' - ) - - def test_simple_bom_v1_2_with_cpe(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_with_cpe.xml' - ) - - def test_simple_bom_v1_1_with_cpe(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_with_cpe.xml' - ) - - def test_simple_bom_v1_0_with_cpe(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_cpe(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_with_cpe.xml' - ) - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_4_full_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_complete.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - def test_bom_v1_3_full_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_complete.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_2)) - def test_bom_v1_2_full_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_complete.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_1)) - def test_bom_v1_1_full_component(self, mock_uuid: Mock) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_complete.xml' - ) - mock_uuid.assert_called() - - def test_bom_v1_0_full_component(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_complete(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_complete.xml' - ) - - def test_bom_v1_4_component_hashes_external_references(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_4, - fixture='bom_toml_hashes_and_references.xml' - ) - - def test_bom_v1_3_component_hashes_external_references(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_3, - fixture='bom_toml_hashes_and_references.xml' - ) - - def test_bom_v1_2_component_hashes_external_references(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_2, - fixture='bom_toml_hashes_and_references.xml' - ) - - def test_bom_v1_1_component_hashes_external_references(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_1, - fixture='bom_toml_hashes_and_references.xml' - ) - - def test_bom_v1_0_component_hashes_external_references(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_toml_1(), schema_version=SchemaVersion.V1_0, - fixture='bom_toml_hashes_and_references.xml' - ) - - def test_bom_v1_4_no_component_version(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_no_version.xml' - ) - - def test_bom_v1_3_no_component_version(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools_no_version.xml' - ) - - def test_bom_v1_2_no_component_version(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_2, - fixture='bom_setuptools_no_version.xml' - ) - - def test_bom_v1_1_no_component_version(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_1, - fixture='bom_setuptools_no_version.xml' - ) - - def test_bom_v1_0_no_component_version(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_no_component_version(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools_no_version.xml' - ) - def test_bom_v1_4_component_with_release_notes(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_release_notes.xml' - ) - def test_bom_v1_3_component_with_release_notes(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_release_notes(), schema_version=SchemaVersion.V1_3, - fixture='bom_setuptools.xml' - ) - - def test_bom_v1_4_component_with_vulnerability(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_4, - fixture='bom_setuptools_with_vulnerabilities.xml' - ) - - def test_bom_v1_0_component_with_vulnerability(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_component_setuptools_with_vulnerability(), schema_version=SchemaVersion.V1_0, - fixture='bom_setuptools.xml' - ) - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - def test_bom_v1_4_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_full_metadata.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_5)) - def test_bom_v1_3_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_3, - fixture='bom_with_full_metadata.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - def test_bom_v1_2_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_2, - fixture='bom_with_full_metadata.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=UUID(MOCK_UUID_1)) - def test_bom_v1_1_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.bom.uuid4', return_value=UUID(MOCK_UUID_1)) - def test_bom_v1_0_with_metadata_component(self, mock_uuid: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_just_complete_metadata(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - mock_uuid.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_simple.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_1_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_3)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_0_services_simple(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_simple(), schema_version=SchemaVersion.V1_0, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_4)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_complex.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_2)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_1_services_complex(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_services_complex(), schema_version=SchemaVersion.V1_1, - fixture='bom_empty.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_4_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_4, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_3_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_3, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - @patch('cyclonedx.model.component.uuid4', return_value=UUID(MOCK_UUID_6)) - @patch('cyclonedx.model.service.uuid4', side_effect=TEST_UUIDS) - def test_bom_v1_2_services_nested(self, mock_1: Mock, mock_2: Mock) -> None: - with self.assertWarns(UserWarning): - self._validate_xml_bom( - bom=get_bom_with_nested_services(), schema_version=SchemaVersion.V1_2, - fixture='bom_services_nested.xml' - ) - mock_1.assert_called() - mock_2.assert_called() - - def test_bom_v1_4_dependencies(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies.xml' - ) - - def test_bom_v1_3_dependencies(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies.xml' - ) - - def test_bom_v1_2_dependencies(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies.xml' - ) - - def test_bom_v1_1_dependencies(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_dependencies_valid(), schema_version=SchemaVersion.V1_1, - fixture='bom_dependencies.xml' - ) - - def test_bom_v1_4_dependencies_for_bom_component(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_4, - fixture='bom_dependencies_component.xml' - ) - - def test_bom_v1_3_dependencies_for_bom_component(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_3, - fixture='bom_dependencies_component.xml' - ) - - def test_bom_v1_2_dependencies_for_bom_component(self) -> None: - self._validate_xml_bom( - bom=get_bom_with_metadata_component_and_dependencies(), schema_version=SchemaVersion.V1_2, - fixture='bom_dependencies_component.xml' - ) - - def test_bom_v1_4_issue_275_components(self) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_4, - fixture='bom_issue_275_components.xml' - ) - - def test_bom_v1_3_issue_275_components(self) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_3, - fixture='bom_issue_275_components.xml' - ) - - def test_bom_v1_2_issue_275_components(self) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_2, - fixture='bom_issue_275_components.xml' - ) - - def test_bom_v1_1_issue_275_components(self) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_1, - fixture='bom_issue_275_components.xml' - ) - - def test_bom_v1_0_issue_275_components(self) -> None: - self._validate_xml_bom( - bom=get_bom_for_issue_275_components(), schema_version=SchemaVersion.V1_0, - fixture='bom_issue_275_components.xml' - ) - - def test_bom_v1_4_warn_dependencies(self) -> None: - with self.assertWarns(UserWarning): - # this data set is expected to throw this UserWarning. - # that is the while point of this test! - self._validate_xml_bom( - bom=get_bom_with_dependencies_hanging(), schema_version=SchemaVersion.V1_4, - fixture='bom_with_dependencies_hanging.xml' - ) - - # region Helper methods +from typing import Any, Callable +from unittest import TestCase +from unittest.mock import Mock, patch - def _validate_xml_bom(self, bom: Bom, schema_version: SchemaVersion, fixture: str) -> None: - outputter = get_instance(bom=bom, schema_version=schema_version) - self.assertEqual(outputter.schema_version, schema_version) - with open( - join(dirname(__file__), f'fixtures/xml/{schema_version.to_version()}/{fixture}')) as expected_xml: - output_as_string = outputter.output_as_string() - self.assertValidAgainstSchema(bom_xml=output_as_string, schema_version=schema_version) - self.assertEqualXmlBom( - expected_xml.read(), output_as_string, namespace=outputter.get_target_namespace() - ) +from ddt import ddt, idata, named_data, unpack - # endregion Helper methods +from cyclonedx.exception import CycloneDxException, MissingOptionalDependencyException +from cyclonedx.exception.model import LicenseExpressionAlongWithOthersException, UnknownComponentDependencyException +from cyclonedx.model.bom import Bom +from cyclonedx.output.xml import BY_SCHEMA_VERSION, Xml +from cyclonedx.schema import OutputFormat, SchemaVersion +from cyclonedx.validation.xml import XmlValidator +from tests import SnapshotMixin, mksname, uuid_generator +from tests._data.models import all_get_bom_funct_invalid, all_get_bom_funct_valid + + +@ddt +class TestOutputXml(TestCase, SnapshotMixin): + + @named_data(*( + (f'{n}-{sv.to_version()}', gb, sv) for n, gb in all_get_bom_funct_valid for sv in SchemaVersion + )) + @unpack + @patch('cyclonedx.model.ThisTool._version', 'TESTING') + @patch('cyclonedx.model.bom_ref.uuid4', side_effect=uuid_generator(0, version=4)) + def test_valid(self, get_bom: Callable[[], Bom], sv: SchemaVersion, *_: Any, **__: Any) -> None: + snapshot_name = mksname(get_bom, sv, OutputFormat.XML) + bom = get_bom() + xml = BY_SCHEMA_VERSION[sv](bom).output_as_string(indent=2) + try: + errors = XmlValidator(sv).validate_str(xml) + except MissingOptionalDependencyException: + errors = None # skipped validation + self.assertIsNone(errors) + self.assertEqualSnapshot(xml, snapshot_name) + + @named_data(*( + (f'{n}-{sv.to_version()}', gb, sv) for n, gb in all_get_bom_funct_invalid for sv in SchemaVersion + )) + @unpack + def test_invalid(self, get_bom: Callable[[], Bom], sv: SchemaVersion) -> None: + bom = get_bom() + outputter = BY_SCHEMA_VERSION[sv](bom) + with self.assertRaises(CycloneDxException) as error: + outputter.output_as_string() + if isinstance(error.exception, ( + LicenseExpressionAlongWithOthersException, + UnknownComponentDependencyException, + )): + return None # expected + raise error.exception + + +@ddt +class TestFunctionalBySchemaVersion(TestCase): + + @idata(SchemaVersion) + def test_get_outputter_expected(self, sv: SchemaVersion) -> None: + outputter_class = BY_SCHEMA_VERSION[sv] + self.assertTrue(issubclass(outputter_class, Xml)) + outputter = outputter_class(Mock(spec=Bom)) + self.assertIs(outputter.schema_version, sv) + self.assertIs(outputter.output_format, OutputFormat.XML) diff --git a/tests/test_real_world_examples.py b/tests/test_real_world_examples.py index 43aa11a9..c3351909 100644 --- a/tests/test_real_world_examples.py +++ b/tests/test_real_world_examples.py @@ -1,4 +1,3 @@ -# encoding: utf-8 # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,31 +14,21 @@ # # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. + import unittest from datetime import datetime -from os.path import dirname, join -from typing import cast +from os.path import join +from typing import Any from unittest.mock import patch -from xml.etree import ElementTree from cyclonedx.model.bom import Bom -from cyclonedx.schema import SchemaVersion - - -def fixed_date_time() -> datetime: - return datetime.fromisoformat('2023-01-07 13:44:32.312678+00:00') +from tests import OWN_DATA_DIRECTORY @patch('cyclonedx.model.ThisTool._version', 'TESTING') -@patch('cyclonedx.model.bom.get_now_utc', fixed_date_time) +@patch('cyclonedx.model.bom.get_now_utc', return_value=datetime.fromisoformat('2023-01-07 13:44:32.312678+00:00')) class TestDeserializeeRealWorldExamples(unittest.TestCase): - def test_webgoat_6_1(self) -> None: - self._attempt_load_example( - schema_version=SchemaVersion.V1_4, fixture='webgoat-6.1.xml' - ) - - def _attempt_load_example(self, schema_version: SchemaVersion, fixture: str) -> None: - with open(join(dirname(__file__), f'fixtures/xml/{schema_version.to_version()}/{fixture}')) as input_xml: - xml = input_xml.read() - cast(Bom, Bom.from_xml(data=ElementTree.fromstring(xml))) + def test_webgoat_6_1(self, *_: Any, **__: Any) -> None: + with open(join(OWN_DATA_DIRECTORY, 'xml', '1.4', 'webgoat-6.1.xml')) as input_xml: + Bom.from_xml(input_xml) diff --git a/tests/test_schema_SchemaVersion.py b/tests/test_schema_SchemaVersion.py new file mode 100644 index 00000000..912c43b2 --- /dev/null +++ b/tests/test_schema_SchemaVersion.py @@ -0,0 +1,76 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + +from unittest import TestCase + +from ddt import ddt, idata, unpack + +from cyclonedx.schema import SchemaVersion + +SORTED_SV = (SchemaVersion.V1_4, + SchemaVersion.V1_3, + SchemaVersion.V1_2, + SchemaVersion.V1_1, + SchemaVersion.V1_0) + +# do not use any value-comparisons or implicit hash-functions here ! +# just work with the position in tuple SORTED_SCHEMA_VERSIONS +td_gt = tuple((a, b) for i, a in enumerate(SORTED_SV) for b in SORTED_SV[i + 1:]) +td_ge = tuple((a, b) for i, a in enumerate(SORTED_SV) for b in SORTED_SV[i:]) +td_eq = tuple((v, v) for v in SORTED_SV) +td_le = tuple((b, a) for a, b in td_ge) +td_lt = tuple((b, a) for a, b in td_gt) +td_ne = tuple((a, b) for i, a in enumerate(SORTED_SV) for j, b in enumerate(SORTED_SV) if i != j) + + +@ddt +class TestSchemaVersion(TestCase): + + @idata(v for v in SchemaVersion) + def test_version_roundtrip(self, v: SchemaVersion) -> None: + v2 = SchemaVersion.from_version(v.to_version()) + self.assertIs(v, v2) + + @idata(td_ne) + @unpack + def test_ne(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertNotEqual(a, b) + + @idata(td_gt) + @unpack + def test_gt(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertGreater(a, b) + + @idata(td_ge) + @unpack + def test_ge(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertGreaterEqual(a, b) + + @idata(td_eq) + @unpack + def test_eq(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertEqual(a, b) + + @idata(td_lt) + @unpack + def test_lt(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertLess(a, b) + + @idata(td_le) + @unpack + def test_le(self, a: SchemaVersion, b: SchemaVersion) -> None: + self.assertLessEqual(a, b) diff --git a/tests/test_schema__res.py b/tests/test_schema__res.py new file mode 100644 index 00000000..930d3709 --- /dev/null +++ b/tests/test_schema__res.py @@ -0,0 +1,42 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + +from os.path import isfile +from typing import Generator +from unittest import TestCase + +from ddt import ddt, idata + +from cyclonedx.schema import _res + + +def _dp_files() -> Generator: + for bom in (_res.BOM_XML, _res.BOM_JSON, _res.BOM_JSON): + for file in bom.values(): + if file is not None: + yield file + yield _res.SPDX_JSON + yield _res.SPDX_XML + yield _res.JSF + + +@ddt +class SchemaResTest(TestCase): + + @idata(_dp_files()) + def test_file_exists(self, file: str) -> None: + self.assertTrue(isfile(file), file) diff --git a/tests/test_spdx.py b/tests/test_spdx.py index 706565ee..6cf244ef 100644 --- a/tests/test_spdx.py +++ b/tests/test_spdx.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - # This file is part of CycloneDX Python Lib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,16 +17,15 @@ from itertools import chain from json import load as json_load -from os.path import join as path_join from unittest import TestCase from ddt import data, ddt, idata, unpack from cyclonedx import spdx +from cyclonedx.schema._res import SPDX_JSON -from . import CDX_SCHEMA_DIRECTORY - -with open(path_join(CDX_SCHEMA_DIRECTORY, 'spdx.schema.json')) as spdx_schema: +# rework access +with open(SPDX_JSON) as spdx_schema: KNOWN_SPDX_IDS = json_load(spdx_schema)['enum'] VALID_COMPOUND_EXPRESSIONS = { diff --git a/tests/test_validation.py b/tests/test_validation.py new file mode 100644 index 00000000..8755191a --- /dev/null +++ b/tests/test_validation.py @@ -0,0 +1,54 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + + +from itertools import product +from typing import Tuple +from unittest import TestCase + +from ddt import data, ddt, named_data, unpack + +from cyclonedx.schema import OutputFormat, SchemaVersion +from cyclonedx.validation import make_schemabased_validator + +UNDEFINED_FORMAT_VERSION = { + (OutputFormat.JSON, SchemaVersion.V1_1), + (OutputFormat.JSON, SchemaVersion.V1_0), +} + + +@ddt +class TestGetSchemabasedValidator(TestCase): + + @named_data(*([f'{f.name} {v.name}', f, v] + for f, v + in product(OutputFormat, SchemaVersion) + if (f, v) not in UNDEFINED_FORMAT_VERSION)) + @unpack + def test_as_expected(self, of: OutputFormat, sv: SchemaVersion) -> None: + validator = make_schemabased_validator(of, sv) + self.assertIs(validator.output_format, of) + self.assertIs(validator.schema_version, sv) + + @data( + *(('foo', sv, (ValueError, 'Unexpected output_format')) for sv in SchemaVersion), + *((f, v, (ValueError, 'Unsupported schema_version')) for f, v in UNDEFINED_FORMAT_VERSION) + ) + @unpack + def test_fails_on_wrong_args(self, of: OutputFormat, sv: SchemaVersion, raises_regex: Tuple) -> None: + with self.assertRaisesRegex(*raises_regex): + make_schemabased_validator(of, sv) diff --git a/tests/test_validation_json.py b/tests/test_validation_json.py new file mode 100644 index 00000000..6e99acb7 --- /dev/null +++ b/tests/test_validation_json.py @@ -0,0 +1,111 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + +from glob import iglob +from os.path import join +from typing import Generator +from unittest import TestCase + +from ddt import data, ddt, idata, unpack + +from cyclonedx.exception import MissingOptionalDependencyException +from cyclonedx.schema import OutputFormat, SchemaVersion +from cyclonedx.validation.json import JsonStrictValidator, JsonValidator +from tests import SCHEMA_TESTDATA_DIRECTORY + +UNSUPPORTED_SCHEMA_VERSIONS = {SchemaVersion.V1_0, SchemaVersion.V1_1, } + + +def _dp(prefix: str) -> Generator: + return ( + (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS + for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'{prefix}-*.json')) + ) + + +@ddt +class TestJsonValidator(TestCase): + + @idata(sv for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS) + def test_validator_as_expected(self, schema_version: SchemaVersion) -> None: + validator = JsonValidator(schema_version) + self.assertIs(validator.schema_version, schema_version) + self.assertIs(validator.output_format, OutputFormat.JSON) + + @idata(UNSUPPORTED_SCHEMA_VERSIONS) + def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: + with self.assertRaisesRegex(ValueError, 'Unsupported schema_version'): + JsonValidator(schema_version) + + @idata(_dp('valid')) + @unpack + def test_validate_no_none(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = JsonValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNone(validation_error) + + @idata(_dp('invalid')) + @unpack + def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = JsonValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNotNone(validation_error) + self.assertIsNotNone(validation_error.data) + + +@ddt +class TestJsonStrictValidator(TestCase): + + @data(*UNSUPPORTED_SCHEMA_VERSIONS) + def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: + with self.assertRaisesRegex(ValueError, 'Unsupported schema_version'): + JsonStrictValidator(schema_version) + + @idata(_dp('valid')) + @unpack + def test_validate_no_none(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = JsonStrictValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNone(validation_error) + + @idata(_dp('invalid')) + @unpack + def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = JsonStrictValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNotNone(validation_error) + self.assertIsNotNone(validation_error.data) diff --git a/tests/test_validation_xml.py b/tests/test_validation_xml.py new file mode 100644 index 00000000..c97ee6f7 --- /dev/null +++ b/tests/test_validation_xml.py @@ -0,0 +1,77 @@ +# This file is part of CycloneDX Python Lib +# +# 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. + +from glob import iglob +from os.path import join +from typing import Generator +from unittest import TestCase + +from ddt import ddt, idata, unpack + +from cyclonedx.exception import MissingOptionalDependencyException +from cyclonedx.schema import OutputFormat, SchemaVersion +from cyclonedx.validation.xml import XmlValidator +from tests import SCHEMA_TESTDATA_DIRECTORY + +UNSUPPORTED_SCHEMA_VERSIONS = set() + + +def _dp(prefix: str) -> Generator: + return ( + (sv, tf) for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS + for tf in iglob(join(SCHEMA_TESTDATA_DIRECTORY, sv.to_version(), f'{prefix}-*.xml')) + ) + + +@ddt +class TestXmlValidator(TestCase): + + @idata(sv for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS) + def test_validator_as_expected(self, schema_version: SchemaVersion) -> None: + validator = XmlValidator(schema_version) + self.assertIs(validator.schema_version, schema_version) + self.assertIs(validator.output_format, OutputFormat.XML) + + @idata(UNSUPPORTED_SCHEMA_VERSIONS) + def test_throws_with_unsupported_schema_version(self, schema_version: SchemaVersion) -> None: + with self.assertRaisesRegex(ValueError, f'unsupported schema_version: {schema_version}'): + XmlValidator(schema_version) + + @idata(_dp('valid')) + @unpack + def test_validate_no_none(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = XmlValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNone(validation_error) + + @idata(_dp('invalid')) + @unpack + def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_file: str) -> None: + validator = XmlValidator(schema_version) + with open(join(test_data_file), 'r') as tdfh: + test_data = tdfh.read() + try: + validation_error = validator.validate_str(test_data) + except MissingOptionalDependencyException: + self.skipTest('MissingOptionalDependencyException') + self.assertIsNotNone(validation_error) + self.assertIsNotNone(validation_error.data) diff --git a/tools/schema-downloader.py b/tools/schema-downloader.py new file mode 100644 index 00000000..af0b1130 --- /dev/null +++ b/tools/schema-downloader.py @@ -0,0 +1,108 @@ +# 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 + +import re +from os.path import dirname, join +from urllib.request import urlretrieve + +SOURCE_ROOT = 'https://raw.githubusercontent.com/CycloneDX/specification/master/schema/' +TARGET_ROOT = join(dirname(__file__), '..', 'cyclonedx', 'schema', '_res') + +BOM_XSD = { + 'versions': ['1.4', '1.3', '1.2', '1.1', '1.0'], + 'sourcePattern': f'{SOURCE_ROOT}bom-%s.xsd', + 'targetPattern': join(TARGET_ROOT, 'bom-%s.SNAPSHOT.xsd'), + 'replace': [], + 'replaceRE': [ + (re.compile(r'schemaLocation="https?://cyclonedx.org/schema/spdx"'), 'schemaLocation="spdx.SNAPSHOT.xsd"') + ] +} + +# "version" is not required but optional with a default value! +# this is wrong in schema<1.5 +_BOM_SCHEMA_ENUM_RE = re.compile( + r'("\$id": "(http://cyclonedx\.org/schema/bom.+?\.schema\.json)".*"enum": \[\s+")' + r'http://cyclonedx\.org/schema/bom.+?\.schema\.json"', + re.DOTALL) +_BOM_SCHEMA_ENUM_REPL = r'\1\2"' + + +# "version" is not required but optional with a default value! +# this is wrong in schema<1.5 +_BOM_REQUIRED_S = """ + "required": [ + "bomFormat", + "specVersion", + "version" + ],""" +_BOM_REQUIRED_R = """ + "required": [ + "bomFormat", + "specVersion" + ],""" + + +# there was a case where the default value did not match the own pattern ... +# this is wrong in schema<1.5 +_DEFAULTS_WITH_PATTERN_RE = re.compile(r'\s+"default": "",(?![^}]*?"pattern": "\^\(\.\*\)\$")', re.MULTILINE) +_DEFAULTS_WITH_PATERN_REPL = r'' + +BOM_JSON_LAX = { + 'versions': ['1.4', '1.3', '1.2'], + 'sourcePattern': f'{SOURCE_ROOT}bom-%s.schema.json', + 'targetPattern': join(TARGET_ROOT, 'bom-%s.SNAPSHOT.schema.json'), + 'replace': [ + ('spdx.schema.json', 'spdx.SNAPSHOT.schema.json'), + ('jsf-0.82.schema.json', 'jsf-0.82.SNAPSHOT.schema.json'), + (_BOM_REQUIRED_S, _BOM_REQUIRED_R), + ], + 'replaceRE': [ + (_BOM_SCHEMA_ENUM_RE, _BOM_SCHEMA_ENUM_REPL), + # there was a case where the default value did not match the own pattern ... + # this is wrong in schema<1.5 + # with current SchemaValidator this is no longer required, as defaults are not applied + # (re.compile(r'\s+"default": "",(?![^}]*?"pattern": "\^\(\.\*\)\$")', re.MULTILINE), '') + ] +} + +BOM_JSON_STRICT = { + 'versions': ['1.3', '1.2'], + 'sourcePattern': f'{SOURCE_ROOT}bom-%s-strict.schema.json', + 'targetPattern': join(TARGET_ROOT, 'bom-%s-strict.SNAPSHOT.schema.json'), + 'replace': BOM_JSON_LAX['replace'], + 'replaceRE': BOM_JSON_LAX['replaceRE'] +} + +OTHER_DOWNLOADABLES = [ + (f'{SOURCE_ROOT}spdx.schema.json', join(TARGET_ROOT, 'spdx.SNAPSHOT.schema.json')), + (f'{SOURCE_ROOT}spdx.xsd', join(TARGET_ROOT, 'spdx.SNAPSHOT.xsd')), + (f'{SOURCE_ROOT}jsf-0.82.schema.json', join(TARGET_ROOT, 'jsf-0.82.SNAPSHOT.schema.json')), +] + +for dspec in (BOM_XSD, BOM_JSON_LAX, BOM_JSON_STRICT): + for version in dspec['versions']: + source = dspec['sourcePattern'].replace('%s', version) + target = dspec['targetPattern'].replace('%s', version) + tempfile, _ = urlretrieve(source) # nosec B310 + with open(tempfile, 'r') as tmpf: + with open(target, 'w') as tarf: + text = tmpf.read() + for search, replace in dspec['replace']: + text = text.replace(search, replace) + for search, replace in dspec['replaceRE']: + text = search.sub(replace, text) + tarf.write(text) + +for source, target in OTHER_DOWNLOADABLES: + urlretrieve(source, target) # nosec B310 diff --git a/tox.ini b/tox.ini index de97d0e6..8187a2c1 100644 --- a/tox.ini +++ b/tox.ini @@ -4,12 +4,12 @@ # and then run "tox" from this directory. [tox] -minversion = 3.10 +minversion = 4.0 envlist = flake8 - mypy-{locked,lowest} - py{311,310,39,38,37}-{locked,lowest} -isolated_build = True + mypy-{current,lowest} + py{312,311,310,39,38}-{allExtras,noExtras} + bandit skip_missing_interpreters = True usedevelop = False download = False @@ -17,11 +17,11 @@ download = False [testenv] # settings in this category apply to all other testenv, if not overwritten skip_install = True -whitelist_externals = poetry +allowlist_externals = poetry commands_pre = {envpython} --version - poetry install -v - lowest: poetry run pip install -U -r deps.lowest.r + !noExtras: poetry install -v --all-extras + noExtras: poetry install -v poetry run pip freeze commands = poetry run coverage run --source=cyclonedx -m unittest discover -t . -s tests -v @@ -29,28 +29,18 @@ setenv = PYTHONHASHSEED=0 CDX_TEST_RECREATE_SNAPSHOTS={env:CDX_TEST_RECREATE_SNAPSHOTS:} -[testenv:mypy{,-locked,-lowest}] +[testenv:mypy{,-current,-lowest}] commands = # mypy config is in own file: `.mypy.ini` !lowest: poetry run mypy - lowest: poetry run mypy --python-version=3.7 + lowest: poetry run mypy --python-version=3.8 [testenv:flake8] commands = - poetry run flake8 cyclonedx/ tests/ + poetry run flake8 cyclonedx/ tests/ typings/ examples/ tools/ + +[testenv:bandit] +commands = + poetry run bandit -c bandit.yml -v -r cyclonedx tests examples tools + -[flake8] -## keep in sync with isort config - in `isort.cfg` file -exclude = - build,dist,__pycache__,.eggs,*.egg-info*, - *_cache,*.cache, - .git,.tox,.venv,venv,.venv*,venv*, - _OLD,_TEST, - docs -max-line-length = 120 -ignore = - E305 - # ignore `self`, `cls` markers of flake8-annotations>=2.0 - ANN101,ANN102 - # ignore ANN401 for dynamically typed *args and **kwargs - ANN401 diff --git a/typings/sortedcontainers.pyi b/typings/sortedcontainers.pyi index b8e8b6f6..c9167837 100644 --- a/typings/sortedcontainers.pyi +++ b/typings/sortedcontainers.pyi @@ -1,9 +1,9 @@ # Correct as of 27 May 2022 # sortedcontainers does not have PEP561 type hints, and there are no published typeshed hints. -# The contents of this file were obtained from +# The contents of this file were obtained from # https://github.com/althonos/python-sortedcontainers/blob/d0a225d7fd0fb4c54532b8798af3cbeebf97e2d5/sortedcontainers/sortedset.pyi -from typing import ( # Iterator,; Tuple,; Type, +from typing import ( # Iterator,; Tuple,; Type, Set Any, Callable, Hashable, @@ -12,7 +12,6 @@ from typing import ( # Iterator,; Tuple,; Type, MutableSet, Optional, Sequence, - Set, TypeVar, Union, overload,