Skip to content

Commit 0eaffb3

Browse files
committed
Require Locale argument for toLower/toUpperCase usage
1 parent e86d88d commit 0eaffb3

File tree

23 files changed

+97
-50
lines changed

23 files changed

+97
-50
lines changed

cas/src/main/java/org/springframework/security/cas/userdetails/GrantedAuthorityFromAssertionAttributesUserDetailsService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import java.util.Locale;
2122

2223
import org.jasig.cas.client.validation.Assertion;
2324

@@ -73,7 +74,8 @@ protected UserDetails loadUserDetails(final Assertion assertion) {
7374
}
7475

7576
private SimpleGrantedAuthority createSimpleGrantedAuthority(Object o) {
76-
return new SimpleGrantedAuthority(this.convertToUpperCase ? o.toString().toUpperCase() : o.toString());
77+
return new SimpleGrantedAuthority(
78+
this.convertToUpperCase ? o.toString().toUpperCase(Locale.ROOT) : o.toString());
7779
}
7880

7981
/**

config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import java.util.Locale;
2122

2223
import javax.servlet.ServletRequest;
2324

@@ -286,7 +287,7 @@ void setCsrfIgnoreRequestMatchers(List<BeanDefinition> requestMatchers) {
286287

287288
// Needed to account for placeholders
288289
static String createPath(String path, boolean lowerCase) {
289-
return lowerCase ? path.toLowerCase() : path;
290+
return lowerCase ? path.toLowerCase(Locale.ENGLISH) : path;
290291
}
291292

292293
BeanReference getSecurityContextRepositoryForAuthenticationFilters() {

core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAttributes2GrantedAuthoritiesMapper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,10 +79,10 @@ public List<GrantedAuthority> getGrantedAuthorities(Collection<String> attribute
7979
*/
8080
private GrantedAuthority getGrantedAuthority(String attribute) {
8181
if (isConvertAttributeToLowerCase()) {
82-
attribute = attribute.toLowerCase(Locale.getDefault());
82+
attribute = attribute.toLowerCase(Locale.ROOT);
8383
}
8484
else if (isConvertAttributeToUpperCase()) {
85-
attribute = attribute.toUpperCase(Locale.getDefault());
85+
attribute = attribute.toUpperCase(Locale.ROOT);
8686
}
8787
if (isAddPrefixIfAlreadyExisting() || !attribute.startsWith(getAttributePrefix())) {
8888
return new SimpleGrantedAuthority(getAttributePrefix() + attribute);

core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Collection;
2020
import java.util.HashSet;
21+
import java.util.Locale;
2122
import java.util.Set;
2223

2324
import org.springframework.beans.factory.InitializingBean;
@@ -71,10 +72,10 @@ public Set<GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthorit
7172

7273
private GrantedAuthority mapAuthority(String name) {
7374
if (this.convertToUpperCase) {
74-
name = name.toUpperCase();
75+
name = name.toUpperCase(Locale.ROOT);
7576
}
7677
else if (this.convertToLowerCase) {
77-
name = name.toLowerCase();
78+
name = name.toLowerCase(Locale.ROOT);
7879
}
7980
if (this.prefix.length() > 0 && !name.startsWith(this.prefix)) {
8081
name = this.prefix + name;

core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Arrays;
2020
import java.util.Collection;
21+
import java.util.Locale;
2122
import java.util.Map;
2223
import java.util.concurrent.ConcurrentHashMap;
2324

@@ -91,7 +92,7 @@ private UserDetails withNewPassword(UserDetails userDetails, String newPassword)
9192
}
9293

9394
private String getKey(String username) {
94-
return username.toLowerCase();
95+
return username.toLowerCase(Locale.ROOT);
9596
}
9697

9798
}

core/src/main/java/org/springframework/security/core/userdetails/memory/UserAttributeEditor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.beans.PropertyEditorSupport;
2020
import java.util.ArrayList;
2121
import java.util.List;
22+
import java.util.Locale;
2223

2324
import org.springframework.util.StringUtils;
2425

@@ -45,10 +46,10 @@ public void setAsText(String s) throws IllegalArgumentException {
4546
userAttrib.setPassword(currentToken);
4647
}
4748
else {
48-
if (currentToken.toLowerCase().equals("enabled")) {
49+
if (currentToken.toLowerCase(Locale.ENGLISH).equals("enabled")) {
4950
userAttrib.setEnabled(true);
5051
}
51-
else if (currentToken.toLowerCase().equals("disabled")) {
52+
else if (currentToken.toLowerCase(Locale.ENGLISH).equals("disabled")) {
5253
userAttrib.setEnabled(false);
5354
}
5455
else {

core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import java.util.Collection;
2020
import java.util.Enumeration;
2121
import java.util.HashMap;
22+
import java.util.Locale;
2223
import java.util.Map;
2324
import java.util.Properties;
2425

@@ -92,23 +93,23 @@ private User createUserDetails(String name, UserAttribute attr) {
9293
@Override
9394
public void createUser(UserDetails user) {
9495
Assert.isTrue(!userExists(user.getUsername()), "user should not exist");
95-
this.users.put(user.getUsername().toLowerCase(), new MutableUser(user));
96+
this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user));
9697
}
9798

9899
@Override
99100
public void deleteUser(String username) {
100-
this.users.remove(username.toLowerCase());
101+
this.users.remove(username.toLowerCase(Locale.ROOT));
101102
}
102103

103104
@Override
104105
public void updateUser(UserDetails user) {
105106
Assert.isTrue(userExists(user.getUsername()), "user should exist");
106-
this.users.put(user.getUsername().toLowerCase(), new MutableUser(user));
107+
this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user));
107108
}
108109

109110
@Override
110111
public boolean userExists(String username) {
111-
return this.users.containsKey(username.toLowerCase());
112+
return this.users.containsKey(username.toLowerCase(Locale.ROOT));
112113
}
113114

114115
@Override
@@ -139,14 +140,14 @@ public void changePassword(String oldPassword, String newPassword) {
139140
@Override
140141
public UserDetails updatePassword(UserDetails user, String newPassword) {
141142
String username = user.getUsername();
142-
MutableUserDetails mutableUser = this.users.get(username.toLowerCase());
143+
MutableUserDetails mutableUser = this.users.get(username.toLowerCase(Locale.ROOT));
143144
mutableUser.setPassword(newPassword);
144145
return mutableUser;
145146
}
146147

147148
@Override
148149
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
149-
UserDetails user = this.users.get(username.toLowerCase());
150+
UserDetails user = this.users.get(username.toLowerCase(Locale.ROOT));
150151
if (user == null) {
151152
throw new UsernameNotFoundException(username);
152153
}

crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.security.MessageDigest;
2020
import java.util.Base64;
21+
import java.util.Locale;
2122

2223
import org.springframework.security.crypto.codec.Utf8;
2324
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
@@ -50,11 +51,11 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
5051

5152
private static final String SSHA_PREFIX = "{SSHA}";
5253

53-
private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase();
54+
private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase(Locale.ENGLISH);
5455

5556
private static final String SHA_PREFIX = "{SHA}";
5657

57-
private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase();
58+
private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase(Locale.ENGLISH);
5859

5960
private BytesKeyGenerator saltGenerator;
6061

etc/checkstyle/checkstyle-suppressions.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,11 @@
5353
<suppress files="WithSecurityContextTestExecutionListenerTests\.java" checks="SpringMethodVisibility"/>
5454
<suppress files="AbstractOAuth2AuthorizationGrantRequestEntityConverter\.java" checks="SpringMethodVisibility"/>
5555
<suppress files="JoseHeader\.java" checks="SpringMethodVisibility"/>
56+
57+
<!-- Lambdas that we can't replace with a method reference because a closure is required -->
58+
<suppress files="BearerTokenAuthenticationFilter\.java" checks="SpringLambda"/>
59+
60+
<!-- Ignore String.toUpperCase() and String.toLowerCase() checks in tests -->
61+
<suppress files="[\\/]src[\\/]test[\\/]" checks="RegexpSinglelineJava" id="toLowerCaseWithoutLocale"/>
62+
<suppress files="[\\/]src[\\/]test[\\/]" checks="RegexpSinglelineJava" id="toUpperCaseWithoutLocale"/>
5663
</suppressions>

etc/checkstyle/checkstyle.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,21 @@
2323
<property name="message" value="Please use assertThatExceptionOfType." />
2424
<property name="ignoreComments" value="true" />
2525
</module>
26+
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
27+
<property name="id" value="toLowerCaseWithoutLocale"/>
28+
<property name="format" value="\.toLowerCase\(\)"/>
29+
<property name="maximum" value="0"/>
30+
<property name="message"
31+
value="String.toLowerCase() should be String.toLowerCase(Locale.ROOT) or String.toLowerCase(Locale.ENGLISH)"/>
32+
<property name="ignoreComments" value="true"/>
33+
</module>
34+
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
35+
<property name="id" value="toUpperCaseWithoutLocale"/>
36+
<property name="format" value="\.toUpperCase\(\)"/>
37+
<property name="maximum" value="0"/>
38+
<property name="message"
39+
value="String.toUpperCase() should be String.toUpperCase(Locale.ROOT) or String.toUpperCase(Locale.ENGLISH)"/>
40+
<property name="ignoreComments" value="true"/>
41+
</module>
2642
</module>
2743
</module>

ldap/src/main/java/org/springframework/security/ldap/LdapEncoder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.security.ldap;
1818

19+
import java.util.Locale;
20+
1921
import org.springframework.ldap.BadLdapGrammarException;
2022

2123
/**
@@ -72,7 +74,7 @@ private LdapEncoder() {
7274
}
7375

7476
protected static String toTwoCharHex(char c) {
75-
String raw = Integer.toHexString(c).toUpperCase();
77+
String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH);
7678
return (raw.length() > 1) ? raw : "0" + raw;
7779
}
7880

ldap/src/main/java/org/springframework/security/ldap/authentication/LdapEncoder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.security.ldap.authentication;
1818

19+
import java.util.Locale;
20+
1921
import org.springframework.ldap.BadLdapGrammarException;
2022

2123
/**
@@ -72,7 +74,7 @@ private LdapEncoder() {
7274
}
7375

7476
protected static String toTwoCharHex(char c) {
75-
String raw = Integer.toHexString(c).toUpperCase();
77+
String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH);
7678
return (raw.length() > 1) ? raw : "0" + raw;
7779
}
7880

ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import java.util.HashMap;
2424
import java.util.Hashtable;
2525
import java.util.List;
26+
import java.util.Locale;
2627
import java.util.Map;
2728
import java.util.regex.Matcher;
2829
import java.util.regex.Pattern;
@@ -142,9 +143,9 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
142143
*/
143144
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, String rootDn) {
144145
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
145-
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
146+
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null;
146147
this.url = url;
147-
this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase() : null;
148+
this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase(Locale.ROOT) : null;
148149
}
149150

150151
/**
@@ -153,7 +154,7 @@ public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, Stri
153154
*/
154155
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) {
155156
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
156-
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
157+
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null;
157158
this.url = url;
158159
this.rootDn = (this.domain != null) ? rootDnFromDomain(this.domain) : null;
159160
}
@@ -361,7 +362,7 @@ private String rootDnFromDomain(String domain) {
361362
}
362363

363364
String createBindPrincipal(String username) {
364-
if (this.domain == null || username.toLowerCase().endsWith(this.domain)) {
365+
if (this.domain == null || username.toLowerCase(Locale.ROOT).endsWith(this.domain)) {
365366
return username;
366367
}
367368
return username + "@" + this.domain;

ldap/src/main/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collection;
2121
import java.util.HashSet;
2222
import java.util.List;
23+
import java.util.Locale;
2324
import java.util.Map;
2425
import java.util.Set;
2526
import java.util.function.Function;
@@ -179,7 +180,7 @@ else if (groupSearchBase.length() == 0) {
179180
return null;
180181
}
181182
if (this.convertToUpperCase) {
182-
role = role.toUpperCase();
183+
role = role.toUpperCase(Locale.ROOT);
183184
}
184185
return new SimpleGrantedAuthority(this.rolePrefix + role);
185186
};

0 commit comments

Comments
 (0)