Skip to content

Commit b4b2b10

Browse files
committed
Parse PYTHONHASHSEED using OptionType
1 parent d347597 commit b4b2b10

File tree

3 files changed

+32
-24
lines changed

3 files changed

+32
-24
lines changed

graalpython/com.oracle.graal.python.cext/src/traceback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,5 @@ int PyTraceBack_Here(PyFrameObject *frame) {
5050

5151
UPCALL_ID(_PyTraceback_Add)
5252
void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) {
53-
return UPCALL_CEXT_VOID(_jls__PyTraceback_Add, polyglot_from_string(funcname, SRC_CS), polyglot_from_string(filename, SRC_CS), lineno);
53+
UPCALL_CEXT_VOID(_jls__PyTraceback_Add, polyglot_from_string(funcname, SRC_CS), polyglot_from_string(filename, SRC_CS), lineno);
5454
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import java.util.LinkedList;
4949
import java.util.List;
5050
import java.util.Map;
51+
import java.util.Optional;
5152
import java.util.WeakHashMap;
5253
import java.util.concurrent.ConcurrentHashMap;
5354
import java.util.concurrent.ConcurrentSkipListMap;
@@ -1287,30 +1288,26 @@ private void setupRuntimeInformation(boolean isPatching) {
12871288
}
12881289

12891290
private void initializeHashSecret() {
1290-
String hashSeed = getOption(PythonOptions.HashSeed);
1291-
if (hashSeed.equals("random")) {
1292-
getSecureRandom().nextBytes(hashSecret);
1293-
} else {
1294-
try {
1295-
long hashSeedValue = Long.parseLong(hashSeed);
1296-
if (hashSeedValue < 0 || hashSeedValue > 4294967295L) {
1297-
throw new NumberFormatException();
1298-
}
1299-
// 0 disables the option, leaving the secret at 0
1300-
if (hashSeedValue != 0) {
1301-
// Generate the whole secret from the seed number the same way as CPython
1302-
// Taken from bootstrap_hash.c:lcg_urandom
1303-
int x = (int) hashSeedValue;
1304-
for (int i = 0; i < hashSecret.length; i++) {
1305-
x *= 214013;
1306-
x += 2531011;
1307-
/* modulo 2 ^ (8 * sizeof(int)) */
1308-
hashSecret[i] = (byte) ((x >>> 16) & 0xff);
1309-
}
1291+
assert !ImageInfo.inImageBuildtimeCode();
1292+
Optional<Integer> hashSeed = getOption(PythonOptions.HashSeed);
1293+
if (hashSeed.isPresent()) {
1294+
int hashSeedValue = hashSeed.get();
1295+
// 0 disables the option, leaving the secret at 0
1296+
if (hashSeedValue != 0) {
1297+
// Generate the whole secret from the seed number the same way as CPython
1298+
// Taken from bootstrap_hash.c:lcg_urandom
1299+
// hashSeedValue was parsed as unsigned integer
1300+
int x = hashSeedValue;
1301+
for (int i = 0; i < hashSecret.length; i++) {
1302+
x *= 214013;
1303+
x += 2531011;
1304+
/* modulo 2 ^ (8 * sizeof(int)) */
1305+
hashSecret[i] = (byte) ((x >>> 16) & 0xff);
13101306
}
1311-
} catch (NumberFormatException e) {
1312-
throw new RuntimeException("PYTHONHASHSEED must be \"random\" or an integer in range [0; 4294967295]");
13131307
}
1308+
} else {
1309+
// Generate random seed
1310+
getSecureRandom().nextBytes(hashSecret);
13141311
}
13151312
}
13161313

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.HashMap;
3636
import java.util.List;
3737
import java.util.Map;
38+
import java.util.Optional;
3839

3940
import org.graalvm.options.OptionCategory;
4041
import org.graalvm.options.OptionDescriptor;
@@ -136,7 +137,17 @@ private PythonOptions() {
136137
public static final OptionKey<String> WarnOptions = new OptionKey<>("");
137138

138139
@Option(category = OptionCategory.USER, help = "Equivalent to setting PYTHONHASHSEED environment variable", stability = OptionStability.STABLE) //
139-
public static final OptionKey<String> HashSeed = new OptionKey<>("random");
140+
public static final OptionKey<Optional<Integer>> HashSeed = new OptionKey<>(Optional.empty(),
141+
new OptionType<>("HashSeed", input -> {
142+
if ("random".equals(input)) {
143+
return Optional.empty();
144+
}
145+
try {
146+
return Optional.of(Integer.parseUnsignedInt(input));
147+
} catch (NumberFormatException e) {
148+
throw new IllegalArgumentException("PYTHONHASHSEED must be \"random\" or an integer in range [0; 4294967295]");
149+
}
150+
}));
140151

141152
@EngineOption @Option(category = OptionCategory.USER, help = "Choose the backend for the POSIX module. Valid values are 'java', 'native', 'llvm'.") //
142153
public static final OptionKey<String> PosixModuleBackend = new OptionKey<>("java");

0 commit comments

Comments
 (0)