You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using 4.5.11 of the vertx-openapi library, which off course transitively depends on vertx-json-schema.
Context
I have openapi files that have $refs to separate json schema files (using draft 4 currently), which are provided to the OpenAPIContract::fromContract by way of the additionalContractFiles argument. That's kind of unrelated, but the important detail is that I have an OpenAPI file with a $ref to a schema that defines a tree structure. That tree schema for the sake of simplicity can be reduced to the following to cause an exception:
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
at java.base/java.lang.String.charAt(String.java:693)
at io.vertx.json.schema.impl.JsonRef.resolveUri(JsonRef.java:326)
at io.vertx.json.schema.impl.JsonRef.resolve(JsonRef.java:211)
at io.vertx.json.schema.impl.JsonRef.resolveUri(JsonRef.java:338)
at io.vertx.json.schema.impl.JsonRef.resolve(JsonRef.java:211)
at io.vertx.json.schema.impl.JsonRef.resolveUri(JsonRef.java:338)
at io.vertx.json.schema.impl.JsonRef.resolve(JsonRef.java:211)
at io.vertx.json.schema.impl.SchemaRepositoryImpl.resolve(SchemaRepositoryImpl.java:243)
at io.vertx.openapi.contract.OpenAPIVersion.lambda$resolve$4(OpenAPIVersion.java:110)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$4(ContextImpl.java:192)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
at io.vertx.core.impl.ContextImpl$1.execute(ContextImpl.java:221)
at io.vertx.core.impl.WorkerTask.run(WorkerTask.java:56)
at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:81)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
Do you have a reproducer?
I do not have a reproducer, but the problem is pretty obvious if you look at the JsonRef::resolveUri function. There is no isEmpty check on the path before accessing the first character.
Steps to reproduce
Look at this if statement and try to tell me that there's a guarantee that path will always be nonempty. If you have a $ref: '#', then the parts array is going to initialized as ["#", ""] and you'll run into the exception above at the linked if statement because the second element is empty.
The temporary solution to fix this was to change my ref to $ref: '#/'. It provides the same behavior as the '#' by itself, but just the pound symbol should be supported and I'm not sure why the existing tests aren't triggering the same exception that I'm running into.
Solutions
There seems to be multiple solutions to fix this, but in the end a pound symbol by itself should just trigger anchors.get(prefix); in the end to retrieve the current schema. Both solutions below should result in the same behavior and both changes are to the JsonRef::resolveUri function.
Option 1:
We could make hashPresent set to false when the passed uri is "#".
I take it back, $ref: '#/' is not a solution because it tries to look for a schema at URI <currentSchemaFileUri>#/ in the lookup table, I believe. That works in the initial validation that the schemas are valid according to the json schema specification, but I'm running into another issue when validating json with against the schema with the recursive reference.
The exception I'm getting there is below. Maybe that portion of code relies on the $ref: '#' being used.
io.vertx.json.schema.SchemaException: Unresolved $ref #/: Absolute URI <relevantSchemaUri>#/
Known schemas:
<big list of schemas in the lookup table>
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:200)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:735)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:553)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:204)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:735)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:553)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:204)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:322)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:204)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:352)
at io.vertx.json.schema.impl.SchemaValidatorImpl.validate(SchemaValidatorImpl.java:54)
at io.vertx.openapi.validation.impl.RequestValidatorImpl.validateBody(RequestValidatorImpl.java:156)
at io.vertx.openapi.validation.impl.RequestValidatorImpl.lambda$validate$2(RequestValidatorImpl.java:106)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$5(ContextImpl.java:205)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
at io.vertx.core.impl.ContextImpl$1.execute(ContextImpl.java:221)
at io.vertx.core.impl.WorkerTask.run(WorkerTask.java:56)
at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:81)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
Version
I'm using 4.5.11 of the vertx-openapi library, which off course transitively depends on vertx-json-schema.
Context
I have openapi files that have $refs to separate json schema files (using draft 4 currently), which are provided to the
OpenAPIContract::fromContract
by way of theadditionalContractFiles
argument. That's kind of unrelated, but the important detail is that I have an OpenAPI file with a $ref to a schema that defines a tree structure. That tree schema for the sake of simplicity can be reduced to the following to cause an exception:The exception in question is this:
Do you have a reproducer?
I do not have a reproducer, but the problem is pretty obvious if you look at the
JsonRef::resolveUri
function. There is no isEmpty check on the path before accessing the first character.Steps to reproduce
Look at this if statement and try to tell me that there's a guarantee that path will always be nonempty. If you have a
$ref: '#'
, then the parts array is going to initialized as["#", ""]
and you'll run into the exception above at the linked if statement because the second element is empty.The temporary solution to fix this was to change my ref to
$ref: '#/'
. It provides the same behavior as the '#' by itself, but just the pound symbol should be supported and I'm not sure why the existing tests aren't triggering the same exception that I'm running into.Solutions
There seems to be multiple solutions to fix this, but in the end a pound symbol by itself should just trigger
anchors.get(prefix);
in the end to retrieve the current schema. Both solutions below should result in the same behavior and both changes are to theJsonRef::resolveUri
function.Option 1:
We could make hashPresent set to false when the passed uri is "#".
Option 2:
We could add a safety check before accessing the first character of the path.
Extra
The text was updated successfully, but these errors were encountered: