diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml new file mode 100644 index 000000000..a3dc889f5 --- /dev/null +++ b/.github/workflows/build_docs.yml @@ -0,0 +1,64 @@ +name: Build Docs + +on: + push: + branches: ['master', 'main'] + pull_request: + workflow_dispatch: + +env: + PYTHON_VERSION_DEFAULT: "3.10" + +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + docs_xml: + runs-on: ubuntu-latest + defaults: + run: + working-directory: docgen/xml + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@v4 + - name: Set up JDK + # see https://github.com/actions/setup-java + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'zulu' + java-package: jdk + - name: Generate Schema documentation + run: ./gen.sh + - name: Archive Schema documentation + # https://github.com/actions/upload-artifact + uses: actions/upload-artifact@v4 + with: + name: XML-Schema-documentation + path: docgen/xml/docs + if-no-files-found: error + docs_json: + runs-on: ubuntu-latest + defaults: + run: + working-directory: docgen/json + 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@v5 + with: + python-version: ${{ env.PYTHON_VERSION_DEFAULT }} + architecture: 'x64' + - name: Generate Schema documentation + run: ./gen.sh + - name: Archive Schema documentation + # https://github.com/actions/upload-artifact + uses: actions/upload-artifact@v4 + with: + name: JSON-Schema-documentation + path: docgen/json/docs + if-no-files-found: error diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml deleted file mode 100644 index aa979e7c3..000000000 --- a/.github/workflows/cibuild.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: CI Build - -on: [push, pull_request] - -env: - PYTHON_VERISON_DEFAULT: "3.10" - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build with Maven - run: | - cd tools - mvn -B package --file pom.xml - cd .. - - name: Setup Python Environment - # see https://github.com/actions/setup-python - uses: actions/setup-python@v2 - with: - python-version: ${{ env.PYTHON_VERISON_DEFAULT }} - architecture: 'x64' - - name: Generate JSON Schema documentation - run: | - cd docgen/json - ./gen.sh - - name: Generate XML Schema documentation - run: | - cd docgen/xml - ./gen.sh - - name: Archive JSON Schema documentation - uses: actions/upload-artifact@v2 - with: - name: JSON-Schema-documentation - path: docgen/json/docs - - name: Archive XML Schema documentation - uses: actions/upload-artifact@v2 - with: - name: XML-Schema-documentation - path: docgen/xml/docs \ No newline at end of file diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml deleted file mode 100644 index dc18f9cc5..000000000 --- a/.github/workflows/js.yml +++ /dev/null @@ -1,32 +0,0 @@ -# docs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions - -name: JS CI - -on: [push, pull_request, workflow_dispatch] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - -defaults: - run: - working-directory: tools/src/test/js - -jobs: - test: - timeout-minutes: 30 - runs-on: ubuntu-latest - steps: - - name: Checkout - # see https://github.com/actions/checkout - uses: actions/checkout@v3 - - name: Setup Node.js - # see https://github.com/actions/setup-node - uses: actions/setup-node@v3 - with: - node-version: '20.x' - - name: Install Depenencies - run: npm install - - name: Run test - run: npm test diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml deleted file mode 100644 index bde345917..000000000 --- a/.github/workflows/php.yml +++ /dev/null @@ -1,28 +0,0 @@ -# docs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions - -name: PHP CI - -on: [push, pull_request, workflow_dispatch] - -defaults: - run: - working-directory: tools/src/test/php - -jobs: - test: - timeout-minutes: 30 - runs-on: ubuntu-latest - steps: - - name: Checkout - # see https://github.com/actions/checkout - uses: actions/checkout@v2 - - name: Setup PHP - # see https://github.com/shivammathur/setup-php - uses: shivammathur/setup-php@v2 - with: - php-version: "8.1" - tools: composer:v2 - - name: Install Depenencies - run: composer install - - name: Run test - run: composer run test diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml new file mode 100644 index 000000000..5935a22c0 --- /dev/null +++ b/.github/workflows/test_java.yml @@ -0,0 +1,37 @@ +name: CT Java + +on: + push: + branches: ['master', 'main'] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: tools + +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + test_java: + runs-on: ubuntu-latest + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Set up JDK + # see https://github.com/actions/setup-java + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 + with: + java-version: '8' + distribution: 'zulu' + java-package: jdk + - name: test with Maven + run: mvn clean test diff --git a/.github/workflows/test_js.yml b/.github/workflows/test_js.yml new file mode 100644 index 000000000..ee3db0f0b --- /dev/null +++ b/.github/workflows/test_js.yml @@ -0,0 +1,41 @@ +# docs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: CT JavaScript + +on: + push: + branches: ['master', 'main'] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: tools/src/test/js + +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + test_js: + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Setup Node.js + # see https://github.com/actions/setup-node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: '24.x' + package-manager-cache: false + - name: Install Dependencies + run: npm install + - name: Run test + run: npm test diff --git a/.github/workflows/test_php.yml b/.github/workflows/test_php.yml new file mode 100644 index 000000000..e6259aa25 --- /dev/null +++ b/.github/workflows/test_php.yml @@ -0,0 +1,41 @@ +# docs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: CT PHP + +on: + push: + branches: ['master', 'main'] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: tools/src/test/php + +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + test_php: + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Setup PHP + # see https://github.com/shivammathur/setup-php + uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2 + with: + php-version: "8.4" + tools: composer:v2 + - name: Install Depenencies + run: composer install + - name: Run test + run: composer run test diff --git a/.github/workflows/test_proto.yml b/.github/workflows/test_proto.yml new file mode 100644 index 000000000..65847affc --- /dev/null +++ b/.github/workflows/test_proto.yml @@ -0,0 +1,33 @@ +# docs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: CT ProtoBuf + +on: + push: + branches: ['master', 'main'] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: tools/src/test/proto + +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + test_proto: + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - name: Checkout + # see https://github.com/actions/checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Run test + run: ./test.sh diff --git a/schema/bom-1.5.proto b/schema/bom-1.5.proto index b6150989c..a6ecd79d1 100644 --- a/schema/bom-1.5.proto +++ b/schema/bom-1.5.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package cyclonedx.v1_5; +package cyclonedx.v1_5; // 1.5.1 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. + // 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; @@ -103,9 +103,10 @@ message Component { 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 + // Specifies the scope of the component. If scope is not specified, SCOPE_REQUIRED scope should be assumed by the consumer of the BOM optional Scope scope = 11; repeated Hash hashes = 12; + // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) 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; @@ -352,7 +353,7 @@ message License { // Licensing details describing the licensor/licensee, license type, renewal and expiration dates, and other important metadata optional Licensing licensing = 6; // Specifies optional, custom, properties - repeated Property properties = 7; + repeated Property properties = 7; } message Licensing { @@ -431,6 +432,7 @@ message Metadata { // 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 + // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) optional LicenseChoice licenses = 7; // Specifies optional, custom, properties repeated Property properties = 8; @@ -554,6 +556,7 @@ message Service { // 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 DataFlow data = 10; + // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) repeated LicenseChoice licenses = 11; // Provides the ability to document external references related to the service. repeated ExternalReference external_references = 12; @@ -572,11 +575,11 @@ message Swid { string tag_id = 1; // Maps to the name of a SoftwareIdentity. string name = 2; - // Maps to the version of a SoftwareIdentity. + // Maps to the version of a SoftwareIdentity. Defaults to '0.0' if not specified. optional string version = 3; - // Maps to the tagVersion of a SoftwareIdentity. + // Maps to the tagVersion of a SoftwareIdentity. Defaults to '0' if not specified. optional int32 tag_version = 4; - // Maps to the patch of a SoftwareIdentity. + // Maps to the patch of a SoftwareIdentity. Defaults to 'false' if not specified. optional bool patch = 5; // Specifies the full content of the SWID tag. optional AttachedText text = 6; @@ -650,6 +653,7 @@ message EvidenceCopyright { } message Evidence { + // EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression) repeated LicenseChoice licenses = 1; repeated EvidenceCopyright copyright = 2; repeated EvidenceIdentity identity = 3; @@ -956,10 +960,10 @@ message VulnerabilityAffectedVersions { oneof choice { // A single version of a component or service. string version = 1; - // 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 + // A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec string range = 2; } - // The vulnerability status for the version or range of versions. + // The vulnerability status for the version or range of versions. Defaults to VULNERABILITY_AFFECTED_STATUS_AFFECTED if not specified. optional VulnerabilityAffectedStatus status = 3; } @@ -1005,6 +1009,8 @@ message ModelCard { optional QuantitativeAnalysis quantitativeAnalysis = 3; // What considerations should be taken into account regarding the model's construction, training, and application? optional ModelCardConsiderations considerations = 4; + // Specifies optional, custom, properties + repeated Property properties = 5; message ModelParameters { // The overall approach to learning used by the model for problem solving. diff --git a/schema/bom-1.5.schema.json b/schema/bom-1.5.schema.json index c14972812..d9c4d0803 100644 --- a/schema/bom-1.5.schema.json +++ b/schema/bom-1.5.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": { @@ -2285,7 +2284,7 @@ "$ref": "#/definitions/version" }, "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", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "$ref": "#/definitions/range" }, "status": { @@ -2327,7 +2326,7 @@ "maxLength": 1024 }, "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", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "type": "string", "minLength": 1, "maxLength": 1024 diff --git a/schema/bom-1.5.xsd b/schema/bom-1.5.xsd index 066c7d1c0..8a541afb0 100644 --- a/schema/bom-1.5.xsd +++ b/schema/bom-1.5.xsd @@ -22,7 +22,7 @@ limitations under the License. targetNamespace="http://cyclonedx.org/schema/bom/1.5" vc:minVersion="1.0" vc:maxVersion="1.1" - version="1.5.0"> + version="1.5.1"> @@ -474,7 +474,7 @@ limitations under the License. Specifies a description for the component - + Specifies the scope of the component. If scope is not specified, 'required' scope SHOULD be assumed by the consumer of the BOM. @@ -2433,12 +2433,12 @@ limitations under the License. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are opensource. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are opensource. @@ -2885,7 +2885,7 @@ limitations under the License. - + @@ -2897,7 +2897,7 @@ limitations under the License. - + @@ -2911,7 +2911,7 @@ limitations under the License. - + @@ -2923,7 +2923,7 @@ limitations under the License. - + @@ -3008,6 +3008,16 @@ limitations under the License. + + + 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. Property names + of interest to the general public are encouraged to be registered in the + CycloneDX Property Taxonomy - https://github.com/CycloneDX/cyclonedx-property-taxonomy. + Formal registration is OPTIONAL. + + @@ -3644,7 +3654,7 @@ limitations under the License. - 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 + A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec diff --git a/schema/xmlcatalog.xml b/schema/xmlcatalog.xml new file mode 100644 index 000000000..2735b5360 --- /dev/null +++ b/schema/xmlcatalog.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/pom.xml b/tools/pom.xml index d074df4fe..9667d4090 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -51,11 +51,12 @@ 1.10 3.1.0 - 2.7 - 3.6 - 1.2 + 2.17.0 + 3.18.0 + 1.12.0 + 1.5.5 1.4.9 - 7.2.0 + 2.0.16 @@ -98,6 +99,24 @@ + + + + + org.slf4j + slf4j-api + ${lib.slf4j.api} + + + + org.slf4j + slf4j-simple + ${lib.slf4j.api} + + + + + @@ -123,16 +142,22 @@ compile + + com.networknt + json-schema-validator + ${lib.json.schema.validator} + test + org.junit.jupiter - junit-jupiter-engine - 5.7.0 + junit-jupiter-api + 5.11.4 test + - org.cyclonedx - cyclonedx-core-java - ${lib.cyclonedx.core.java.version} + org.slf4j + slf4j-simple test @@ -142,8 +167,16 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.5.2 + + + ${project.basedir}/../schema + + + src/test/resources + + diff --git a/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java index ff45bd20c..a5b4697ed 100644 --- a/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java @@ -28,20 +28,18 @@ List getAllResources() throws Exception { files.addAll(getResources("1.2/")); files.addAll(getResources("1.3/")); files.addAll(getResources("1.4/")); + files.addAll(getResources("1.5/")); return files; } - List getResources(final String resourceDirectory) throws Exception { - final List files = new ArrayList<>(); - String dir = resourceDirectory; - if (!resourceDirectory.endsWith("/")) { - dir += "/"; - } - try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(dir)) { + private List getResources(final String resourceDirectory) throws Exception { + final List resources = new ArrayList<>(); + try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceDirectory)) { if (in != null) { - files.addAll(IOUtils.readLines(in, StandardCharsets.UTF_8)); + IOUtils.readLines(in, StandardCharsets.UTF_8) + .forEach(resource -> resources.add(resourceDirectory + resource)); } } - return files; + return resources; } } diff --git a/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java index 55716982e..5d74ac935 100644 --- a/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java @@ -13,63 +13,124 @@ */ package org.cyclonedx.schema; -import org.cyclonedx.CycloneDxSchema; -import org.cyclonedx.parsers.JsonParser; -import org.junit.jupiter.api.DynamicTest; -import org.junit.jupiter.api.TestFactory; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.networknt.schema.DefaultJsonMetaSchemaFactory; +import com.networknt.schema.DisallowUnknownKeywordFactory; +import com.networknt.schema.JsonMetaSchema; +import com.networknt.schema.JsonMetaSchemaFactory; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.NonValidationKeyword; +import com.networknt.schema.SchemaId; +import com.networknt.schema.SchemaLocation; +import com.networknt.schema.SchemaValidatorsConfig; +import com.networknt.schema.resource.ClasspathSchemaLoader; +import com.networknt.schema.resource.DisallowSchemaLoader; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { + + private static final ObjectMapper MAPPER = new JsonMapper(); + + private static final String JSF_NAMESPACE = "http://cyclonedx.org/schema/jsf-0.82.schema.json"; + private static final String SPDX_NAMESPACE = "http://cyclonedx.org/schema/spdx.schema.json"; + private static final String CRYPTO_DEF_NAMESPACE = "http://cyclonedx.org/schema/cryptography-defs.schema.json"; + + private static final JsonSchema VERSION_12; + private static final JsonSchema VERSION_13; + private static final JsonSchema VERSION_14; + private static final JsonSchema VERSION_15; -public class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { + static { + JsonMetaSchemaFactory metaSchemaFactory = new DefaultJsonMetaSchemaFactory() { + @Override + public JsonMetaSchema getMetaSchema( + String iri, JsonSchemaFactory schemaFactory, SchemaValidatorsConfig config) { + return addCustomKeywords(super.getMetaSchema(iri, schemaFactory, config)); + } + }; + JsonSchemaFactory factory = JsonSchemaFactory.builder() + .defaultMetaSchemaIri(SchemaId.V7) + .metaSchema(addCustomKeywords(JsonMetaSchema.getV7())) + .metaSchemaFactory(metaSchemaFactory) + .schemaLoaders(b -> b.add(new ClasspathSchemaLoader()).add(DisallowSchemaLoader.getInstance())) + .schemaMappers(b -> b.mapPrefix(SPDX_NAMESPACE, "classpath:spdx.schema.json") + .mapPrefix(JSF_NAMESPACE, "classpath:jsf-0.82.schema.json") + .mapPrefix(CRYPTO_DEF_NAMESPACE, "classpath:cryptography-defs.schema.json") + ).build(); + VERSION_12 = factory.getSchema(SchemaLocation.of("classpath:bom-1.2-strict.schema.json")); + VERSION_13 = factory.getSchema(SchemaLocation.of("classpath:bom-1.3-strict.schema.json")); + VERSION_14 = factory.getSchema(SchemaLocation.of("classpath:bom-1.4.schema.json")); + VERSION_15 = factory.getSchema(SchemaLocation.of("classpath:bom-1.5.schema.json")); + } + + private static JsonMetaSchema addCustomKeywords(JsonMetaSchema metaSchema) { + return JsonMetaSchema.builder(metaSchema) + // Non-standard keywords in the CycloneDX schema files. + .keyword(new NonValidationKeyword("deprecated")) + .keyword(new NonValidationKeyword("meta:enum")) + .unknownKeywordFactory(new DisallowUnknownKeywordFactory()) + .build(); + } @TestFactory Collection dynamicTestsWithCollection() throws Exception { - final List files = getAllResources(); + final List resources = getAllResources(); final List dynamicTests = new ArrayList<>(); - for (final String file: files) { - if (file.endsWith(".json")) { - final CycloneDxSchema.Version schemaVersion; - if (file.endsWith("-1.2.json")) { - schemaVersion = CycloneDxSchema.Version.VERSION_12; - } else if (file.endsWith("-1.3.json")) { - schemaVersion = CycloneDxSchema.Version.VERSION_13; - } else if (file.endsWith("-1.4.json")) { - schemaVersion = CycloneDxSchema.Version.VERSION_14; - } else { - schemaVersion = null; - } - if (file.startsWith("valid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); - } else if (file.startsWith("invalid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); + for (final String resource : resources) { + String resourceName = StringUtils.substringAfterLast(resource, "/"); + if (resourceName.endsWith(".json")) { + JsonSchema schema = getSchema(resourceName); + if (schema != null) { + if (resourceName.startsWith("valid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertTrue(isValid(schema, resource), resource))); + } else if (resourceName.startsWith("invalid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertFalse(isValid(schema, resource), resource))); + } } } } return dynamicTests; } - private boolean isValidJson(CycloneDxSchema.Version version, String resource) throws Exception { - final File file = new File(this.getClass().getResource(resource).getFile()); - final JsonParser parser = new JsonParser(); - return parser.isValid(file, version); - - // Uncomment to provide more detailed validation errors - /* - try { - final String jsonString = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - parser.getJsonSchema(version, true).validate(new JSONObject(jsonString)); - return true; - } catch (ValidationException e) { - e.printStackTrace(); + private boolean isValid(JsonSchema schema, String resource) { + try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource); + JsonParser parser = MAPPER.createParser(input)) { + JsonNode node = parser.readValueAsTree(); + return schema.validate(node).isEmpty(); + } catch (IOException e) { return false; } - */ + } + + private JsonSchema getSchema(String resourceName) { + if (resourceName.endsWith("-1.2.json")) { + return VERSION_12; + } + if (resourceName.endsWith("-1.3.json")) { + return VERSION_13; + } + if (resourceName.endsWith("-1.4.json")) { + return VERSION_14; + } + if (resourceName.endsWith("-1.5.json")) { + return VERSION_15; + } + return null; } } diff --git a/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java new file mode 100644 index 000000000..30df90312 --- /dev/null +++ b/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java @@ -0,0 +1,129 @@ +package org.cyclonedx.schema; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +public class XmlCatalogVerificationTest { + + /** + * Tests the XML catalog by parsing the xmlcatalog.xml file and verifying if the XML namespaces + * in the referenced XSD schema files match the XML namespaces defined in the xmlcatalog.xml file. + * + * @return a list of dynamic tests for each URI in the xmlcatalog.xml file + * @throws IOException if an I/O error occurs while reading the XML catalog file + * @throws ParserConfigurationException if a parser configuration error occurs + * @throws SAXException if a SAX error occurs while parsing the XML catalog file + * @throws XPathExpressionException if an XPath expression error occurs + */ + @TestFactory + public List testXmlCatalog() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException { + // Define the path to the XML catalog file. This is relative to "${basedir}/../schema" in the pom.xml. + String xmlCatalogFilename = "xmlcatalog.xml"; + + // Load the XML catalog file from the classpath + ClassLoader classLoader = getClass().getClassLoader(); + InputStream xmlCatalogStream = classLoader.getResourceAsStream(xmlCatalogFilename); + + // Ensure the XML catalog file is found + Assertions.assertNotNull(xmlCatalogStream, "XML catalog file not found"); + + // Parse the xmlcatalog.xml file + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); // Make the factory namespace-aware + DocumentBuilder builder = factory.newDocumentBuilder(); + Document xmlCatalogDocument = builder.parse(new InputSource(xmlCatalogStream)); + + // Get the XML catalog elements + NodeList xmlCatalogElements = xmlCatalogDocument.getDocumentElement().getChildNodes(); + + // List to hold dynamic tests + List dynamicTests = new ArrayList<>(); + + // Iterate through the XML catalog elements + for (int i = 0; i < xmlCatalogElements.getLength(); i++) { + Node xmlCatalogElement = xmlCatalogElements.item(i); + + // Check if the element is a element, continue if it is not + if (!xmlCatalogElement.getNodeName().equals("uri")) { + continue; + } + + // Get the URI name and the local filename of the XSD schema + String uriNameXmlCtlg = xmlCatalogElement.getAttributes().getNamedItem("name").getTextContent(); + String xsdLocalFilename = xmlCatalogElement.getAttributes().getNamedItem("uri").getTextContent(); + + // Load the XSD schema local file from the classpath + InputStream xsdSchemaFileStream = classLoader.getResourceAsStream(xsdLocalFilename); + Assertions.assertNotNull(xsdSchemaFileStream, "The following file is missing: " + xsdLocalFilename); + + // Parse the XSD schema local file + DocumentBuilderFactory factoryXsd = DocumentBuilderFactory.newInstance(); + factoryXsd.setNamespaceAware(true); // Make the factory namespace-aware + DocumentBuilder builderXsd = factoryXsd.newDocumentBuilder(); + Document xsdDocument = builderXsd.parse(new InputSource(xsdSchemaFileStream)); + + // Create an XPath instance to evaluate the targetNamespace field found in the XSD local schema file + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.setNamespaceContext(new NamespaceContext() { + @Override + public String getNamespaceURI(String prefix) { + // Define the namespace URI for the xs prefix + if ("xs".equals(prefix)) { + return "http://www.w3.org/2001/XMLSchema"; + } + return null; + } + + @Override + public String getPrefix(String namespaceURI) { + // Define the prefix for the namespace URI + if ("http://www.w3.org/2001/XMLSchema".equals(namespaceURI)) { + return "xs"; + } + return null; + } + + @Override + public Iterator getPrefixes(String namespaceURI) { + return null; + } + }); + + // Evaluate the targetNamespace attribute from the XSD document + String targetNamespace = (String) xPath.evaluate("/xs:schema/@targetNamespace", xsdDocument, XPathConstants.STRING); + + // Create a dynamic test for each URI + dynamicTests.add(dynamicTest("Testing if URI namespace from the XML catalog: " + uriNameXmlCtlg + " matches the URI namespace from the local XSD file: " + targetNamespace, () -> { + // Assert if the targetNamespace from the XSD file matches the uriNameXmlCtlg from the XML catalog + Assertions.assertEquals(uriNameXmlCtlg, targetNamespace, "The namespace " + uriNameXmlCtlg + " does not match the targetNamespace in file " + xsdLocalFilename); + })); + } + + // Return the list of dynamic tests + return dynamicTests; + } +} diff --git a/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java index 124949218..3df3d6628 100644 --- a/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java @@ -13,55 +13,134 @@ */ package org.cyclonedx.schema; -import org.cyclonedx.CycloneDxSchema; -import org.cyclonedx.parsers.XmlParser; -import org.junit.jupiter.api.DynamicTest; -import org.junit.jupiter.api.TestFactory; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.ArrayList; import java.util.Collection; import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; public class XmlSchemaVerificationTest extends BaseSchemaVerificationTest { + private static final Schema VERSION_10; + private static final Schema VERSION_11; + private static final Schema VERSION_12; + private static final Schema VERSION_13; + private static final Schema VERSION_14; + private static final Schema VERSION_15; + + static { + try { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "file"); + ClassLoader cl = XmlSchemaVerificationTest.class.getClassLoader(); + // Override the `schemaLocation` property in the file + factory.setProperty( + "http://apache.org/xml/properties/schema/external-schemaLocation", + "http://cyclonedx.org/schema/spdx spdx.xsd"); + VERSION_10 = factory.newSchema(cl.getResource("bom-1.0.xsd")); + VERSION_11 = factory.newSchema(cl.getResource("bom-1.1.xsd")); + VERSION_12 = factory.newSchema(cl.getResource("bom-1.2.xsd")); + VERSION_13 = factory.newSchema(cl.getResource("bom-1.3.xsd")); + VERSION_14 = factory.newSchema(cl.getResource("bom-1.4.xsd")); + VERSION_15 = factory.newSchema(cl.getResource("bom-1.5.xsd")); + } catch (SAXException e) { + throw new IllegalStateException(e); + } + } + + /** + * Generates a collection of dynamic tests based on the available XML files. + * + * @return Collection a collection of dynamic tests + * @throws Exception if an error occurs during the generation of the dynamic tests + */ @TestFactory Collection dynamicTestsWithCollection() throws Exception { - final List files = getAllResources(); + final List resources = getAllResources(); final List dynamicTests = new ArrayList<>(); - for (final String file: files) { - if (file.endsWith(".xml")) { - final CycloneDxSchema.Version schemaVersion; - if (file.endsWith("-1.0.xml")) { - schemaVersion = CycloneDxSchema.Version.VERSION_10; - } else if (file.endsWith("-1.1.xml")) { - schemaVersion = CycloneDxSchema.Version.VERSION_11; - } else if (file.endsWith("-1.2.xml")) { - schemaVersion = CycloneDxSchema.Version.VERSION_12; - } else if (file.endsWith("-1.3.xml")) { - schemaVersion = CycloneDxSchema.Version.VERSION_13; - } else if (file.endsWith("-1.4.xml")) { - schemaVersion = CycloneDxSchema.Version.VERSION_14; - } else { - schemaVersion = null; - } - if (file.startsWith("valid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( - isValid(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); - } else if (file.startsWith("invalid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( - isValid(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); + for (final String resource : resources) { + String resourceName = StringUtils.substringAfterLast(resource, "/"); + if (resourceName.endsWith(".xml")) { + Schema schema = getSchema(resourceName); + if (schema != null) { + if (resourceName.startsWith("valid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertTrue(isValid(schema, resource), resource))); + } else if (resourceName.startsWith("invalid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertFalse(isValid(schema, resource), resource))); + } } } } return dynamicTests; } - private boolean isValid(CycloneDxSchema.Version version, String resource) throws Exception { - final File file = new File(this.getClass().getResource(resource).getFile()); - final XmlParser parser = new XmlParser(); - return parser.isValid(file, version); + /** + * Validates the given XML file against the specified CycloneDX schema version. + * + * @param schema the CycloneDX schema to validate against + * @param resource the path to the XML file to be validated + * @return boolean true if the XML file is valid according to the specified schema version, false otherwise + * @throws Exception if an error occurs during the validation process + */ + private boolean isValid(Schema schema, String resource) throws Exception { + Validator validator = schema.newValidator(); + validator.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + }); + try { + validator.validate(new StreamSource(getClass().getClassLoader().getResourceAsStream(resource))); + } catch (SAXParseException e) { + return false; + } + return true; + } + + private Schema getSchema(String resourceName) { + if (resourceName.endsWith("-1.0.xml")) { + return VERSION_10; + } + if (resourceName.endsWith("-1.1.xml")) { + return VERSION_11; + } + if (resourceName.endsWith("-1.2.xml")) { + return VERSION_12; + } + if (resourceName.endsWith("-1.3.xml")) { + return VERSION_13; + } + if (resourceName.endsWith("-1.4.xml")) { + return VERSION_14; + } + if (resourceName.endsWith("-1.5.xml")) { + return VERSION_15; + } + return null; } } diff --git a/tools/src/test/js/json-schema-functional-tests.js b/tools/src/test/js/json-schema-functional-tests.js index b165e65ed..e2b849238 100644 --- a/tools/src/test/js/json-schema-functional-tests.js +++ b/tools/src/test/js/json-schema-functional-tests.js @@ -55,9 +55,10 @@ const ajv = new Ajv({ strict: false, validateFormats: true, addUsedSchema: false, + loadSchema: (uri) => { throw new Error(`Remote schemas are disabled: ${uri}`) }, schemas: { 'http://cyclonedx.org/schema/spdx.schema.json': spdxSchema, - 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema + 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema, } }); addFormats(ajv) @@ -113,4 +114,4 @@ for (const file of globSync(join(testdataDir, 'invalid-*.json'))) { // Exit statuses should be in the range 0 to 254. // The status 0 is used to terminate the program successfully. -process.exitCode = Math.min(errCnt, 254) \ No newline at end of file +process.exitCode = Math.min(errCnt, 254) diff --git a/tools/src/test/js/json-schema-lint-tests.js b/tools/src/test/js/json-schema-lint-tests.js index 2afd4bcbc..7d35972b0 100644 --- a/tools/src/test/js/json-schema-lint-tests.js +++ b/tools/src/test/js/json-schema-lint-tests.js @@ -49,9 +49,12 @@ function getAjv(strict) { validateFormats: true, allowMatchingProperties: true, addUsedSchema: false, + allowUnionTypes: false, + keywords: ["meta:enum"], + loadSchema: (uri) => { throw new Error(`Remote schemas are disabled: ${uri}`) }, schemas: { 'http://cyclonedx.org/schema/spdx.schema.json': spdxSchema, - 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema + 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema, } }); addFormats(ajv) @@ -110,4 +113,4 @@ for (const bomSchemaFile of bomSchemas) { // Exit statuses should be in the range 0 to 254. // The status 0 is used to terminate the program successfully. -process.exitCode = Math.min(errCnt, 254) \ No newline at end of file +process.exitCode = Math.min(errCnt, 254) diff --git a/tools/src/test/js/package.json b/tools/src/test/js/package.json index 429aeb361..dc9b46d9c 100644 --- a/tools/src/test/js/package.json +++ b/tools/src/test/js/package.json @@ -2,22 +2,22 @@ "private": true, "type": "module", "engines": { - "node": ">=18.3" + "node": ">=20.0" }, "dependencies": { "ajv": "^8.12.0", - "ajv-formats": "^2.1.1", + "ajv-formats": "^3.0.1", "ajv-formats-draft2019": "^1.6.1", - "glob": "^10.2.6", + "glob": "^13.0.0", "npm-run-all": "^4.1.5" }, "devDependencies": { "@types/node": ">=18.3" }, "scripts": { - "test": "run-s test:*", + "test": "run-s test:\\*", "test:json-schema-lint": "node -- json-schema-lint-tests.js", - "test:json-schema-functional": "run-s test:json-schema-functional:*", + "test:json-schema-functional": "run-s test:json-schema-functional:\\*", "test:json-schema-functional:1.5": "node -- json-schema-functional-tests.js -v 1.5", "test:json-schema-functional:1.4": "node -- json-schema-functional-tests.js -v 1.4", "test:json-schema-functional:1.3": "node -- json-schema-functional-tests.js -v 1.3", diff --git a/tools/src/test/php/composer.json b/tools/src/test/php/composer.json index 204156ffc..a45baa42e 100644 --- a/tools/src/test/php/composer.json +++ b/tools/src/test/php/composer.json @@ -5,7 +5,7 @@ "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", - "opis/json-schema": "2.3" + "opis/json-schema": "2.6.0" }, "require-dev": { "roave/security-advisories": "dev-latest" @@ -46,4 +46,4 @@ "test": "run all tests", "test:json-schema-lint": "lint JSON schema." } -} \ No newline at end of file +} diff --git a/tools/src/test/php/json-schema-functional-tests.php b/tools/src/test/php/json-schema-functional-tests.php index 4b7e460ec..0e4530a3a 100644 --- a/tools/src/test/php/json-schema-functional-tests.php +++ b/tools/src/test/php/json-schema-functional-tests.php @@ -90,4 +90,4 @@ function validateFile(string $file): ?JsonSchema\Errors\ValidationError // Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used. // The status 0 is used to terminate the program successfully. -exit(min($errCnt, 254)); \ No newline at end of file +exit(min($errCnt, 254)); diff --git a/tools/src/test/php/xml-schema-functional-tests.php b/tools/src/test/php/xml-schema-functional-tests.php index 2646de5c7..e5d4da638 100644 --- a/tools/src/test/php/xml-schema-functional-tests.php +++ b/tools/src/test/php/xml-schema-functional-tests.php @@ -14,6 +14,8 @@ define('TESTSCHEMA_VERSION', getopt('v:')['v']); define('SCHEMA_DIR', realpath(__DIR__ . '/../../../../schema')); define('SCHEMA_FILE', SCHEMA_DIR . '/bom-' . TESTSCHEMA_VERSION . '.xsd'); +define('SPDX_FILE', SCHEMA_DIR . '/spdx.xsd'); + define('TESTDATA_DIR', realpath(__DIR__ . '/../resources/' . TESTSCHEMA_VERSION)); if (empty(TESTSCHEMA_VERSION)) { @@ -58,7 +60,13 @@ function validateFile(string $file): ?LibXMLError throw new Exception("failed loading file: $file" . PHP_EOL . libxml_get_last_error()->message); } - $valid = $doc->schemaValidate(SCHEMA_FILE); + $xsd = str_replace( + 'schemaLocation="http://cyclonedx.org/schema/spdx"', + 'schemaLocation="file://'. htmlspecialchars(SPDX_FILE, ENT_XML1, 'UTF-8') .'"', + file_get_contents(SCHEMA_FILE) + ); + + $valid = $doc->schemaValidateSource($xsd, LIBXML_SCHEMA_CREATE); return $valid ? null : libxml_get_last_error(); @@ -96,4 +104,4 @@ function validateFile(string $file): ?LibXMLError // Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used. // The status 0 is used to terminate the program successfully. -exit(min($errCnt, 254)); \ No newline at end of file +exit(min($errCnt, 254)); diff --git a/tools/src/test/proto/buf_breaking-remote.yaml b/tools/src/test/proto/buf_breaking-remote.yaml new file mode 100644 index 000000000..e3fecdfd4 --- /dev/null +++ b/tools/src/test/proto/buf_breaking-remote.yaml @@ -0,0 +1,6 @@ +# This is the config for "Buf" - a ProtocolBuffer linter/checker/more +# see https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +breaking: # https://buf.build/docs/configuration/v2/buf-yaml#breaking + use: # see https://buf.build/docs/breaking/overview#rules-and-categories + - WIRE \ No newline at end of file diff --git a/tools/src/test/proto/buf_breaking-version.yaml b/tools/src/test/proto/buf_breaking-version.yaml new file mode 100644 index 000000000..535aa1d90 --- /dev/null +++ b/tools/src/test/proto/buf_breaking-version.yaml @@ -0,0 +1,14 @@ +# This is the config for "Buf" - a ProtocolBuffer linter/checker/more +# see https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +breaking: # https://buf.build/docs/configuration/v2/buf-yaml#breaking + use: # see https://buf.build/docs/breaking/overview#rules-and-categories + - WIRE + ignore_only: + # possible breaks are acknowledged for this specific findings only + FIELD_WIRE_COMPATIBLE_CARDINALITY: + # DO NOT ADD NEW VERSIONS HERE WITHOUT CONSULTING THE CDX CORE-WORKING-GROUP + - 'schema/bom-1.5.proto' + FIELD_WIRE_COMPATIBLE_TYPE: + # DO NOT ADD NEW VERSIONS HERE WITHOUT CONSULTING THE CDX CORE-WORKING-GROUP + - 'schema/bom-1.5.proto' diff --git a/tools/src/test/proto/buf_lint.yaml b/tools/src/test/proto/buf_lint.yaml new file mode 100644 index 000000000..d4bedb2d1 --- /dev/null +++ b/tools/src/test/proto/buf_lint.yaml @@ -0,0 +1,31 @@ +# This is the config for "Buf" - a ProtocolBuffer linter/checker/more +# see https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +lint: # https://buf.build/docs/configuration/v2/buf-yaml#lint + use: # see https://buf.build/docs/lint/rules + - STANDARD # https://buf.build/docs/lint/rules/#standard + - COMMENTS # https://buf.build/docs/lint/rules/#comments + except: + # directory/file layout does not match the recommendation/framework of the tool + - DIRECTORY_SAME_PACKAGE # https://buf.build/docs/lint/rules#directory_same_package + - PACKAGE_DIRECTORY_MATCH # https://buf.build/docs/lint/rules#package_lower_snake_case + - FILE_LOWER_SNAKE_CASE # https://buf.build/docs/lint/rules#file_lower_snake_case + # we do not stick to the following best-practices and recommendations: + # (shall be fixed with v2.0 of this very schema) + - PACKAGE_VERSION_SUFFIX # https://buf.build/docs/lint/rules#package_version_suffix + - FIELD_LOWER_SNAKE_CASE # https://buf.build/docs/lint/rules#field_lower_snake_case + # some comments are not required, as they should be self-explanatory from their respective symbol name or the symbol's applied usage + - COMMENT_MESSAGE + - COMMENT_ENUM + - COMMENT_ENUM_VALUE + - COMMENT_ONEOF + ignore_only: + # legacy schema files may NOT stick to the rules -- this is acknowledged. + STANDARD: + - "schema/bom-1.5.proto" + - "schema/bom-1.4.proto" + - "schema/bom-1.3.proto" + COMMENTS: + - "schema/bom-1.5.proto" + - "schema/bom-1.4.proto" + - "schema/bom-1.3.proto" diff --git a/tools/src/test/proto/test.sh b/tools/src/test/proto/test.sh new file mode 100755 index 000000000..1d31f4572 --- /dev/null +++ b/tools/src/test/proto/test.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash +set -ue + +THIS_PATH="$(realpath "$(dirname "$0")")" +ROOT_PATH="$(realpath "${THIS_PATH}/../../../..")" + +# paths relative to $ROOT_PATH +SCHEMA_DIR='schema' +TEST_RES_DIR='tools/src/test/resources' + +REMOTE="https://github.com/${GITHUB_REPOSITORY:-CycloneDX/specification}.git" + +BUF_IMAGE_VERSION='1.58.0' +BUF_IMAGE="bufbuild/buf:${BUF_IMAGE_VERSION}" + +LOG_FORMAT='text' # set to 'json' to see details +if [[ -n "${GITHUB_WORKFLOW:-}" ]] +then + LOG_FORMAT='github-actions' +fi + + +## ---- + + +function prepare () { + docker pull "$BUF_IMAGE" +} + + +function schema-lint () { + echo '> lint schema files' >&2 + + docker run --rm \ + --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ + --volume "${THIS_PATH}/buf_lint.yaml:/workspace/buf.yaml:ro" \ + --workdir '/workspace' \ + "$BUF_IMAGE" \ + lint --path "$SCHEMA_DIR" \ + --error-format "$LOG_FORMAT" + + echo '>> OK.' >&2 +} + + +function schema-breaking-version () { + echo '> test schema for breaking changes against previous version' >&2 + + function compare() { + local NEW="bom-${1}.proto" + local OLD="bom-${2}.proto" + + local NEW_NP OLD_NP + NEW_NP="$(mktemp)" + OLD_NP="$(mktemp)" + + # remove package identifier -> so that the comparison works as expected + sed 's/^package .*//' "${ROOT_PATH}/${SCHEMA_DIR}/${NEW}" > "$NEW_NP" + sed 's/^package .*//' "${ROOT_PATH}/${SCHEMA_DIR}/${OLD}" > "$OLD_NP" + + echo ">> compare new:${NEW} -VS- old:${OLD}" >&2 + # stick with the original path and name of "$NEW", so the reporting makes sense... + docker run --rm \ + --volume "${OLD_NP}:/workspaces/old/${SCHEMA_DIR}/${NEW}:ro" \ + --volume "${NEW_NP}:/workspaces/new/${SCHEMA_DIR}/${NEW}:ro" \ + --volume "${THIS_PATH}/buf_breaking-version.yaml:/workspaces/new/buf.yaml:ro" \ + --workdir '/workspaces/new' \ + "$BUF_IMAGE" \ + breaking \ + --against ../old \ + --error-format "$LOG_FORMAT" + } + + compare '1.5' '1.4' || echo "possible breaks are acknowledged for this specific version only" + compare '1.4' '1.3' + + echo '>> OK.' >&2 +} + +function schema-breaking-remote () { + echo '> test schema for breaking changes against remote' >&2 + + docker run --rm \ + --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ + --volume "${THIS_PATH}/buf_breaking-remote.yaml:/workspace/buf.yaml:ro" \ + --workdir '/workspace' \ + "$BUF_IMAGE" \ + breaking --path "$SCHEMA_DIR" \ + --against "$REMOTE" \ + --error-format "$LOG_FORMAT" + + echo '>> OK.' >&2 +} + +function schema-functional () { + echo '> test all examples against the respective schema' >&2 + + function validate() { + local FILE="$1" + local SCHEMA_VERS="$2" + local SCHEMA_FILE="bom-${SCHEMA_VERS}.proto" + local MESSAGE="cyclonedx.v${SCHEMA_VERS/./_}.Bom" + + echo ">> validate $(realpath --relative-to="$PWD" "$FILE") as ${MESSAGE} of ${SCHEMA_FILE}" >&2 + + # this test method is a bare minimum, and it might not detect all kinds of malformed input. + # could be improved by utilizing protoc -- see https://github.com/CycloneDX/specification/pull/385/commits/8db0967c11cb913ac3c7a9a037159338df3f3bd9 + docker run --rm \ + --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ + --volume "${FILE}:/workspace/test_res:ro" \ + --workdir '/workspace' \ + "$BUF_IMAGE" \ + convert "${SCHEMA_DIR}/${SCHEMA_FILE}" \ + --type "$MESSAGE" \ + --from 'test_res#format=txtpb' \ + --to /dev/null + } + + local SCHEMA_VERS + shopt -s globstar + for test_res in "$ROOT_PATH"/"$TEST_RES_DIR"/*/valid-*.textproto + do + SCHEMA_VERS="$(basename "$(dirname "$test_res")")" + validate "$test_res" "$SCHEMA_VERS" + done + + echo '>> OK.' >&2 +} + + +## ---- + + +case "${1:-all}" in + 'schema-lint') + prepare + schema-lint + ;; + 'schema-breaking-version') + prepare + schema-breaking-version + ;; + 'schema-breaking-remote') + prepare + schema-breaking-remote + ;; + 'schema-breaking') + prepare + schema-breaking-version + schema-breaking-remote + ;; + 'schema-functional') + prepare + schema-functional + ;; + 'all') + # all the above + prepare + schema-lint + schema-breaking-version + schema-breaking-remote + schema-functional + ;; + *) + echo 'unexpected argument. known arguments:' \ + 'schema-lint,schema-breaking-version,schema-breaking-remote,schema-breaking,schema-functional,all' \ + >&2 + exit 1 + ;; +esac diff --git a/tools/src/test/resources/1.5/invalid-license-id-count-1.5.xml b/tools/src/test/resources/1.5/invalid-license-id-count-1.5.xml index ecb0f870c..dee671201 100644 --- a/tools/src/test/resources/1.5/invalid-license-id-count-1.5.xml +++ b/tools/src/test/resources/1.5/invalid-license-id-count-1.5.xml @@ -16,9 +16,9 @@ - Apache-2 + MIT - Apache-2 + MIT pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar diff --git a/tools/src/test/resources/1.5/valid-annotation-1.5.textproto b/tools/src/test/resources/1.5/valid-annotation-1.5.textproto index 30a2d163b..d44fd91ca 100644 --- a/tools/src/test/resources/1.5/valid-annotation-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-annotation-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-assembly-1.5.textproto b/tools/src/test/resources/1.5/valid-assembly-1.5.textproto index 934857777..80ee6bb56 100644 --- a/tools/src/test/resources/1.5/valid-assembly-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-assembly-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-bom-1.5.json b/tools/src/test/resources/1.5/valid-bom-1.5.json index 3bdbeaa13..23197b9a0 100644 --- a/tools/src/test/resources/1.5/valid-bom-1.5.json +++ b/tools/src/test/resources/1.5/valid-bom-1.5.json @@ -103,7 +103,7 @@ "text": { "contentType": "text/plain", "encoding": "base64", - "content": "License text here" + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" }, "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" } diff --git a/tools/src/test/resources/1.5/valid-bom-1.5.textproto b/tools/src/test/resources/1.5/valid-bom-1.5.textproto index fede993c6..a16e0e266 100644 --- a/tools/src/test/resources/1.5/valid-bom-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-bom-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" @@ -86,7 +89,7 @@ components { text { content_type: "text/plain" encoding: "base64" - value: "License text here" + value: "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" } url: "https://www.apache.org/licenses/LICENSE-2.0.txt" } diff --git a/tools/src/test/resources/1.5/valid-component-hashes-1.5.textproto b/tools/src/test/resources/1.5/valid-component-hashes-1.5.textproto index 7802427e0..67c43c6b3 100644 --- a/tools/src/test/resources/1.5/valid-component-hashes-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-component-hashes-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-component-ref-1.5.textproto b/tools/src/test/resources/1.5/valid-component-ref-1.5.textproto index 6660cd17f..8c16722cc 100644 --- a/tools/src/test/resources/1.5/valid-component-ref-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-component-ref-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-component-swid-1.5.textproto b/tools/src/test/resources/1.5/valid-component-swid-1.5.textproto index 55ee386bf..820eca450 100644 --- a/tools/src/test/resources/1.5/valid-component-swid-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-component-swid-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-component-swid-full-1.5.textproto b/tools/src/test/resources/1.5/valid-component-swid-full-1.5.textproto index d8c827976..fa4926b24 100644 --- a/tools/src/test/resources/1.5/valid-component-swid-full-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-component-swid-full-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-component-types-1.5.textproto b/tools/src/test/resources/1.5/valid-component-types-1.5.textproto index b1edc8ff9..f272b33ad 100644 --- a/tools/src/test/resources/1.5/valid-component-types-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-component-types-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-compositions-1.5.json b/tools/src/test/resources/1.5/valid-compositions-1.5.json index 11c8a0012..74b8712f7 100644 --- a/tools/src/test/resources/1.5/valid-compositions-1.5.json +++ b/tools/src/test/resources/1.5/valid-compositions-1.5.json @@ -29,6 +29,7 @@ ] }, { + "bom-ref": "pkg:maven/acme/library@3.0", "type": "library", "name": "Acme Library", "version": "3.0", diff --git a/tools/src/test/resources/1.5/valid-compositions-1.5.textproto b/tools/src/test/resources/1.5/valid-compositions-1.5.textproto index bc542cf41..678fb5a2d 100644 --- a/tools/src/test/resources/1.5/valid-compositions-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-compositions-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" @@ -25,6 +28,7 @@ components { } components { type: CLASSIFICATION_LIBRARY + bom_ref: "pkg:maven/acme/library@3.0" name: "Acme Library" version: "3.0" purl: "pkg:maven/acme/library@3.0" diff --git a/tools/src/test/resources/1.5/valid-dependency-1.5.textproto b/tools/src/test/resources/1.5/valid-dependency-1.5.textproto index ea61f1968..8730e4daf 100644 --- a/tools/src/test/resources/1.5/valid-dependency-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-dependency-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-empty-components-1.5.textproto b/tools/src/test/resources/1.5/valid-empty-components-1.5.textproto index fbb782f3d..ebdc87115 100644 --- a/tools/src/test/resources/1.5/valid-empty-components-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-empty-components-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-evidence-1.5.textproto b/tools/src/test/resources/1.5/valid-evidence-1.5.textproto index 663f66df5..c9634bf5e 100644 --- a/tools/src/test/resources/1.5/valid-evidence-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-evidence-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + # proto-file: bom-1.5.proto # proto-message: Bom diff --git a/tools/src/test/resources/1.5/valid-external-reference-1.5.textproto b/tools/src/test/resources/1.5/valid-external-reference-1.5.textproto index 6ea87fc8c..06533c202 100644 --- a/tools/src/test/resources/1.5/valid-external-reference-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-external-reference-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-formulation-1.5.textproto b/tools/src/test/resources/1.5/valid-formulation-1.5.textproto index b7619428d..0ee698e55 100644 --- a/tools/src/test/resources/1.5/valid-formulation-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-formulation-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-license-expression-1.5.textproto b/tools/src/test/resources/1.5/valid-license-expression-1.5.textproto index d09924f97..2b4ad712b 100644 --- a/tools/src/test/resources/1.5/valid-license-expression-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-license-expression-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-license-id-1.5.textproto b/tools/src/test/resources/1.5/valid-license-id-1.5.textproto index 105b5a236..4f1dd332c 100644 --- a/tools/src/test/resources/1.5/valid-license-id-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-license-id-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-license-licensing-1.5.textproto b/tools/src/test/resources/1.5/valid-license-licensing-1.5.textproto index 490bb6768..e6e59c172 100644 --- a/tools/src/test/resources/1.5/valid-license-licensing-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-license-licensing-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-license-name-1.5.textproto b/tools/src/test/resources/1.5/valid-license-name-1.5.textproto index e77390bf5..8d0329ea3 100644 --- a/tools/src/test/resources/1.5/valid-license-name-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-license-name-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.json b/tools/src/test/resources/1.5/valid-machine-learning-1.5.json index 59dc3ceef..f16696aff 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.json +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.json @@ -60,16 +60,20 @@ }, "considerations": { "users": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Data scientists and ML researchers" ], "useCases": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Text-to-image generation for creative applications" ], "technicalLimitations": [ - "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?", + "Limited performance on non-photographic styles" ], "performanceTradeoffs": [ - "What are the known tradeoffs in accuracy/performance of the model?" + "What are the known tradeoffs in accuracy/performance of the model?", + "Higher resolution output requires more computational resources" ], "ethicalConsiderations": [ { @@ -85,7 +89,17 @@ "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } ] - } + }, + "properties": [ + { + "name": "modelcard:custom-property", + "value": "custom-value" + }, + { + "name": "modelcard:another-custom-property", + "value": "another-custom-value" + } + ] } } ] diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto b/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto index 0bb04b765..a7e6e0d38 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" @@ -45,9 +48,13 @@ components { } considerations: { users: "Who are the intended users of the model?" + users: "Data scientists and ML researchers" useCases: "Who are the intended users of the model?" + useCases: "Text-to-image generation for creative applications" technicalLimitations: "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + technicalLimitations: "Limited performance on non-photographic styles" performanceTradeoffs: "What are the known tradeoffs in accuracy/performance of the model?" + performanceTradeoffs: "Higher resolution output requires more computational resources" ethicalConsiderations: { name: "The name of the risk" mitigationStrategy: "Strategy used to address this risk" @@ -59,5 +66,13 @@ components { mitigationStrategy: "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } } + properties: { + name: "modelcard:custom-property" + value: "custom-value" + } + properties: { + name: "modelcard:another-custom-property" + value: "another-custom-value" + } } } diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml b/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml index 7c541ecb8..6756ccb7f 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml @@ -61,15 +61,19 @@ Who are the intended users of the model? + Data scientists and ML researchers Who are the intended users of the model? + Text-to-image generation for creative applications What are the known technical limitations of the model? + Limited performance on non-photographic styles What are the known tradeoffs in accuracy/performance of the model? + Higher resolution output requires more computational resources @@ -86,6 +90,10 @@ + + custom-value + another-custom-value + diff --git a/tools/src/test/resources/1.5/valid-metadata-author-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-author-1.5.textproto index effa2fafa..dc3561fa2 100644 --- a/tools/src/test/resources/1.5/valid-metadata-author-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-author-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-license-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-license-1.5.textproto index 5c0535934..7bc58ba2b 100644 --- a/tools/src/test/resources/1.5/valid-metadata-license-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-license-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-lifecycle-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-lifecycle-1.5.textproto index 48b7aaea1..2344c331a 100644 --- a/tools/src/test/resources/1.5/valid-metadata-lifecycle-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-lifecycle-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-manufacture-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-manufacture-1.5.textproto index 55bcc6dcd..921da16cf 100644 --- a/tools/src/test/resources/1.5/valid-metadata-manufacture-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-manufacture-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-supplier-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-supplier-1.5.textproto index 6986b7f62..dd5068d91 100644 --- a/tools/src/test/resources/1.5/valid-metadata-supplier-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-supplier-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-timestamp-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-timestamp-1.5.textproto index f93c59067..0a0ab8ecb 100644 --- a/tools/src/test/resources/1.5/valid-metadata-timestamp-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-timestamp-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-tool-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-tool-1.5.textproto index a8b428201..4f8c083e1 100644 --- a/tools/src/test/resources/1.5/valid-metadata-tool-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-tool-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-metadata-tool-deprecated-1.5.textproto b/tools/src/test/resources/1.5/valid-metadata-tool-deprecated-1.5.textproto index 7c3d0cb08..7f4a7c243 100644 --- a/tools/src/test/resources/1.5/valid-metadata-tool-deprecated-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-metadata-tool-deprecated-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-minimal-viable-1.5.textproto b/tools/src/test/resources/1.5/valid-minimal-viable-1.5.textproto index 387e40c7f..4754d0d2f 100644 --- a/tools/src/test/resources/1.5/valid-minimal-viable-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-minimal-viable-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-patch-1.5.textproto b/tools/src/test/resources/1.5/valid-patch-1.5.textproto index d3895eccc..4fd6ced57 100644 --- a/tools/src/test/resources/1.5/valid-patch-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-patch-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-properties-1.5.textproto b/tools/src/test/resources/1.5/valid-properties-1.5.textproto index 63d878b59..cbf83d7d0 100644 --- a/tools/src/test/resources/1.5/valid-properties-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-properties-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-release-notes-1.5.textproto b/tools/src/test/resources/1.5/valid-release-notes-1.5.textproto index 0c6c0d40e..dd381c6de 100644 --- a/tools/src/test/resources/1.5/valid-release-notes-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-release-notes-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" @@ -85,7 +88,7 @@ services { url: "http://api.partner.org/swagger" } releaseNotes: { - type: RELEASE_TYPE_MAJOR + type: "major" title: "My new release" featuredImage: "https://example.com/featured_image.png" socialImage: "https://example.com/social_image.png" diff --git a/tools/src/test/resources/1.5/valid-saasbom-1.5.textproto b/tools/src/test/resources/1.5/valid-saasbom-1.5.textproto index cf6fcb970..f0e1fe6e6 100644 --- a/tools/src/test/resources/1.5/valid-saasbom-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-saasbom-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-service-1.5.json b/tools/src/test/resources/1.5/valid-service-1.5.json index c799e9c0e..d59cf884a 100644 --- a/tools/src/test/resources/1.5/valid-service-1.5.json +++ b/tools/src/test/resources/1.5/valid-service-1.5.json @@ -5,7 +5,7 @@ "version": 1, "components": [ { - "bom-ref": "pkg:npm/acme/component@1.0.0", + "bom-ref": "pkg:maven/com.acme/stock-java-client@1.0.12", "type": "library", "publisher": "Acme Inc", "group": "com.acme", diff --git a/tools/src/test/resources/1.5/valid-service-1.5.textproto b/tools/src/test/resources/1.5/valid-service-1.5.textproto index ab0c1c7b8..a296b0599 100644 --- a/tools/src/test/resources/1.5/valid-service-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-service-1.5.textproto @@ -1,9 +1,12 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { type: CLASSIFICATION_LIBRARY - bom_ref: "pkg:npm/acme/component@1.0.0" + bom_ref: "pkg:maven/com.acme/stock-java-client@1.0.12" publisher: "Acme Inc" group: "com.acme" name: "stock-java-client" diff --git a/tools/src/test/resources/1.5/valid-service-empty-objects-1.5.textproto b/tools/src/test/resources/1.5/valid-service-empty-objects-1.5.textproto index 3cbacc90b..342a967e9 100644 --- a/tools/src/test/resources/1.5/valid-service-empty-objects-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-service-empty-objects-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" diff --git a/tools/src/test/resources/1.5/valid-vulnerability-1.5.textproto b/tools/src/test/resources/1.5/valid-vulnerability-1.5.textproto index 3f50d5692..684283133 100644 --- a/tools/src/test/resources/1.5/valid-vulnerability-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-vulnerability-1.5.textproto @@ -1,3 +1,6 @@ +# proto-file: schema/bom-1.5.proto +# proto-message: Bom + spec_version: "1.5" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"