Skip to content

Commit c261ca3

Browse files
committed
Ensure scheme not lowercased if URI variable
Closes gh-33699
1 parent a63cf06 commit c261ca3

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

Diff for: spring-web/src/main/java/org/springframework/web/util/RfcUriParser.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.web.util;
1818

19+
import java.util.Locale;
1920
import java.util.Set;
2021

2122
import org.apache.commons.logging.Log;
@@ -508,7 +509,8 @@ public InternalParser resolveIfOpaque() {
508509
}
509510

510511
public InternalParser captureScheme() {
511-
this.scheme = captureComponent("scheme").toLowerCase();
512+
String scheme = captureComponent("scheme");
513+
this.scheme = (!scheme.startsWith("{") ? scheme.toLowerCase(Locale.ROOT) : scheme);
512514
return this;
513515
}
514516

@@ -633,8 +635,11 @@ public boolean processCurlyBrackets(char c) {
633635
return true;
634636
}
635637
else if (c == '}') {
636-
this.openCurlyBracketCount--;
637-
return true;
638+
if (this.openCurlyBracketCount > 0) {
639+
this.openCurlyBracketCount--;
640+
return true;
641+
}
642+
return false;
638643
}
639644
return (this.openCurlyBracketCount > 0);
640645
}

Diff for: spring-web/src/main/java/org/springframework/web/util/WhatWgUrlParser.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ private void setState(State newState) {
235235
logger.trace("Changing state from " + this.state + " to " + newState + " (cur: " + c + ")");
236236
}
237237
this.state = newState;
238-
this.openCurlyBracketCount = 0;
238+
this.openCurlyBracketCount = (this.buffer.toString().equals("{") ? this.openCurlyBracketCount : 0);
239239
}
240240

241241
private boolean processCurlyBrackets(int c) {
@@ -244,8 +244,11 @@ private boolean processCurlyBrackets(int c) {
244244
return true;
245245
}
246246
if (c == '}') {
247-
this.openCurlyBracketCount--;
248-
return true;
247+
if (this.openCurlyBracketCount > 0) {
248+
this.openCurlyBracketCount--;
249+
return true;
250+
}
251+
return false;
249252
}
250253
return (this.openCurlyBracketCount > 0 && c != EOF);
251254
}
@@ -756,7 +759,7 @@ private enum State {
756759
public void handle(int c, UrlRecord url, WhatWgUrlParser p) {
757760
// If c is an ASCII alpha, append c, lowercased, to buffer, and set state to scheme state.
758761
if (isAsciiAlpha(c)) {
759-
p.append(Character.toLowerCase((char) c));
762+
p.append(p.openCurlyBracketCount == 0 ? Character.toLowerCase((char) c) : c);
760763
p.setState(SCHEME);
761764
}
762765
// EXTRA: if c is '{', append to buffer and continue as SCHEME
@@ -782,7 +785,7 @@ else if (p.stateOverride == null) {
782785
public void handle(int c, UrlRecord url, WhatWgUrlParser p) {
783786
// If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.), append c, lowercased, to buffer.
784787
if (isAsciiAlphaNumeric(c) || (c == '+' || c == '-' || c == '.')) {
785-
p.append(Character.toLowerCase((char) c));
788+
p.append(p.openCurlyBracketCount == 0 ? Character.toLowerCase((char) c) : c);
786789
}
787790
// Otherwise, if c is U+003A (:), then:
788791
else if (c == ':') {

Diff for: spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java

+10
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,16 @@ void buildAndExpandOpaque(ParserType parserType) {
629629
assertThat(result.toUriString()).isEqualTo("mailto:[email protected]");
630630
}
631631

632+
@ParameterizedTest // gh-33699
633+
@EnumSource(value = ParserType.class)
634+
void schemeVariableMixedCase(ParserType parserType) {
635+
URI uri = UriComponentsBuilder
636+
.fromUriString("{TheScheme}://example.org", parserType)
637+
.buildAndExpand(Map.of("TheScheme", "ws"))
638+
.toUri();
639+
assertThat(uri.toString()).isEqualTo("ws://example.org");
640+
}
641+
632642
@ParameterizedTest
633643
@EnumSource(value = ParserType.class)
634644
void queryParamWithValueWithEquals(ParserType parserType) {

0 commit comments

Comments
 (0)