mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
rust: warn about bindgen
versions 0.66.0 and 0.66.1
`bindgen` versions 0.66.0 and 0.66.1 panic due to C string literals with NUL characters [1]: panicked at .cargo/registry/src/index.crates.io-6f17d22bba15001f/bindgen-0.66.0/codegen/mod.rs:717:71: called `Result::unwrap()` on an `Err` value: FromBytesWithNulError { kind: InteriorNul(4) } Thus, in preparation for supporting several `bindgen` versions, add a version check to warn the user about it. Since some distributions may have patched it (e.g. Debian did [2]), check if that seems to be the case (after the version check matches), in order to avoid printing a warning in that case. We could make it an error, but 1) it is going to fail anyway later in the build, 2) we would disable `RUST`, which is also painful, 3) someone could have patched it in a way that still makes our extra check fail (however unlikely), 4) the interior NUL may go away in the headers (however unlikely). Thus just warn about it so that users know why it is failing. In addition, add a couple tests for the new cases. Link: https://github.com/rust-lang/rust-bindgen/pull/2567 [1] Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1069047 [2] Link: https://lore.kernel.org/r/20240709160615.998336-11-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
c844fa64a2
commit
981ad93c89
@ -161,6 +161,19 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers
|
|||||||
echo >&2 "***"
|
echo >&2 "***"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [ "$rust_bindings_generator_cversion" -eq 6600 ] ||
|
||||||
|
[ "$rust_bindings_generator_cversion" -eq 6601 ]; then
|
||||||
|
# Distributions may have patched the issue (e.g. Debian did).
|
||||||
|
if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_0_66.h >/dev/null; then
|
||||||
|
echo >&2 "***"
|
||||||
|
echo >&2 "*** Rust bindings generator '$BINDGEN' versions 0.66.0 and 0.66.1 may not"
|
||||||
|
echo >&2 "*** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567),"
|
||||||
|
echo >&2 "*** unless patched (like Debian's)."
|
||||||
|
echo >&2 "*** Your version: $rust_bindings_generator_version"
|
||||||
|
echo >&2 "***"
|
||||||
|
warning=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Check that the `libclang` used by the Rust bindings generator is suitable.
|
# Check that the `libclang` used by the Rust bindings generator is suitable.
|
||||||
#
|
#
|
||||||
|
2
scripts/rust_is_available_bindgen_0_66.h
Normal file
2
scripts/rust_is_available_bindgen_0_66.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#define A "\0"
|
@ -54,23 +54,30 @@ else:
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_bindgen(cls, version_stdout, libclang_stderr):
|
def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False):
|
||||||
if libclang_stderr is None:
|
if libclang_stderr is None:
|
||||||
libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
|
libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
|
||||||
else:
|
else:
|
||||||
libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)"
|
libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)"
|
||||||
|
|
||||||
|
if version_0_66_patched:
|
||||||
|
version_0_66_case = "pass"
|
||||||
|
else:
|
||||||
|
version_0_66_case = "raise SystemExit(1)"
|
||||||
|
|
||||||
return cls.generate_executable(f"""#!/usr/bin/env python3
|
return cls.generate_executable(f"""#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
|
if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
|
||||||
{libclang_case}
|
{libclang_case}
|
||||||
|
elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv):
|
||||||
|
{version_0_66_case}
|
||||||
else:
|
else:
|
||||||
print({repr(version_stdout)})
|
print({repr(version_stdout)})
|
||||||
""")
|
""")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_bindgen_version(cls, stdout):
|
def generate_bindgen_version(cls, stdout, version_0_66_patched=False):
|
||||||
return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr)
|
return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr, version_0_66_patched)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_bindgen_libclang_failure(cls):
|
def generate_bindgen_libclang_failure(cls):
|
||||||
@ -231,6 +238,19 @@ else:
|
|||||||
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
|
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
|
||||||
self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr)
|
self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr)
|
||||||
|
|
||||||
|
def test_bindgen_bad_version_0_66_0_and_0_66_1(self):
|
||||||
|
for version in ("0.66.0", "0.66.1"):
|
||||||
|
with self.subTest(version=version):
|
||||||
|
bindgen = self.generate_bindgen_version(f"bindgen {version}")
|
||||||
|
result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
|
||||||
|
self.assertIn(f"Rust bindings generator '{bindgen}' versions 0.66.0 and 0.66.1 may not", result.stderr)
|
||||||
|
|
||||||
|
def test_bindgen_bad_version_0_66_0_and_0_66_1_patched(self):
|
||||||
|
for version in ("0.66.0", "0.66.1"):
|
||||||
|
with self.subTest(version=version):
|
||||||
|
bindgen = self.generate_bindgen_version(f"bindgen {version}", True)
|
||||||
|
result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen })
|
||||||
|
|
||||||
def test_bindgen_libclang_failure(self):
|
def test_bindgen_libclang_failure(self):
|
||||||
bindgen = self.generate_bindgen_libclang_failure()
|
bindgen = self.generate_bindgen_libclang_failure()
|
||||||
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
|
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
|
||||||
|
Loading…
Reference in New Issue
Block a user