Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly decode $ref #7191

Merged
merged 8 commits into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
import org.slf4j.LoggerFactory;
import org.apache.commons.io.FileUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URLDecoder;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -71,7 +73,7 @@ public class ModelUtils {
JSON_MAPPER = ObjectMapperFactory.createJson();
YAML_MAPPER = ObjectMapperFactory.createYaml();
}

public static void setDisallowAdditionalPropertiesIfNotPresent(boolean value) {
GlobalSettings.setProperty(disallowAdditionalPropertiesIfNotPresent, Boolean.toString(value));
}
Expand Down Expand Up @@ -386,6 +388,18 @@ public static String getSimpleRef(String ref) {

}

try {
ref = URLDecoder.decode(ref, "UTF-8");
} catch (UnsupportedEncodingException ignored) {
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we decode it at the start of the function getSimpleRef instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought, but why decoding a String part which gets thrown away? I see no reason to do so

By the way, I think we should also unescape these special cases:
image

// see https://tools.ietf.org/html/rfc6901#section-3
// Because the characters '~' (%x7E) and '/' (%x2F) have special meanings in
// JSON Pointer, '~' needs to be encoded as '~0' and '/' needs to be encoded
// as '~1' when these characters appear in a reference token.
// This reverses that encoding.
ref = ref.replace("~1", "/").replace("~0", "~");
sbu-WBT marked this conversation as resolved.
Show resolved Hide resolved

return ref;
}

Expand Down Expand Up @@ -1077,15 +1091,15 @@ public static Schema unaliasSchema(OpenAPI openAPI,

/**
* Returns the additionalProperties Schema for the specified input schema.
*
*
* The additionalProperties keyword is used to control the handling of additional, undeclared
* properties, that is, properties whose names are not listed in the properties keyword.
* The additionalProperties keyword may be either a boolean or an object.
* If additionalProperties is a boolean and set to false, no additional properties are allowed.
* By default when the additionalProperties keyword is not specified in the input schema,
* any additional properties are allowed. This is equivalent to setting additionalProperties
* to the boolean value True or setting additionalProperties: {}
*
*
* @param openAPI the object that encapsulates the OAS document.
* @param schema the input schema that may or may not have the additionalProperties keyword.
* @return the Schema of the additionalProperties. The null value is returned if no additional
Expand Down Expand Up @@ -1141,7 +1155,7 @@ public static Schema getAdditionalProperties(OpenAPI openAPI, Schema schema) {
}
return null;
}

public static Header getReferencedHeader(OpenAPI openAPI, Header header) {
if (header != null && StringUtils.isNotEmpty(header.get$ref())) {
String name = getSimpleRef(header.get$ref());
Expand Down Expand Up @@ -1478,12 +1492,12 @@ private static ObjectMapper getRightMapper(String data) {

/**
* Parse and return a JsonNode representation of the input OAS document.
*
*
* @param location the URL of the OAS document.
* @param auths the list of authorization values to access the remote URL.
*
*
* @throws java.lang.Exception if an error occurs while retrieving the OpenAPI document.
*
*
* @return A JsonNode representation of the input OAS document.
*/
public static JsonNode readWithInfo(String location, List<AuthorizationValue> auths) throws Exception {
Expand Down Expand Up @@ -1511,14 +1525,14 @@ public static JsonNode readWithInfo(String location, List<AuthorizationValue> au
/**
* Parse the OAS document at the specified location, get the swagger or openapi version
* as specified in the source document, and return the version.
*
*
* For OAS 2.0 documents, return the value of the 'swagger' attribute.
* For OAS 3.x documents, return the value of the 'openapi' attribute.
*
*
* @param openAPI the object that encapsulates the OAS document.
* @param location the URL of the OAS document.
* @param auths the list of authorization values to access the remote URL.
*
*
* @return the version of the OpenAPI document.
*/
public static SemVer getOpenApiVersion(OpenAPI openAPI, String location, List<AuthorizationValue> auths) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,10 @@ public void testIsSetFailsForNullSchema() {
ArraySchema as = null;
Assert.assertFalse(ModelUtils.isSet(as));
}
}

@Test
public void testSimpleRefDecoding() {
String decoded = ModelUtils.getSimpleRef("#/components/~01%20Hallo~1Welt");
Assert.assertEquals(decoded, "~1 Hallo/Welt");
}
}