diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java b/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java index 74e5649a1..223ed8e71 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/JsonIO.java @@ -24,6 +24,10 @@ public static JsonIO newI return jackson; } + private boolean wrapped(String value, String prefix, String suffix) { + return value.startsWith(prefix) && value.endsWith(suffix); + } + default Object parseValue(String value) { if (value == null || value.isEmpty()) { return null; @@ -32,10 +36,19 @@ default Object parseValue(String value) { String trimmedValue = value.trim(); switch (trimmedValue.charAt(0)) { - case '{': /* JSON Object */ - case '[': /* JSON Array */ - case '-': /* JSON Negative Number */ - case '0': /* JSON Numbers */ + case '{': + case '[': + if (wrapped(trimmedValue, "{", "}") || wrapped(trimmedValue, "[", "]")) { + /* Looks like a JSON Object or Array */ + try { + return fromJson(fromString(trimmedValue, Format.JSON)); + } catch (Exception e) { + IoLogging.logger.unparseableJson(trimmedValue); + } + } + break; + case '-': /* Negative Number */ + case '0': /* Numbers */ case '1': case '2': case '3': @@ -46,11 +59,11 @@ default Object parseValue(String value) { case '8': case '9': try { - return fromJson(fromString(trimmedValue, Format.JSON)); - } catch (Exception e) { + return new BigDecimal(trimmedValue); + } catch (NumberFormatException e) { IoLogging.logger.unparseableJson(trimmedValue); - break; } + break; case 't': return "true".equals(trimmedValue) ? Boolean.TRUE : value; case 'f': diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java index 536fb8834..53009b282 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java @@ -763,4 +763,30 @@ public String getWo() { assertJsonEquals("components.schemas.jackson-property-access.json", Bean.class); } + + @Test + void testExceptionalExampleParsing() throws IOException, JSONException { + @Schema(name = "Bean") + class Bean { + @Schema(example = "{ Looks like object, but invalid }") + public Object property1; + @Schema(example = "{ \"key\": \"object end missing\"") + public Object property2; + @Schema(example = "[ Looks like array, but invalid ]") + public Object property3; + @Schema(example = "[ \"array end missing\"") + public Object property4; + @Schema(example = "trick") // not Boolean.TRUE + public Object property5; + @Schema(example = "fake") // not Boolean.FALSE + public Object property6; + @Schema(example = "1046\n1049\n1051") // not a number + public Object property7; + @Schema(example = "") // empty + public Object property8; + + } + + assertJsonEquals("components.schemas.exceptional-examples.json", Bean.class); + } } diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json new file mode 100644 index 000000000..29892de7f --- /dev/null +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.exceptional-examples.json @@ -0,0 +1,36 @@ +{ + "openapi" : "3.0.3", + "components" : { + "schemas" : { + "Bean" : { + "type" : "object", + "properties" : { + "property1" : { + "example" : "{ Looks like object, but invalid }" + }, + "property2" : { + "example" : "{ \"key\": \"object end missing\"" + }, + "property3" : { + "example" : "[ Looks like array, but invalid ]" + }, + "property4" : { + "example" : "[ \"array end missing\"" + }, + "property5" : { + "example" : "trick" + }, + "property6" : { + "example" : "fake" + }, + "property7" : { + "example" : "1046\n1049\n1051" + }, + "property8" : { + "example" : "" + } + } + } + } + } +}