quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.66k stars 2.65k forks source link

Quarkus REST: `UriInfo` fails building URI for path parameters with regexes #42249

Open FroMage opened 2 months ago

FroMage commented 2 months ago

Describe the bug

Given this endpoint:

    @GET
    @Path("test/{token}/{checksum}{extension:(\\.png)?}")
    public String get(UriInfo info, @RestPath UUID token, @RestPath Integer checksum, @RestPath String extension) {
        return info.getBaseUriBuilder().path(Application.class, "get")
                .resolveTemplate("token", token)
                .resolveTemplate("checksum", checksum)
                .resolveTemplate("extension", extension)
                .build().toASCIIString();
    }

When invoked as http://localhost:8080/Application/test/453f74a6-d1f1-4cca-9322-142f9f46df09/1234.png, the result is http://localhost:8080/test/453f74a6-d1f1-4cca-9322-142f9f46df09/1234%7Bextension:(%5C.png)?%7D which is incorrect (it should be identical, we're re-creating the original URI).

This is due to the first call of UriBuilderImpl.resolveTemplate going to resolve the first template parameter, then call:

            Matcher match = hierarchicalUri.matcher(uriTemplate);
            if (match.matches()) {
                ssp = null;
                return parseHierarchicalUri(uriTemplate, match);
            }

And hierarchicalUri will look at http://localhost:8080/Application/test/453f74a6-d1f1-4cca-9322-142f9f46df09/{checksum}{extension:(\\.png)?} and conclude, quite erroneously, that ?} is the start of the query part. So it will end up in parseHierarchicalUri with a match.group(5) of /Application/test/453f74a6-d1f1-4cca-9322-142f9f46df09/{checksum}{extension:(\\.png) (notice how it's missing the ?} at the end, making this an invalid path parameter, which will end up encoded in all sorts of wrong ways.

The problem is that we can't really use a regex for parsing URIs with template parameter that are regexes, because some of the regexes match as path/query separators.

Honestly, I'm not sure how to fix this.

quarkus-bot[bot] commented 2 months ago

/cc @geoand (resteasy-reactive), @stuartwdouglas (resteasy-reactive)