#974 remove one or two escapes for supporting JSON (#982)

Hi.  This is an attempt to fix #974 (cc @ryanjbaxter )

As mentioned previously in the ticket, the original code tries to mask out escaped variables (i.e. `\${hello}`) before performing replacement, and then finally removing the escapes before returning.  

This works fine for .yaml or .properties, but not for JSON.

The jackson serialization that happens before the property resolution ends up adding an extra `\` (so that the JSON is well-formed) [EnvironmentController.labelledJsonPropertes](https://github.com/spring-cloud/spring-cloud-config/blob/master/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java#L169).

I've updated the `resolverPlaceholders` to accept one or two escapes (`\` or `\\`).

I realize this will now treat `\\` as an escape in yml or properties, which may be unintended, but seems unlikely.

An alternative might be to add a flag to this method to indicate whether or not to allow double escape, and updating the `labelledJson` method to pass the flag?

I'm open to any feedback on this approach or another.

Thanks!
This commit is contained in:
Larry Ogrodnek
2018-09-17 09:36:50 -04:00
committed by Spencer Gibb
parent fdf72039af
commit 35d176e56f
2 changed files with 25 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
package org.springframework.cloud.config.server.support;
import java.util.Map;
import java.util.regex.Pattern;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.core.env.PropertySource;
@@ -22,11 +23,14 @@ public class EnvironmentPropertySource extends PropertySource<Environment> {
return standardEnvironment;
}
// "\${" (from text) or "\\${" from JSON to signal escaped placeholder
private static final Pattern ESCAPED_PLACEHOLDERS = Pattern.compile("[\\\\]{1,2}\\$\\{");
public static String resolvePlaceholders(StandardEnvironment preparedEnvironment,
String text) {
// Mask out escaped placeholders
text = text.replace("\\${", "$_{");
return preparedEnvironment.resolvePlaceholders(text).replace("$_{", "${");
// Mask out escaped placeholders
text = ESCAPED_PLACEHOLDERS.matcher(text).replaceAll("\\$_{");
return preparedEnvironment.resolvePlaceholders(text).replace("$_{", "${");
}
public EnvironmentPropertySource(Environment sources) {

View File

@@ -0,0 +1,18 @@
package org.springframework.cloud.config.server.support;
import static org.junit.Assert.assertEquals;
import static org.springframework.cloud.config.server.support.EnvironmentPropertySource.resolvePlaceholders;
import org.junit.Test;
import org.springframework.core.env.StandardEnvironment;
public class EnvironmentPropertySourceTest {
private final StandardEnvironment env = new StandardEnvironment();
@Test
public void testEscapedPlaceholdersRemoved() {
assertEquals("${abc}", resolvePlaceholders(env, "\\${abc}"));
// JSON generated from jackson will be double escaped
assertEquals("${abc}", resolvePlaceholders(env, "\\\\${abc}"));
}
}