diff --git a/CHANGELOG.md b/CHANGELOG.md index e3dab72..10f2d51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.3.0-beta-2] - 2026-09-01 + +### Fixed + +- An unsupported value in `openapi` / `swagger` no longer discards the whole file: the analysis reported success with zero issues from every rule. The document is now analysed with the closest known grammar. + ## [1.3.0-beta-1] - 2026-08-18 ### Added diff --git a/its/pom.xml b/its/pom.xml index 119f9e5..311f079 100644 --- a/its/pom.xml +++ b/its/pom.xml @@ -5,7 +5,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 ../pom.xml 4.0.0 diff --git a/openapi-checks/pom.xml b/openapi-checks/pom.xml index 7cfac7d..162df78 100644 --- a/openapi-checks/pom.xml +++ b/openapi-checks/pom.xml @@ -5,7 +5,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 ../pom.xml diff --git a/openapi-front-end/pom.xml b/openapi-front-end/pom.xml index 4c3b289..3865c8f 100644 --- a/openapi-front-end/pom.xml +++ b/openapi-front-end/pom.xml @@ -5,7 +5,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 ../pom.xml diff --git a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v2/OpenApi2Grammar.java b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v2/OpenApi2Grammar.java index 5933bb1..5991a58 100644 --- a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v2/OpenApi2Grammar.java +++ b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v2/OpenApi2Grammar.java @@ -67,7 +67,7 @@ public static YamlGrammarBuilder create() { b.setRootRule(ROOT); b.rule(ROOT).is(b.object( - b.mandatoryProperty("swagger", "2.0"), + b.mandatoryProperty("swagger", b.scalar()), b.mandatoryProperty("info", INFO), b.property("host", b.string()), b.property("basePath", b.string()), diff --git a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v3/OpenApi3Grammar.java b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v3/OpenApi3Grammar.java index 38156ed..8112fb4 100644 --- a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v3/OpenApi3Grammar.java +++ b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v3/OpenApi3Grammar.java @@ -83,7 +83,7 @@ public static YamlGrammarBuilder create() { b.setRootRule(ROOT); b.rule(ROOT).is(b.object( - b.mandatoryProperty("openapi", b.firstOf("3.0.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4")), + b.mandatoryProperty("openapi", b.scalar()), b.mandatoryProperty("info", INFO), b.property("servers", b.array(SERVER)), b.mandatoryProperty("paths", PATHS), diff --git a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v31/OpenApi31Grammar.java b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v31/OpenApi31Grammar.java index 74c01ef..051fd25 100644 --- a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v31/OpenApi31Grammar.java +++ b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v31/OpenApi31Grammar.java @@ -89,7 +89,7 @@ public static YamlGrammarBuilder create() { b.setRootRule(ROOT); b.rule(ROOT).is(b.object( - b.mandatoryProperty("openapi", b.firstOf("3.1.0", "3.1.1", "3.1.2")), + b.mandatoryProperty("openapi", b.scalar()), b.mandatoryProperty("info", INFO), b.property("jsonSchemaDialect", b.string()), b.property("servers", b.array(SERVER)), diff --git a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v32/OpenApi32Grammar.java b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v32/OpenApi32Grammar.java index 3fb0e9e..afc9ce3 100644 --- a/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v32/OpenApi32Grammar.java +++ b/openapi-front-end/src/main/java/org/apiaddicts/apitools/dosonarapi/api/v32/OpenApi32Grammar.java @@ -90,7 +90,7 @@ public static YamlGrammarBuilder create() { b.setRootRule(ROOT); b.rule(ROOT).is(b.object( - b.mandatoryProperty("openapi", "3.2.0"), + b.mandatoryProperty("openapi", b.scalar()), b.mandatoryProperty("info", INFO), b.property("$self", b.string()), b.property("jsonSchemaDialect", b.string()), diff --git a/openapi-test-tools/pom.xml b/openapi-test-tools/pom.xml index b6f012d..380027b 100644 --- a/openapi-test-tools/pom.xml +++ b/openapi-test-tools/pom.xml @@ -5,7 +5,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 ../pom.xml diff --git a/pom.xml b/pom.xml index b58cf45..60878a0 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 pom SonarOpenAPI diff --git a/sonar-openapi-plugin/pom.xml b/sonar-openapi-plugin/pom.xml index 0a6a333..c131549 100644 --- a/sonar-openapi-plugin/pom.xml +++ b/sonar-openapi-plugin/pom.xml @@ -5,7 +5,7 @@ org.apiaddicts.apitools.dosonarapi dosonarapi - 1.3.0-beta-1 + 1.3.0-beta-2 ../pom.xml diff --git a/sonar-openapi-plugin/src/main/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiAnalyzer.java b/sonar-openapi-plugin/src/main/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiAnalyzer.java index 5f4fe9d..503c9d6 100644 --- a/sonar-openapi-plugin/src/main/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiAnalyzer.java +++ b/sonar-openapi-plugin/src/main/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiAnalyzer.java @@ -109,24 +109,14 @@ public void scanFiles() { } } - private static boolean isV3Version(JsonNode openapiNode) { - if (openapiNode.isMissing()) return false; - String v = openapiNode.getTokenValue(); - return "3.0.0".equals(v) || "3.0.1".equals(v) || "3.0.2".equals(v) || "3.0.3".equals(v) || "3.0.4".equals(v); - } - - private static boolean isV31Version(JsonNode openapiNode) { - if (openapiNode.isMissing()) return false; - String v = openapiNode.getTokenValue(); - return "3.1.0".equals(v) || "3.1.1".equals(v) || "3.1.2".equals(v); - } + private YamlParser selectParser(JsonNode swaggerNode, JsonNode openapiNode) { + if (!swaggerNode.isMissing()) return OpenApiParser.createV2(configuration); - private YamlParser selectParser(boolean isV2, boolean isV3, boolean isV31, boolean isV32) { - if (isV2) return OpenApiParser.createV2(configuration); - if (isV32) return OpenApiParser.createV32(configuration); - if (isV31) return OpenApiParser.createV31(configuration); - if (isV3) return OpenApiParser.createV3(configuration); - return null; + String version = openapiNode.isMissing() ? null : openapiNode.getTokenValue(); + if (version == null) return OpenApiParser.createV3(configuration); + if (version.startsWith("3.2")) return OpenApiParser.createV32(configuration); + if (version.startsWith("3.1")) return OpenApiParser.createV31(configuration); + return OpenApiParser.createV3(configuration); } private void scanFile(InputFile inputFile) { @@ -136,13 +126,11 @@ private void scanFile(InputFile inputFile) { String content = getContent(inputFile); if (!content.contains("swagger") && !content.contains("openapi")) return; JsonNode rootNode = OpenApiParser.createGeneric(configuration).parse(content); - boolean isV2 = !rootNode.at("/swagger").isMissing(); + JsonNode swaggerNode = rootNode.at("/swagger"); JsonNode openapiNode = rootNode.at("/openapi"); - boolean isV3 = isV3Version(openapiNode); - boolean isV31 = isV31Version(openapiNode); - boolean isV32 = !openapiNode.isMissing() && openapiNode.getTokenValue().equals("3.2.0"); - YamlParser targetParser = selectParser(isV2, isV3, isV31, isV32); - if (targetParser == null) return; + + if (swaggerNode.isMissing() && openapiNode.isMissing()) return; + YamlParser targetParser = selectParser(swaggerNode, openapiNode); visitorContext = new OpenApiVisitorContext(targetParser.parse(content), targetParser.getIssues(), openApiFile); saveMeasures(inputFile, visitorContext); diff --git a/sonar-openapi-plugin/src/test/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiScannerSensorTest.java b/sonar-openapi-plugin/src/test/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiScannerSensorTest.java index 8e87685..12a79c1 100644 --- a/sonar-openapi-plugin/src/test/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiScannerSensorTest.java +++ b/sonar-openapi-plugin/src/test/java/org/apiaddicts/apitools/dosonarapi/plugin/OpenApiScannerSensorTest.java @@ -250,6 +250,32 @@ public void test_folder() { System.out.println(errorFiles); } + @Test + public void unsupported_openapi_version_still_runs_rules() { + activeRules = (new ActiveRulesBuilder()) + .create(RuleKey.of(CheckList.YAML_REPOSITORY_KEY, "PathMaskerading")) + .activate() + .build(); + + inputFile("unsupported-openapi-version.yaml"); + sensor().execute(context); + + assertThat(context.allIssues()).hasSize(1); + } + + @Test + public void unsupported_swagger_version_still_runs_rules() { + activeRules = (new ActiveRulesBuilder()) + .create(RuleKey.of(CheckList.YAML_REPOSITORY_KEY, "PathMaskerading")) + .activate() + .build(); + + inputFile("unsupported-swagger-version.yaml"); + sensor().execute(context); + + assertThat(context.allIssues()).hasSize(1); + } + @Test public void cancelled_analysis() { InputFile inputFile = inputFile("file1.yaml"); diff --git a/sonar-openapi-plugin/src/test/resources/sensor/unsupported-openapi-version.yaml b/sonar-openapi-plugin/src/test/resources/sensor/unsupported-openapi-version.yaml new file mode 100644 index 0000000..54ac061 --- /dev/null +++ b/sonar-openapi-plugin/src/test/resources/sensor/unsupported-openapi-version.yaml @@ -0,0 +1,29 @@ +openapi: "1.1.3" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets/{petId}: + get: + responses: + '200': + description: success + content: + 'application/json': + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + /pets/1234: + get: + responses: + '200': + description: success + content: + 'application/json': + schema: + $ref: '#/components/schemas/Pet' +components: + schemas: + Pet: + type: object diff --git a/sonar-openapi-plugin/src/test/resources/sensor/unsupported-swagger-version.yaml b/sonar-openapi-plugin/src/test/resources/sensor/unsupported-swagger-version.yaml new file mode 100644 index 0000000..7313414 --- /dev/null +++ b/sonar-openapi-plugin/src/test/resources/sensor/unsupported-swagger-version.yaml @@ -0,0 +1,24 @@ +swagger: "1.2" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets/{petId}: + get: + responses: + '200': + description: success + schema: + type: array + items: + $ref: '#/definitions/Pet' + /pets/1234: + get: + responses: + '200': + description: success + schema: + $ref: '#/definitions/Pet' +definitions: + Pet: + type: object