Hi,

we've recently discovered a problem with Console.readPassword() which
failed to restore the correct echo mode on Linux/s390x [1]. We could
finally track this down to a "bug" [2] in the s390x template
interpreter which failed to call the "result handler" after a native
call. For jboolean return types, the "result handler" merges all
values > 0 into 1 (i.e. JNI_TRUE). Not calling the result handler
after returning from native calls resulted in cases where non-zero
jboolean values returned from native functions where interpreted as
zero (i.e. JNI_FALSE).

The offending code in Console_md.c looks as follows:

#define ECHO    8

JNIEXPORT jboolean JNICALL
Java_java_io_Console_echo(...) {

    jboolean old;
    ...
    old = (tio.c_lflag & ECHO);
    ...
    return old;
}

The intention of this code is to return "true" if the ECHO flag was
set but it really returns the value of ECHO (which is defined as '8'
in a system header).

The question now is, if a Java SE compatible VM guarantees that any
arbitrary, non-zero valued jboolean will be interpreted as "JNI_TRUE"
and only a zero valued jboolean will be interpreted as "JNI_FALSE"?

Or, the other way round, is the normalization performed by the HotSpot
result handlers necessary (i.e. enforced by the specification) or just
a convenience to fix broken code like the above from Console.echo()?

All I could find from the Specification so far is the following, which
seems to suggest that only JNI_TRUE/JNI_FASLE are valid values for a
jboolean, but I'm not completely sure...

From: JNI Types and Data Structures [3]

Java "boolean" == JNI "jboolean" == unsigned 8 bits

The following definition is provided for convenience.

#define JNI_FALSE  0
#define JNI_TRUE   1

From: JVMLS, ยง 2.3.4. The boolean Type [4]

Although the Java Virtual Machine defines a boolean type, it only
provides very limited support for it. There are no Java Virtual
Machine instructions solely dedicated to operations on boolean values.
Instead, expressions in the Java programming language that operate on
boolean values are compiled to use values of the Java Virtual Machine
int data type.

The Java Virtual Machine encodes boolean array components using 1 to
represent true and 0 to represent false. Where Java programming
language boolean values are mapped by compilers to values of Java
Virtual Machine type int, the compilers must use the same encoding.

Thank you and best regards,
Volker

[1] 
http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-July/thread.html#54479
[2] https://bugs.openjdk.java.net/browse/JDK-8209637
[3] https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
[4] https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.3.4

Reply via email to