Browse Source

SPR-17606 @Profile mishandles "not" operand mixed with "&" (#2066)

Correct handling of not/and expressions in ProfilesParser

Issue: SPR-17606
pull/18152/head
Andrzej Leśkiewicz 7 years ago committed by Juergen Hoeller
parent
commit
952045c216
  1. 25
      spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java
  2. 52
      spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java

25
spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -54,6 +54,9 @@ final class ProfilesParser { @@ -54,6 +54,9 @@ final class ProfilesParser {
}
private static Profiles parseTokens(String expression, StringTokenizer tokens) {
return parseTokens(expression, tokens, Context.NONE);
}
private static Profiles parseTokens(String expression, StringTokenizer tokens, Context context) {
List<Profiles> elements = new ArrayList<>();
Operator operator = null;
while (tokens.hasMoreTokens()) {
@ -63,7 +66,11 @@ final class ProfilesParser { @@ -63,7 +66,11 @@ final class ProfilesParser {
}
switch (token) {
case "(":
elements.add(parseTokens(expression, tokens));
Profiles contents = parseTokens(expression, tokens, Context.BRACKET);
if (context == Context.INVERT) {
return contents;
}
elements.add(contents);
break;
case "&":
assertWellFormed(expression, operator == null || operator == Operator.AND);
@ -74,16 +81,23 @@ final class ProfilesParser { @@ -74,16 +81,23 @@ final class ProfilesParser {
operator = Operator.OR;
break;
case "!":
elements.add(not(parseTokens(expression, tokens)));
elements.add(not(parseTokens(expression, tokens, Context.INVERT)));
break;
case ")":
Profiles merged = merge(expression, elements, operator);
if (context == Context.BRACKET) {
return merged;
}
elements.clear();
elements.add(merged);
operator = null;
break;
default:
elements.add(equals(token));
Profiles value = equals(token);
if (context == Context.INVERT) {
return value;
}
elements.add(value);
}
}
return merge(expression, elements, operator);
@ -126,6 +140,9 @@ final class ProfilesParser { @@ -126,6 +140,9 @@ final class ProfilesParser {
private enum Operator {AND, OR}
private enum Context {NONE, INVERT, BRACKET}
private static class ParsedProfiles implements Profiles {
private final String[] expressions;

52
spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -195,6 +195,56 @@ public class ProfilesTests { @@ -195,6 +195,56 @@ public class ProfilesTests {
assertTrue(profiles.matches(activeProfiles("java")));
}
@Test
public void ofAndExpressionWithInvertedSingleElement() {
Profiles profiles = Profiles.of("!spring & framework");
assertOfAndExpressionWithInvertedSingleElement(profiles);
}
@Test
public void ofAndExpressionWithInBracketsInvertedSingleElement() {
Profiles profiles = Profiles.of("(!spring) & framework");
assertOfAndExpressionWithInvertedSingleElement(profiles);
}
@Test
public void ofAndExpressionWithInvertedSingleElementInBrackets() {
Profiles profiles = Profiles.of("! (spring) & framework");
assertOfAndExpressionWithInvertedSingleElement(profiles);
}
@Test
public void ofAndExpressionWithInvertedSingleElementInBracketsWithoutSpaces() {
Profiles profiles = Profiles.of("!(spring)&framework");
assertOfAndExpressionWithInvertedSingleElement(profiles);
}
@Test
public void ofAndExpressionWithInvertedSingleElementWithoutSpaces() {
Profiles profiles = Profiles.of("!spring&framework");
assertOfAndExpressionWithInvertedSingleElement(profiles);
}
private void assertOfAndExpressionWithInvertedSingleElement(Profiles profiles) {
assertTrue(profiles.matches(activeProfiles("framework")));
assertFalse(profiles.matches(activeProfiles("java")));
assertFalse(profiles.matches(activeProfiles("spring", "framework")));
assertFalse(profiles.matches(activeProfiles("spring")));
}
@Test
public void ofOrExpressionWithInvertedSingleElementWithoutSpaces() {
Profiles profiles = Profiles.of("!spring|framework");
assertOfOrExpressionWithInvertedSingleElement(profiles);
}
private void assertOfOrExpressionWithInvertedSingleElement(Profiles profiles) {
assertTrue(profiles.matches(activeProfiles("framework")));
assertTrue(profiles.matches(activeProfiles("java")));
assertTrue(profiles.matches(activeProfiles("spring", "framework")));
assertFalse(profiles.matches(activeProfiles("spring")));
}
@Test
public void ofNotOrExpression() {
Profiles profiles = Profiles.of("!(spring | framework)");

Loading…
Cancel
Save