Don't rely on default locale when using toUpperCase() and toLowerCase()

Otherwise these methods may produce unexpected results if used for
strings that are intended to be interpreted locale independently.
Examples are programming language identifiers, protocol keys, and HTML
tags. For instance, "TITLE".toLowerCase() in a Turkish locale returns
"t\u0131tle", where '\u0131' is the LATIN SMALL LETTER DOTLESS I
character.

See
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#toLowerCase--
http://blog.thetaphi.de/2012/07/default-locales-default-charsets-and.html

Bug: 511238
Change-Id: Id8d8f37d84d62239c918b81f8d883ed798d87656
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2017-01-28 15:06:15 +01:00
parent 2eb1bebd60
commit a4feeb0194
18 changed files with 52 additions and 25 deletions

View File

@ -57,6 +57,7 @@
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.SimpleTimeZone;
import java.util.SortedMap;
@ -247,7 +248,7 @@ private static String canonicalizeHeaderNames(
for (String header : sortedHeaders) {
if (buffer.length() > 0)
buffer.append(";"); //$NON-NLS-1$
buffer.append(header.toLowerCase());
buffer.append(header.toLowerCase(Locale.ROOT));
}
return buffer.toString();
@ -265,7 +266,8 @@ private static String canonicalizeHeaderString(
StringBuilder buffer = new StringBuilder();
for (String key : sortedHeaders) {
buffer.append(key.toLowerCase().replaceAll("\\s+", " ") + ":" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
buffer.append(
key.toLowerCase(Locale.ROOT).replaceAll("\\s+", " ") + ":" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ headers.get(key).replaceAll("\\s+", " ")); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("\n"); //$NON-NLS-1$
}

View File

@ -57,6 +57,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
@ -152,7 +153,7 @@ public void test010_toString() {
public void test011_toString() {
final String x = "0123456789ABCDEFabcdef01234567890123456789ABCDEFabcdef0123456789";
final LongObjectId oid = LongObjectId.fromString(x);
assertEquals(x.toLowerCase(), oid.name());
assertEquals(x.toLowerCase(Locale.ROOT), oid.name());
}
@Test

View File

@ -51,6 +51,7 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Locale;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
@ -79,7 +80,7 @@ public class LfsPointer {
* evaluate to "sha256"
*/
public static final String HASH_FUNCTION_NAME = Constants.LONG_HASH_FUNCTION
.toLowerCase().replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$
.toLowerCase(Locale.ROOT).replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$
private AnyLongObjectId oid;

View File

@ -53,6 +53,7 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@ -102,8 +103,8 @@ void addAdditionalNoteRef(String notesRef) {
@Option(name = "--date", usage = "usage_date")
void dateFormat(String date) {
if (date.toLowerCase().equals(date))
date = date.toUpperCase();
if (date.toLowerCase(Locale.ROOT).equals(date))
date = date.toUpperCase(Locale.ROOT);
dateFormatter = new GitDateFormatter(Format.valueOf(date));
}

View File

@ -53,6 +53,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.eclipse.jgit.awtui.AwtAuthenticator;
import org.eclipse.jgit.awtui.AwtCredentialsProvider;
@ -240,7 +241,8 @@ private void execute(final String[] argv) throws Exception {
}
if (version) {
String cmdId = Version.class.getSimpleName().toLowerCase();
String cmdId = Version.class.getSimpleName()
.toLowerCase(Locale.ROOT);
subcommand = CommandCatalog.get(cmdId).create();
}

View File

@ -49,6 +49,8 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Locale;
import org.eclipse.jgit.errors.InvalidObjectIdException;
import org.junit.Test;
@ -122,7 +124,7 @@ public void test010_toString() {
public void test011_toString() {
final String x = "0123456789ABCDEFabcdef1234567890abcdefAB";
final ObjectId oid = ObjectId.fromString(x);
assertEquals(x.toLowerCase(), oid.name());
assertEquals(x.toLowerCase(Locale.ROOT), oid.name());
}
@Test(expected = InvalidObjectIdException.class)

View File

@ -85,6 +85,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
@ -461,7 +462,7 @@ static List<String> cryptoCipherList(String regex) {
Set<String> source = Security.getAlgorithms("Cipher");
Set<String> target = new TreeSet<String>();
for (String algo : source) {
algo = algo.toUpperCase();
algo = algo.toUpperCase(Locale.ROOT);
if (algo.matches(regex)) {
target.add(algo);
}
@ -759,7 +760,7 @@ static boolean isAlgorithmPresent(String algorithm) {
for (String source : cipherSet) {
// Standard names are not case-sensitive.
// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
String target = algorithm.toUpperCase();
String target = algorithm.toUpperCase(Locale.ROOT);
if (source.equalsIgnoreCase(target)) {
return true;
}

View File

@ -50,6 +50,7 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
@ -134,7 +135,7 @@ public enum FastForwardMode implements ConfigEnum {
FF_ONLY;
public String toConfigValue() {
return "--" + name().toLowerCase().replace('_', '-'); //$NON-NLS-1$
return "--" + name().toLowerCase(Locale.ROOT).replace('_', '-'); //$NON-NLS-1$
}
public boolean matchConfigValue(String in) {

View File

@ -55,6 +55,7 @@
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
@ -342,7 +343,7 @@ && getDirectory().getName().startsWith(".")) //$NON-NLS-1$
if (symLinks != null)
cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_SYMLINKS, symLinks.name()
.toLowerCase());
.toLowerCase(Locale.ROOT));
cfg.setInt(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0);
cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,

View File

@ -58,6 +58,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@ -895,7 +896,7 @@ public <T extends Enum<?>> void setEnum(final String section,
if (value instanceof ConfigEnum)
n = ((ConfigEnum) value).toConfigValue();
else
n = value.name().toLowerCase().replace('_', ' ');
n = value.name().toLowerCase(Locale.ROOT).replace('_', ' ');
setString(section, subsection, name, n);
}

View File

@ -43,6 +43,8 @@
package org.eclipse.jgit.patch;
import java.util.Locale;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.util.RawParseUtils;
@ -102,7 +104,7 @@ public String getLineText() {
@Override
public String toString() {
final StringBuilder r = new StringBuilder();
r.append(getSeverity().name().toLowerCase());
r.append(getSeverity().name().toLowerCase(Locale.ROOT));
r.append(": at offset "); //$NON-NLS-1$
r.append(getOffset());
r.append(": "); //$NON-NLS-1$

View File

@ -43,6 +43,8 @@
package org.eclipse.jgit.revwalk;
import java.util.Locale;
import org.eclipse.jgit.lib.Constants;
/** Case insensitive key for a {@link FooterLine}. */
@ -68,7 +70,7 @@ public final class FooterKey {
*/
public FooterKey(final String keyName) {
name = keyName;
raw = Constants.encode(keyName.toLowerCase());
raw = Constants.encode(keyName.toLowerCase(Locale.ROOT));
}
/** @return name of this footer line. */

View File

@ -45,6 +45,7 @@
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Locale;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator;
@ -663,7 +664,8 @@ public IgnoreSubmoduleMode getModulesIgnore() throws IOException,
ConfigConstants.CONFIG_KEY_IGNORE);
if (name == null)
return null;
return IgnoreSubmoduleMode.valueOf(name.trim().toUpperCase());
return IgnoreSubmoduleMode
.valueOf(name.trim().toUpperCase(Locale.ROOT));
}
/**

View File

@ -56,6 +56,7 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
@ -168,7 +169,8 @@ static HttpAuthMethod scanResponse(final HttpConnection conn,
SCHEMA_NAME_SEPARATOR, 2);
try {
Type methodType = Type.valueOf(valuePart[0].toUpperCase());
Type methodType = Type.valueOf(
valuePart[0].toUpperCase(Locale.ROOT));
if ((ignoreTypes != null)
&& (ignoreTypes.contains(methodType))) {
@ -540,7 +542,7 @@ void configureRequest(HttpConnection conn) throws IOException {
GSSManager gssManager = GSS_MANAGER_FACTORY.newInstance(conn
.getURL());
String host = conn.getURL().getHost();
String peerName = "HTTP@" + host.toLowerCase(); //$NON-NLS-1$
String peerName = "HTTP@" + host.toLowerCase(Locale.ROOT); //$NON-NLS-1$
try {
GSSName gssName = gssManager.createName(peerName,
GSSName.NT_HOSTBASED_SERVICE);

View File

@ -48,6 +48,7 @@
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
@ -230,7 +231,7 @@ private void parse() {
matcher.reset(line);
while (matcher.find()) {
String command = matcher.group().toLowerCase();
String command = matcher.group().toLowerCase(Locale.ROOT);
if (command.startsWith("#")) { //$NON-NLS-1$
matcher.reset(""); //$NON-NLS-1$
continue;

View File

@ -56,6 +56,7 @@
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
@ -217,11 +218,12 @@ private class ExtSession implements RemoteSession {
public Process exec(String command, int timeout)
throws TransportException {
String ssh = SystemReader.getInstance().getenv("GIT_SSH"); //$NON-NLS-1$
boolean putty = ssh.toLowerCase().contains("plink"); //$NON-NLS-1$
boolean putty = ssh.toLowerCase(Locale.ROOT).contains("plink"); //$NON-NLS-1$
List<String> args = new ArrayList<String>();
args.add(ssh);
if (putty && !ssh.toLowerCase().contains("tortoiseplink")) //$NON-NLS-1$
if (putty
&& !ssh.toLowerCase(Locale.ROOT).contains("tortoiseplink")) //$NON-NLS-1$
args.add("-batch"); //$NON-NLS-1$
if (0 < getURI().getPort()) {
args.add(putty ? "-P" : "-p"); //$NON-NLS-1$ //$NON-NLS-2$

View File

@ -52,6 +52,7 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -192,7 +193,7 @@ static class JetS3tV2 extends WalkEncryption {
// Standard names are not case-sensitive.
// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
String cryptoName = cryptoAlg.toUpperCase();
String cryptoName = cryptoAlg.toUpperCase(Locale.ROOT);
if (!cryptoName.startsWith("PBE")) //$NON-NLS-1$
throw new GeneralSecurityException(JGitText.get().encryptionOnlyPBE);
@ -373,7 +374,7 @@ static abstract class SymmetricEncryption extends WalkEncryption
SecretKey keyBase = factory.generateSecret(keySpec);
String name = cipherAlgo.toUpperCase();
String name = cipherAlgo.toUpperCase(Locale.ROOT);
Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
Matcher matcherTrans = Pattern.compile(REGEX_TRANS).matcher(name);
if (matcherPBE.matches()) {
@ -506,7 +507,7 @@ static Properties wrap(String algo, String pass) {
JGitV1(String algo, String pass)
throws GeneralSecurityException {
super(wrap(algo, pass));
String name = cipherAlgo.toUpperCase();
String name = cipherAlgo.toUpperCase(Locale.ROOT);
Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
if (!matcherPBE.matches())
throw new GeneralSecurityException(

View File

@ -65,6 +65,7 @@
import java.text.Normalizer.Form;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import org.eclipse.jgit.internal.JGitText;
@ -542,7 +543,8 @@ else if (!ignoreCase
public static boolean isStaleFileHandle(IOException ioe) {
String msg = ioe.getMessage();
return msg != null
&& msg.toLowerCase().matches("stale .*file .*handle"); //$NON-NLS-1$
&& msg.toLowerCase(Locale.ROOT)
.matches("stale .*file .*handle"); //$NON-NLS-1$
}
/**