Skip to content

Considering redefining jboolean as either an bool or our own #[repr(u8)] enum #19

@rib

Description

@rib

While looking at jni-rs/jni-rs#400 it was noted that there's a risk that code can easily cause undefined behaviour for the JVM by setting boolean array elements to values other than 0 or 1.

This isn't something that's specific to array elements though; anywhere that Rust returns a jboolean to Java it needs to ensure the byte value is either 0 or 1.

Since jboolean is currently simply an alias for u8 (pub type jboolean = u8;) then it's very easy to return arbitrary invalid boolean values to the JVM.

My initial thought was that we could represent a jboolean as:

#[repr(u8)]
enum jboolean {
    False=0,
    True=1
}

and it was then also noted by @argv-minus-one that this is essentially how the Rust Reference defines bool: https://doc.rust-lang.org/reference/types/boolean.html

My initial reservation with simply defining jboolean as an alias for bool is that Rust doesn't generally guarantee much in terms of stable ABI and I wouldn't like to potentially depending on an implementation detail. e.g. the Rust Reference says "this book is not normative. It may include details that are specific to rustc itself, and should not be taken as a specification for the Rust language."

It looks like historically bool was assumed to be defined in terms of the C _Bool type (and several FFI projects have made that assumption) which wouldn't technically guarantee that bool were one byte on all platforms, ref: https://internals.rust-lang.org/t/rusts-stability-story-should-apply-to-bool-in-ffi/6305/8

Considering the follow up discussion here: rust-lang/rust#46176 it looks like the consensus was that bool is defined to be the same as C's _Bool but it was also noted that that means it's one byte one all platforms supported by Rust.

A bool is also explicitly documented as being one byte here: https://doc.rust-lang.org/std/mem/fn.size_of.html

I think it's fair to conclude that Rust's bool type is basically guaranteed to always be 1 byte and to also use the values 1 and 0 for true and false - which is what we want for jboolean

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions