Don't rely on an implicit default character set
JEP 400 (Java 18) will change the default character set to UTF-8 unconditionally.[1] Introduce SystemReader.getDefaultCharset() that provides the locale-dependent charset the way JEP 400 recommends. Change all code locations using Charset.defaultCharset() to use the new SystemReader method instead. [1] https://openjdk.java.net/jeps/400 Change-Id: I986f97a410d2fc70748b6f93228a2d45ff100b2c Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
ff3c3d8ff5
commit
fc6fe793ce
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -182,7 +181,7 @@ public void testReadPipePosixCommandFailure()
|
||||||
|
|
||||||
FS.readPipe(fs.userHome(),
|
FS.readPipe(fs.userHome(),
|
||||||
new String[] { "/bin/sh", "-c", "exit 1" },
|
new String[] { "/bin/sh", "-c", "exit 1" },
|
||||||
Charset.defaultCharset().name());
|
SystemReader.getInstance().getDefaultCharset().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = CommandFailedException.class)
|
@Test(expected = CommandFailedException.class)
|
||||||
|
@ -192,7 +191,7 @@ public void testReadPipeCommandStartFailure()
|
||||||
|
|
||||||
FS.readPipe(fs.userHome(),
|
FS.readPipe(fs.userHome(),
|
||||||
new String[] { "this-command-does-not-exist" },
|
new String[] { "this-command-does-not-exist" },
|
||||||
Charset.defaultCharset().name());
|
SystemReader.getInstance().getDefaultCharset().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -440,6 +440,7 @@ lockOnNotHeld=Lock on {0} not held.
|
||||||
lockStreamClosed=Output to lock on {0} already closed
|
lockStreamClosed=Output to lock on {0} already closed
|
||||||
lockStreamMultiple=Output to lock on {0} already opened
|
lockStreamMultiple=Output to lock on {0} already opened
|
||||||
logInconsistentFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: {} > {}, but diff = {}. Aborting measurement at resolution {}.
|
logInconsistentFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: {} > {}, but diff = {}. Aborting measurement at resolution {}.
|
||||||
|
logInvalidDefaultCharset=System property "native.encoding" specifies unknown character set: {}
|
||||||
logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement.
|
logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement.
|
||||||
logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}.
|
logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}.
|
||||||
logXDGConfigHomeInvalid=Environment variable XDG_CONFIG_HOME contains an invalid path {}
|
logXDGConfigHomeInvalid=Environment variable XDG_CONFIG_HOME contains an invalid path {}
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import org.eclipse.jgit.api.errors.AbortedByHookException;
|
import org.eclipse.jgit.api.errors.AbortedByHookException;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.util.FS;
|
import org.eclipse.jgit.util.FS;
|
||||||
import org.eclipse.jgit.util.ProcessResult;
|
import org.eclipse.jgit.util.ProcessResult;
|
||||||
|
import org.eclipse.jgit.util.SystemReader;
|
||||||
import org.eclipse.jgit.util.io.TeeOutputStream;
|
import org.eclipse.jgit.util.io.TeeOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +171,8 @@ protected void doRun() throws AbortedByHookException, IOException {
|
||||||
getStdinArgs());
|
getStdinArgs());
|
||||||
if (result.isExecutedWithError()) {
|
if (result.isExecutedWithError()) {
|
||||||
handleError(new String(errorByteArray.toByteArray(),
|
handleError(new String(errorByteArray.toByteArray(),
|
||||||
Charset.defaultCharset().name()), result);
|
SystemReader.getInstance().getDefaultCharset().name()),
|
||||||
|
result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -468,6 +468,7 @@ public static JGitText get() {
|
||||||
/***/ public String lockStreamClosed;
|
/***/ public String lockStreamClosed;
|
||||||
/***/ public String lockStreamMultiple;
|
/***/ public String lockStreamMultiple;
|
||||||
/***/ public String logInconsistentFiletimeDiff;
|
/***/ public String logInconsistentFiletimeDiff;
|
||||||
|
/***/ public String logInvalidDefaultCharset;
|
||||||
/***/ public String logLargerFiletimeDiff;
|
/***/ public String logLargerFiletimeDiff;
|
||||||
/***/ public String logSmallerFiletime;
|
/***/ public String logSmallerFiletime;
|
||||||
/***/ public String logXDGConfigHomeInvalid;
|
/***/ public String logXDGConfigHomeInvalid;
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.file.AccessDeniedException;
|
import java.nio.file.AccessDeniedException;
|
||||||
import java.nio.file.FileStore;
|
import java.nio.file.FileStore;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -1507,7 +1506,7 @@ protected File discoverGitSystemConfig() {
|
||||||
try {
|
try {
|
||||||
v = readPipe(gitExe.getParentFile(),
|
v = readPipe(gitExe.getParentFile(),
|
||||||
new String[] { gitExe.getPath(), "--version" }, //$NON-NLS-1$
|
new String[] { gitExe.getPath(), "--version" }, //$NON-NLS-1$
|
||||||
Charset.defaultCharset().name());
|
SystemReader.getInstance().getDefaultCharset().name());
|
||||||
} catch (CommandFailedException e) {
|
} catch (CommandFailedException e) {
|
||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
@ -1527,7 +1526,7 @@ protected File discoverGitSystemConfig() {
|
||||||
w = readPipe(gitExe.getParentFile(),
|
w = readPipe(gitExe.getParentFile(),
|
||||||
new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$
|
new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
"--edit" }, //$NON-NLS-1$
|
"--edit" }, //$NON-NLS-1$
|
||||||
Charset.defaultCharset().name(), env);
|
SystemReader.getInstance().getDefaultCharset().name(), env);
|
||||||
} catch (CommandFailedException e) {
|
} catch (CommandFailedException e) {
|
||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.FileStore;
|
import java.nio.file.FileStore;
|
||||||
import java.nio.file.FileSystemException;
|
import java.nio.file.FileSystemException;
|
||||||
|
@ -119,8 +118,8 @@ private static int readUmask() {
|
||||||
new String[] { "sh", "-c", "umask" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
new String[] { "sh", "-c", "umask" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
null, null);
|
null, null);
|
||||||
try (BufferedReader lineRead = new BufferedReader(
|
try (BufferedReader lineRead = new BufferedReader(
|
||||||
new InputStreamReader(p.getInputStream(), Charset
|
new InputStreamReader(p.getInputStream(), SystemReader
|
||||||
.defaultCharset().name()))) {
|
.getInstance().getDefaultCharset().name()))) {
|
||||||
if (p.waitFor() == 0) {
|
if (p.waitFor() == 0) {
|
||||||
String s = lineRead.readLine();
|
String s = lineRead.readLine();
|
||||||
if (s != null && s.matches("0?\\d{3}")) { //$NON-NLS-1$
|
if (s != null && s.matches("0?\\d{3}")) { //$NON-NLS-1$
|
||||||
|
@ -150,7 +149,8 @@ protected File discoverGitExe() {
|
||||||
try {
|
try {
|
||||||
String w = readPipe(userHome(),
|
String w = readPipe(userHome(),
|
||||||
new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||||
Charset.defaultCharset().name());
|
SystemReader.getInstance().getDefaultCharset()
|
||||||
|
.name());
|
||||||
if (!StringUtils.isEmptyOrNull(w)) {
|
if (!StringUtils.isEmptyOrNull(w)) {
|
||||||
gitExe = new File(w);
|
gitExe = new File(w);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,8 @@ protected File discoverGitExe() {
|
||||||
try {
|
try {
|
||||||
String w = readPipe(userHome(),
|
String w = readPipe(userHome(),
|
||||||
new String[] { "xcode-select", "-p" }, //$NON-NLS-1$ //$NON-NLS-2$
|
new String[] { "xcode-select", "-p" }, //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
Charset.defaultCharset().name());
|
SystemReader.getInstance().getDefaultCharset()
|
||||||
|
.name());
|
||||||
if (StringUtils.isEmptyOrNull(w)) {
|
if (StringUtils.isEmptyOrNull(w)) {
|
||||||
gitExe = null;
|
gitExe = null;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.file.FileVisitOption;
|
import java.nio.file.FileVisitOption;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -150,8 +149,10 @@ protected File discoverGitExe() {
|
||||||
String w;
|
String w;
|
||||||
try {
|
try {
|
||||||
w = readPipe(userHome(),
|
w = readPipe(userHome(),
|
||||||
new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
new String[] { "bash", "--login", "-c", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
Charset.defaultCharset().name());
|
"which git" }, // //$NON-NLS-1$
|
||||||
|
SystemReader.getInstance().getDefaultCharset()
|
||||||
|
.name());
|
||||||
} catch (CommandFailedException e) {
|
} catch (CommandFailedException e) {
|
||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ public static String decodeNoFallback(final Charset cs,
|
||||||
|
|
||||||
// Try the default character set. A small group of people
|
// Try the default character set. A small group of people
|
||||||
// might actually use the same (or very similar) locale.
|
// might actually use the same (or very similar) locale.
|
||||||
Charset defcs = Charset.defaultCharset();
|
Charset defcs = SystemReader.getInstance().getDefaultCharset();
|
||||||
if (!defcs.equals(cs) && !defcs.equals(UTF_8)) {
|
if (!defcs.equals(cs) && !defcs.equals(UTF_8)) {
|
||||||
try {
|
try {
|
||||||
return decode(b, defcs);
|
return decode(b, defcs);
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.IllegalCharsetNameException;
|
||||||
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -198,6 +201,8 @@ public static void setInstance(SystemReader newReader) {
|
||||||
|
|
||||||
private AtomicReference<FileBasedConfig> jgitConfig = new AtomicReference<>();
|
private AtomicReference<FileBasedConfig> jgitConfig = new AtomicReference<>();
|
||||||
|
|
||||||
|
private volatile Charset defaultCharset;
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
// Creating ObjectChecker must be deferred. Unit tests change
|
// Creating ObjectChecker must be deferred. Unit tests change
|
||||||
// behavior of is{Windows,MacOS} in constructor of subclass.
|
// behavior of is{Windows,MacOS} in constructor of subclass.
|
||||||
|
@ -438,6 +443,35 @@ public Locale getLocale() {
|
||||||
return Locale.getDefault();
|
return Locale.getDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the default {@link Charset} depending on the system locale.
|
||||||
|
*
|
||||||
|
* @return the {@link Charset}
|
||||||
|
* @since 6.0
|
||||||
|
* @see <a href="https://openjdk.java.net/jeps/400">JEP 400</a>
|
||||||
|
*/
|
||||||
|
public Charset getDefaultCharset() {
|
||||||
|
Charset result = defaultCharset;
|
||||||
|
if (result == null) {
|
||||||
|
// JEP 400: Java 18 populates this system property.
|
||||||
|
String encoding = getProperty("native.encoding"); //$NON-NLS-1$
|
||||||
|
try {
|
||||||
|
if (!StringUtils.isEmptyOrNull(encoding)) {
|
||||||
|
result = Charset.forName(encoding);
|
||||||
|
}
|
||||||
|
} catch (IllegalCharsetNameException
|
||||||
|
| UnsupportedCharsetException e) {
|
||||||
|
LOG.error(JGitText.get().logInvalidDefaultCharset, encoding);
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
// This is always UTF-8 on Java >= 18.
|
||||||
|
result = Charset.defaultCharset();
|
||||||
|
}
|
||||||
|
defaultCharset = result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a simple date format instance as specified by the given pattern.
|
* Returns a simple date format instance as specified by the given pattern.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue