From e6977d7c2018902262b2e5f09daece495f72c9ee Mon Sep 17 00:00:00 2001 From: Martin Goldhahn Date: Sat, 6 Jan 2024 23:01:02 +0100 Subject: [PATCH 1/6] fixed issue 2034, added test case for issue --- .../swagger/v3/parser/reference/Visitor.java | 12 ++--- .../parser/test/OpenAPIV31ParserUriTest.java | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserUriTest.java diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/Visitor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/Visitor.java index d41b21cc22..7e1f26375d 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/Visitor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/Visitor.java @@ -62,14 +62,14 @@ public interface Visitor { Example visitExample(Example example); - default String readFile(String uri) throws Exception { - try (InputStream inputStream = new FileInputStream(uri)) { + default String readFile(String path) throws Exception { + try (InputStream inputStream = new FileInputStream(path)) { return IOUtils.toString(inputStream, UTF_8); } } - default String readClasspath(String uri) throws Exception { - return ClasspathHelper.loadFileFromClasspath(uri); + default String readClasspath(String classPath) throws Exception { + return ClasspathHelper.loadFileFromClasspath(classPath); } default String readHttp(String uri, List auths) throws Exception { return RemoteUrl.urlToString(uri, auths); @@ -81,9 +81,9 @@ default String readURI(String absoluteUri, List auths) throw if (resolved.getScheme().startsWith("http")) { return readHttp(absoluteUri, auths); } else if (resolved.getScheme().startsWith("file")) { - return readFile(absoluteUri); + return readFile(resolved.getPath()); } else if (resolved.getScheme().startsWith("classpath")) { - return readClasspath(absoluteUri); + return readClasspath(resolved.getPath()); } } // If no matches exists, try file diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserUriTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserUriTest.java new file mode 100644 index 0000000000..5452bb2bf8 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserUriTest.java @@ -0,0 +1,52 @@ +package io.swagger.v3.parser.test; + + +import io.swagger.v3.parser.OpenAPIV3Parser; +import io.swagger.v3.parser.core.models.ParseOptions; +import io.swagger.v3.parser.core.models.SwaggerParseResult; +import org.apache.commons.io.IOUtils; +import org.testng.annotations.Test; + +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +/** + * Test parsing classpath and file URIs. + * Before the fix, an exception is logged as an error and a message containing "(No such file or directory)" + * is added to the parse result. + * This test checks for the absence of the message. + */ +public class OpenAPIV31ParserUriTest { + @Test + public void resolveFileInput() throws Exception { + URI uri = getClass().getResource("/3.1.0/basic.yaml").toURI(); + assertEquals(uri.getScheme(), "file"); + String uriString = uri.toString(); + ParseOptions options = new ParseOptions(); + options.setResolve(true); + SwaggerParseResult result = new OpenAPIV3Parser().readLocation(uriString, null, options); + validateParseResult(result, "(No such file or directory)"); + } + + @Test + public void resolveClasspathInput() throws Exception { + URL url = getClass().getResource("/3.1.0/basic.yaml"); + String content = IOUtils.toString(url, StandardCharsets.UTF_8); + ParseOptions options = new ParseOptions(); + options.setResolve(true); + SwaggerParseResult result = new OpenAPIV3Parser().readContents(content, null, options, "classpath:/3.1.0/basic.yaml"); + validateParseResult(result, "Could not find classpath:/3.1.0/basic.yaml"); + } + + private static void validateParseResult(SwaggerParseResult result, String checkForMessage) { + String noSuchFileMessage = result.getMessages().stream() + .filter(message -> message.contains(checkForMessage)) + .findFirst() + .orElse(null); + assertNull(noSuchFileMessage); + } +} From 5b91535cf430fb5bc434f609a9555c36fc68f26e Mon Sep 17 00:00:00 2001 From: frantuma Date: Thu, 18 Jan 2024 12:57:45 +0100 Subject: [PATCH 2/6] update dependencies --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 25657340de..e65b7f388a 100644 --- a/pom.xml +++ b/pom.xml @@ -413,19 +413,19 @@ 8 2.2 - 1.0.68 - 2.15.0 + 1.0.69 + 2.15.1 2.0.9 - 2.2.19 + 2.2.20 1.6.12 4.13.2 - 7.8.0 + 7.9.0 1.49 2.35.1 3.2.2 - 3.13.0 - 2.15.3 - 2.15.3 + 3.14.0 + 2.16.1 + 2.16.1 UTF-8 https://oss.sonatype.org/content/repositories/snapshots/ From 3a31c1629bd27c3e1a8d5975ba8e1d55b0ef330a Mon Sep 17 00:00:00 2001 From: frantuma Date: Thu, 18 Jan 2024 12:17:29 +0000 Subject: [PATCH 3/6] prepare release 2.1.20 --- README.md | 2 +- modules/swagger-parser-cli/pom.xml | 4 ++-- modules/swagger-parser-core/pom.xml | 2 +- modules/swagger-parser-safe-url-resolver/pom.xml | 2 +- modules/swagger-parser-v2-converter/pom.xml | 2 +- modules/swagger-parser-v3/pom.xml | 2 +- modules/swagger-parser/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 50142f67ca..15faffe42d 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ You can include this library from Sonatype OSS for SNAPSHOTS, or Maven central f io.swagger.parser.v3 swagger-parser - 2.1.19 + 2.1.20 ``` diff --git a/modules/swagger-parser-cli/pom.xml b/modules/swagger-parser-cli/pom.xml index c8372842fd..886493969a 100644 --- a/modules/swagger-parser-cli/pom.xml +++ b/modules/swagger-parser-cli/pom.xml @@ -5,7 +5,7 @@ swagger-parser-project io.swagger.parser.v3 - 2.1.20-SNAPSHOT + 2.1.20 ../.. 4.0.0 @@ -91,7 +91,7 @@ io.swagger.parser.v3 swagger-parser-v3 - 2.1.20-SNAPSHOT + 2.1.20 compile diff --git a/modules/swagger-parser-core/pom.xml b/modules/swagger-parser-core/pom.xml index 27534b5463..be7bea7d32 100644 --- a/modules/swagger-parser-core/pom.xml +++ b/modules/swagger-parser-core/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 ../.. 4.0.0 diff --git a/modules/swagger-parser-safe-url-resolver/pom.xml b/modules/swagger-parser-safe-url-resolver/pom.xml index ec1e1be6c1..a78f79d923 100644 --- a/modules/swagger-parser-safe-url-resolver/pom.xml +++ b/modules/swagger-parser-safe-url-resolver/pom.xml @@ -6,7 +6,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 ../../pom.xml diff --git a/modules/swagger-parser-v2-converter/pom.xml b/modules/swagger-parser-v2-converter/pom.xml index 300c854307..44d8697aeb 100644 --- a/modules/swagger-parser-v2-converter/pom.xml +++ b/modules/swagger-parser-v2-converter/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 ../.. 4.0.0 diff --git a/modules/swagger-parser-v3/pom.xml b/modules/swagger-parser-v3/pom.xml index dec8eefea5..2781ab5102 100644 --- a/modules/swagger-parser-v3/pom.xml +++ b/modules/swagger-parser-v3/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 ../.. 4.0.0 diff --git a/modules/swagger-parser/pom.xml b/modules/swagger-parser/pom.xml index 33467e2108..6cfb99e9c5 100644 --- a/modules/swagger-parser/pom.xml +++ b/modules/swagger-parser/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 ../.. 4.0.0 diff --git a/pom.xml b/pom.xml index e65b7f388a..0a908e426a 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 io.swagger.parser.v3 swagger-parser-project - 2.1.20-SNAPSHOT + 2.1.20 pom swagger-parser-project From 00d2c5cd152d7475fbbf100e1b52ace0abd103ea Mon Sep 17 00:00:00 2001 From: frantuma Date: Thu, 18 Jan 2024 12:37:28 +0000 Subject: [PATCH 4/6] bump snapshot 2.1.21-SNAPSHOT --- modules/swagger-parser-cli/pom.xml | 4 ++-- modules/swagger-parser-core/pom.xml | 2 +- modules/swagger-parser-safe-url-resolver/pom.xml | 2 +- modules/swagger-parser-v2-converter/pom.xml | 2 +- modules/swagger-parser-v3/pom.xml | 2 +- modules/swagger-parser/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/swagger-parser-cli/pom.xml b/modules/swagger-parser-cli/pom.xml index 886493969a..87f842748e 100644 --- a/modules/swagger-parser-cli/pom.xml +++ b/modules/swagger-parser-cli/pom.xml @@ -5,7 +5,7 @@ swagger-parser-project io.swagger.parser.v3 - 2.1.20 + 2.1.21-SNAPSHOT ../.. 4.0.0 @@ -91,7 +91,7 @@ io.swagger.parser.v3 swagger-parser-v3 - 2.1.20 + 2.1.21-SNAPSHOT compile diff --git a/modules/swagger-parser-core/pom.xml b/modules/swagger-parser-core/pom.xml index be7bea7d32..3af87e6b2b 100644 --- a/modules/swagger-parser-core/pom.xml +++ b/modules/swagger-parser-core/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT ../.. 4.0.0 diff --git a/modules/swagger-parser-safe-url-resolver/pom.xml b/modules/swagger-parser-safe-url-resolver/pom.xml index a78f79d923..65b60afa05 100644 --- a/modules/swagger-parser-safe-url-resolver/pom.xml +++ b/modules/swagger-parser-safe-url-resolver/pom.xml @@ -6,7 +6,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT ../../pom.xml diff --git a/modules/swagger-parser-v2-converter/pom.xml b/modules/swagger-parser-v2-converter/pom.xml index 44d8697aeb..9e39087e6b 100644 --- a/modules/swagger-parser-v2-converter/pom.xml +++ b/modules/swagger-parser-v2-converter/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT ../.. 4.0.0 diff --git a/modules/swagger-parser-v3/pom.xml b/modules/swagger-parser-v3/pom.xml index 2781ab5102..c0e23c8aa4 100644 --- a/modules/swagger-parser-v3/pom.xml +++ b/modules/swagger-parser-v3/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT ../.. 4.0.0 diff --git a/modules/swagger-parser/pom.xml b/modules/swagger-parser/pom.xml index 6cfb99e9c5..d68a137eef 100644 --- a/modules/swagger-parser/pom.xml +++ b/modules/swagger-parser/pom.xml @@ -3,7 +3,7 @@ io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT ../.. 4.0.0 diff --git a/pom.xml b/pom.xml index 0a908e426a..36849c6847 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 io.swagger.parser.v3 swagger-parser-project - 2.1.20 + 2.1.21-SNAPSHOT pom swagger-parser-project From 25381a3ee1c738bc39a915a560200ee376b28381 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 22 Jan 2024 22:12:56 -0500 Subject: [PATCH 5/6] [Issue 2048] NullPointerException: Cannot invoke "io.swagger.v3.oas.models.media.Schema.get$ref()" because "items" is null #2048 PR for: ``` Caused by: java.lang.NullPointerException: Cannot invoke "io.swagger.v3.oas.models.media.Schema.get$ref()" because "items" is null at io.swagger.v3.parser.processors.SchemaProcessor.processArraySchema(SchemaProcessor.java:218) at io.swagger.v3.parser.processors.SchemaProcessor.processSchemaType(SchemaProcessor.java:69) at io.swagger.v3.parser.processors.SchemaProcessor.processPropertySchema(SchemaProcessor.java:139) at io.swagger.v3.parser.processors.SchemaProcessor.processSchemaType(SchemaProcessor.java:76) at io.swagger.v3.parser.processors.SchemaProcessor.processSchema(SchemaProcessor.java:61) at io.swagger.v3.parser.processors.ComponentsProcessor.processSchemas(ComponentsProcessor.java:231) at io.swagger.v3.parser.processors.ComponentsProcessor.processComponents(ComponentsProcessor.java:145) at io.swagger.v3.parser.OpenAPIResolver.resolve(OpenAPIResolver.java:73) ... ``` The above is from a log and I don't have a easy way to create a reproducer. You'll notice though that most call sites of `ArraySchema.getItems()` in this repo do check for a null result value, but not _all_ call sites. --- .../io/swagger/v3/parser/processors/SchemaProcessor.java | 5 ++++- .../io/swagger/v3/parser/util/InlineModelResolver.java | 3 +++ .../io/swagger/v3/parser/test/OpenAPIResolverTest.java | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index 9dbee9987a..6eab18cf36 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -65,6 +65,9 @@ public void processSchema(Schema schema) { public void processSchemaType(Schema schema){ + if (schema == null) { + return; + } if (schema instanceof ArraySchema) { processArraySchema((ArraySchema) schema); } @@ -215,7 +218,7 @@ private void changeDiscriminatorMapping(ComposedSchema composedSchema, String ol public void processArraySchema(ArraySchema arraySchema) { final Schema items = arraySchema.getItems(); - if (items.get$ref() != null) { + if (items != null && items.get$ref() != null) { processReferenceSchema(items); }else{ processSchemaType(items); diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java index 741874873c..045697168e 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java @@ -735,6 +735,9 @@ public void copyVendorExtensions(Schema source, Schema target) { } private boolean isObjectSchema(Schema schema) { + if (schema == null) { + return false; + } return schema instanceof ObjectSchema || "object".equalsIgnoreCase(schema.getType()) || (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty() diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java index f600b6fa4d..5820e23775 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java @@ -1464,4 +1464,13 @@ private static int getDynamicPort() { return new Random().ints(50000, 60000).findFirst().getAsInt(); } + @Test + public void testResolveArraySchemaItemsNullPointerException() { + final ParseOptions options = new ParseOptions(); + options.setResolve(true); + final String actualLocation = "C:/Users/ggregory/git/r/api-gateway/ais-swagger-test-fixtures/src/test/resources/APIs-guru/openapi-directory-master/APIs/clearblade.com/3.0/swagger.yaml"; + final OpenAPI output = new OpenAPIV3Parser().read(actualLocation, null, options); + new OpenAPIResolver(output, null, actualLocation).resolve(); + } + } From 19c65e72146d390dc2eed90d3e59589ab01ee7b4 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 22 Jan 2024 17:22:07 -0500 Subject: [PATCH 6/6] [Issue 2046] NPE in OpenAPIV3Parser.read(String, List, ParseOptions) --- .../swagger/parser/test/V2ConverterTest.java | 42 +++++++++++++++++++ .../io/swagger/v3/parser/OpenAPIV3Parser.java | 6 ++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java index 41425bca06..b185a7c944 100644 --- a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java +++ b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java @@ -14,10 +14,14 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.tags.Tag; +import io.swagger.v3.parser.OpenAPIV3Parser; import io.swagger.v3.parser.converter.SwaggerConverter; +import io.swagger.v3.parser.core.extensions.SwaggerParserExtension; import io.swagger.v3.parser.core.models.AuthorizationValue; import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.core.models.SwaggerParseResult; + +import org.testng.Assert; import org.testng.annotations.Test; import java.io.IOException; @@ -923,4 +927,42 @@ public void testConvertFormDataAsObjectSchema() throws Exception { assertEquals(companiesSchema.getClass(), ObjectSchema.class); } + + /** + * A clone (almost) of {@link OpenAPIV3Parser#readContents(String, List, ParseOptions)}. + */ + private OpenAPI read(String location, List auths, ParseOptions resolve, final List parserExtensions) { + if (location == null) { + return null; + } + SwaggerParseResult parsed; + for (SwaggerParserExtension extension : parserExtensions) { + parsed = extension.readLocation(location, auths, resolve); + if (parsed.getMessages() != null) { + for (String message : parsed.getMessages()) { + // LOGGER.info("{}: {}", extension, message); + } + } + final OpenAPI result = parsed.getOpenAPI(); + if (result != null) { + return result; + } + } + return null; + } + + /** + * Tests an NPE when bother the old and new parser are on the classpath. The only way to test this is cloning the + * {@link OpenAPIV3Parser#readContents(String, List, ParseOptions)} to see the NPE when we pass in the extentions. Instead of, for example, mocking the call + * to {@link io.swagger.v3.parser.OpenAPIV3Parser.getExtensions()}. + */ + @Test + public void testIssue2046() { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + // This should not throw an NPE: + final OpenAPI openAPI = read("I/do/not/exist/on/the/file/system/I/really/do/not.yaml", null, options, Arrays.asList(new SwaggerConverter())); + Assert.assertNull(openAPI); + } + } diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java index ac3a7f2c41..bcf0af8a4c 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java @@ -122,8 +122,10 @@ public OpenAPI read(String location, List auths, ParseOption SwaggerParseResult parsed; for (SwaggerParserExtension extension : parserExtensions) { parsed = extension.readLocation(location, auths, resolve); - for (String message : parsed.getMessages()) { - LOGGER.info("{}: {}", extension, message); + if (parsed.getMessages() != null) { + for (String message : parsed.getMessages()) { + LOGGER.info("{}: {}", extension, message); + } } final OpenAPI result = parsed.getOpenAPI(); if (result != null) {