Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.
/ jdk18u Public archive

Commit

Permalink
8285517: System.getenv() returns unexpected value if environment vari…
Browse files Browse the repository at this point in the history
…able has non ASCII character

Backport-of: 890771e708277c5f7ea9460ff7bcc7e4cae87eab
  • Loading branch information
Ichiroh Takiguchi committed May 31, 2022
1 parent 0928c06 commit 751cadc
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 47 deletions.
78 changes: 40 additions & 38 deletions src/java.base/share/classes/jdk/internal/util/StaticProperty.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -26,12 +26,13 @@
package jdk.internal.util;

import java.util.Properties;
import java.nio.charset.Charset;

/**
* System Property access for internal use only.
* Read-only access to System property values initialized during Phase 1
* are cached. Setting, clearing, or modifying the value using
* {@link System#setProperty) or {@link System#getProperties()} is ignored.
* {@link System#setProperty} or {@link System#getProperties()} is ignored.
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in these access methods. The caller of these methods should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
Expand All @@ -52,6 +53,8 @@ public final class StaticProperty {
private static final String NATIVE_ENCODING;
private static final String FILE_ENCODING;
private static final String JAVA_PROPERTIES_DATE;
private static final String SUN_JNU_ENCODING;
private static final Charset jnuCharset;

private StaticProperty() {}

Expand All @@ -69,6 +72,8 @@ private StaticProperty() {}
NATIVE_ENCODING = getProperty(props, "native.encoding");
FILE_ENCODING = getProperty(props, "file.encoding");
JAVA_PROPERTIES_DATE = getProperty(props, "java.properties.date", null);
SUN_JNU_ENCODING = getProperty(props, "sun.jnu.encoding");
jnuCharset = Charset.forName(SUN_JNU_ENCODING, Charset.defaultCharset());
}

private static String getProperty(Properties props, String key) {
Expand All @@ -86,159 +91,156 @@ private static String getProperty(Properties props, String key,
}

/**
* Return the {@code java.home} system property.
* {@return the {@code java.home} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code java.home} system property
*/
public static String javaHome() {
return JAVA_HOME;
}

/**
* Return the {@code user.home} system property.
* {@return the {@code user.home} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.home} system property
*/
public static String userHome() {
return USER_HOME;
}

/**
* Return the {@code user.dir} system property.
* {@return the {@code user.dir} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.dir} system property
*/
public static String userDir() {
return USER_DIR;
}

/**
* Return the {@code user.name} system property.
* {@return the {@code user.name} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.name} system property
*/
public static String userName() {
return USER_NAME;
}

/**
* Return the {@code java.library.path} system property.
* {@return the {@code java.library.path} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code java.library.path} system property
*/
public static String javaLibraryPath() {
return JAVA_LIBRARY_PATH;
}

/**
* Return the {@code java.io.tmpdir} system property.
* {@return the {@code java.io.tmpdir} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code java.io.tmpdir} system property
*/
public static String javaIoTmpDir() {
return JAVA_IO_TMPDIR;
}

/**
* Return the {@code sun.boot.library.path} system property.
* {@return the {@code sun.boot.library.path} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code sun.boot.library.path} system property
*/
public static String sunBootLibraryPath() {
return SUN_BOOT_LIBRARY_PATH;
}


/**
* Return the {@code jdk.serialFilter} system property.
* {@return the {@code jdk.serialFilter} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code jdk.serialFilter} system property
*/
public static String jdkSerialFilter() {
return JDK_SERIAL_FILTER;
}


/**
* Return the {@code jdk.serialFilterFactory} system property.
* {@return the {@code jdk.serialFilterFactory} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code jdk.serialFilterFactory} system property
*/
public static String jdkSerialFilterFactory() {
return JDK_SERIAL_FILTER_FACTORY;
}

/**
* Return the {@code native.encoding} system property.
* {@return the {@code native.encoding} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code native.encoding} system property
*/
public static String nativeEncoding() {
return NATIVE_ENCODING;
}

/**
* Return the {@code file.encoding} system property.
* {@return the {@code file.encoding} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code file.encoding} system property
*/
public static String fileEncoding() {
return FILE_ENCODING;
}

/**
* Return the {@code java.properties.date} system property.
* {@return the {@code java.properties.date} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method.</strong>
*
* @return the {@code java.properties.date} system property
*/
public static String javaPropertiesDate() {
return JAVA_PROPERTIES_DATE;
}

/**
* {@return the {@code sun.jnu.encoding} system property}
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*/
public static String jnuEncoding() {
return SUN_JNU_ENCODING;
}

/**
* {@return {@code Charset} for {@code sun.jnu.encoding} system property}
*
* <strong>If {@code sun.jnu.encoding} system property has invalid
* encoding name, {@link Charset#defaultCharset()} is returned.</strong>
*/
public static Charset jnuCharset() {
return jnuCharset;
}
}
12 changes: 7 additions & 5 deletions src/java.base/unix/classes/java/lang/ProcessEnvironment.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -55,7 +55,9 @@
package java.lang;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import jdk.internal.util.StaticProperty;


final class ProcessEnvironment
Expand Down Expand Up @@ -163,7 +165,7 @@ public static Variable valueOfQueryOnly(Object str) {
}

public static Variable valueOfQueryOnly(String str) {
return new Variable(str, str.getBytes());
return new Variable(str, str.getBytes(StaticProperty.jnuCharset()));
}

public static Variable valueOf(String str) {
Expand All @@ -172,7 +174,7 @@ public static Variable valueOf(String str) {
}

public static Variable valueOf(byte[] bytes) {
return new Variable(new String(bytes), bytes);
return new Variable(new String(bytes, StaticProperty.jnuCharset()), bytes);
}

public int compareTo(Variable variable) {
Expand All @@ -196,7 +198,7 @@ public static Value valueOfQueryOnly(Object str) {
}

public static Value valueOfQueryOnly(String str) {
return new Value(str, str.getBytes());
return new Value(str, str.getBytes(StaticProperty.jnuCharset()));
}

public static Value valueOf(String str) {
Expand All @@ -205,7 +207,7 @@ public static Value valueOf(String str) {
}

public static Value valueOf(byte[] bytes) {
return new Value(new String(bytes), bytes);
return new Value(new String(bytes, StaticProperty.jnuCharset()), bytes);
}

public int compareTo(Value value) {
Expand Down
5 changes: 3 additions & 2 deletions src/java.base/unix/classes/java/lang/ProcessImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Locale;
Expand Down Expand Up @@ -147,7 +148,7 @@ static Platform get() {
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] bytes = s.getBytes(StaticProperty.jnuCharset());
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
Expand All @@ -171,7 +172,7 @@ static Process start(String[] cmdarray,
byte[][] args = new byte[cmdarray.length-1][];
int size = args.length; // For added NUL bytes
for (int i = 0; i < args.length; i++) {
args[i] = cmdarray[i+1].getBytes();
args[i] = cmdarray[i+1].getBytes(StaticProperty.jnuCharset());
size += args[i].length;
}
byte[] argBlock = new byte[size];
Expand Down
9 changes: 7 additions & 2 deletions test/jdk/java/lang/ProcessBuilder/Basic.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* 4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464
* 8067796 8224905 8263729 8265173 8272600 8231297 8282219
* 8067796 8224905 8263729 8265173 8272600 8231297 8282219 8285517
* @key intermittent
* @summary Basic tests for Process and Environment Variable code
* @modules java.base/java.lang:open
Expand All @@ -50,6 +50,7 @@
import static java.lang.ProcessBuilder.Redirect.*;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -598,7 +599,11 @@ private static void testEncoding(String encoding, String tested) {
try {
// If round trip conversion works, should be able to set env vars
// correctly in child.
if (new String(tested.getBytes()).equals(tested)) {
String jnuEncoding = System.getProperty("sun.jnu.encoding");
Charset cs = jnuEncoding != null
? Charset.forName(jnuEncoding, Charset.defaultCharset())
: Charset.defaultCharset();
if (new String(tested.getBytes(cs), cs).equals(tested)) {
out.println("Testing " + encoding + " environment values");
ProcessBuilder pb = new ProcessBuilder();
pb.environment().put("ASCIINAME",tested);
Expand Down
Loading

1 comment on commit 751cadc

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.