Skip to content

Commit e4ce670

Browse files
authored
Merge pull request #2406 from marcingrzejszczak/fix/issue-1790-header-escape-duplication
Fixes double escaping of headers fixes gh-1790
2 parents 095557b + 0976c63 commit e4ce670

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/ComparisonBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ default String assertThatUnescaped(String object, Object valueToCompareAgainst)
6666
}
6767

6868
default String isEqualTo(String escapedHeaderValue) {
69-
return isEqualToUnquoted(bodyParser().quotedShortText(escapedHeaderValue));
69+
// Use quotedEscapedShortText since the value is already escaped by
70+
// convertUnicodeEscapesIfRequired
71+
return isEqualToUnquoted(bodyParser().quotedEscapedShortText(escapedHeaderValue));
7072
}
7173

7274
default String isEqualToUnquoted(String unquoted) {

spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/builder/GroovyComparisonBuilder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,11 @@ default String isNotNull() {
6565
return " != null";
6666
}
6767

68+
@Override
69+
default String convertUnicodeEscapesIfRequired(String json) {
70+
// For Groovy, delegate to the body parser which doesn't escape quotes
71+
// since Groovy triple-quoted strings don't need escaped quotes
72+
return bodyParser().convertUnicodeEscapesIfRequired(json);
73+
}
74+
6875
}

spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,4 +3400,43 @@ DocumentContext parsedJson = JsonPath.parse(json);
34003400
}
34013401
"webclient" | { configProperties.testMode = TestMode.WEBTESTCLIENT }
34023402
}
3403+
3404+
@Issue('#1790')
3405+
def 'should not double-escape header values containing quotes for [#methodBuilderName]'() {
3406+
given:
3407+
Contract contractDsl = Contract.make {
3408+
request {
3409+
method GET()
3410+
url '/download'
3411+
}
3412+
response {
3413+
status OK()
3414+
headers {
3415+
header('Content-Disposition', 'attachment; filename="test.pdf"')
3416+
}
3417+
body("file content")
3418+
}
3419+
}
3420+
methodBuilder()
3421+
when:
3422+
String test = singleTestGenerator(contractDsl)
3423+
then:
3424+
// The header value should contain properly escaped quotes for Java string literal,
3425+
// not double-escaped quotes. Spock uses == with triple quotes, JUnit uses isEqualTo.
3426+
headerAssertion.call(test)
3427+
// Should never contain double-escaped quotes (4 backslashes before each quote)
3428+
!test.contains('filename=\\\\\\"test.pdf\\\\\\"')
3429+
and:
3430+
SyntaxChecker.tryToCompile(methodBuilderName, test)
3431+
where:
3432+
methodBuilderName | methodBuilder | headerAssertion
3433+
// Spock MockMvc uses triple quotes so no escaping needed inside
3434+
"spock" | { configProperties.testFramework = TestFramework.SPOCK } | { String body -> body.contains("'''attachment; filename=\"test.pdf\"'''") }
3435+
"testng" | { configProperties.testFramework = TestFramework.TESTNG } | { String body -> body.contains('isEqualTo("attachment; filename=\\"test.pdf\\"")') }
3436+
"mockmvc" | { configProperties.testMode = TestMode.MOCKMVC } | { String body -> body.contains('isEqualTo("attachment; filename=\\"test.pdf\\"")') }
3437+
// JaxRs Spock uses double quotes so quotes need escaping
3438+
"jaxrs-spock" | { configProperties.testFramework = TestFramework.SPOCK; configProperties.testMode = TestMode.JAXRSCLIENT } | { String body -> body.contains('filename=\\"test.pdf\\"') }
3439+
"jaxrs" | { configProperties.testFramework = TestFramework.JUNIT; configProperties.testMode = TestMode.JAXRSCLIENT } | { String body -> body.contains('isEqualTo("attachment; filename=\\"test.pdf\\"")') }
3440+
"webclient" | { configProperties.testMode = TestMode.WEBTESTCLIENT } | { String body -> body.contains('isEqualTo("attachment; filename=\\"test.pdf\\"")') }
3441+
}
34033442
}

0 commit comments

Comments
 (0)