Skip to content

Commit 32b6616

Browse files
ojedajannau
authored andcommitted
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: rust-lang/rust-bindgen#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>
1 parent 53ea91e commit 32b6616

3 files changed

+38
-3
lines changed

scripts/rust_is_available.sh

+13
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,19 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers
161161
echo >&2 "***"
162162
exit 1
163163
fi
164+
if [ "$rust_bindings_generator_cversion" -eq 6600 ] ||
165+
[ "$rust_bindings_generator_cversion" -eq 6601 ]; then
166+
# Distributions may have patched the issue (e.g. Debian did).
167+
if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_0_66.h >/dev/null; then
168+
echo >&2 "***"
169+
echo >&2 "*** Rust bindings generator '$BINDGEN' versions 0.66.0 and 0.66.1 may not"
170+
echo >&2 "*** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567),"
171+
echo >&2 "*** unless patched (like Debian's)."
172+
echo >&2 "*** Your version: $rust_bindings_generator_version"
173+
echo >&2 "***"
174+
warning=1
175+
fi
176+
fi
164177

165178
# Check that the `libclang` used by the Rust bindings generator is suitable.
166179
#
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#define A "\0"

scripts/rust_is_available_test.py

+23-3
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,30 @@ def generate_rustc(cls, stdout):
5454
""")
5555

5656
@classmethod
57-
def generate_bindgen(cls, version_stdout, libclang_stderr):
57+
def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False):
5858
if libclang_stderr is None:
5959
libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
6060
else:
6161
libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)"
6262

63+
if version_0_66_patched:
64+
version_0_66_case = "pass"
65+
else:
66+
version_0_66_case = "raise SystemExit(1)"
67+
6368
return cls.generate_executable(f"""#!/usr/bin/env python3
6469
import sys
6570
if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
6671
{libclang_case}
72+
elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv):
73+
{version_0_66_case}
6774
else:
6875
print({repr(version_stdout)})
6976
""")
7077

7178
@classmethod
72-
def generate_bindgen_version(cls, stdout):
73-
return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr)
79+
def generate_bindgen_version(cls, stdout, version_0_66_patched=False):
80+
return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr, version_0_66_patched)
7481

7582
@classmethod
7683
def generate_bindgen_libclang_failure(cls):
@@ -231,6 +238,19 @@ def test_bindgen_old_version(self):
231238
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
232239
self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr)
233240

241+
def test_bindgen_bad_version_0_66_0_and_0_66_1(self):
242+
for version in ("0.66.0", "0.66.1"):
243+
with self.subTest(version=version):
244+
bindgen = self.generate_bindgen_version(f"bindgen {version}")
245+
result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
246+
self.assertIn(f"Rust bindings generator '{bindgen}' versions 0.66.0 and 0.66.1 may not", result.stderr)
247+
248+
def test_bindgen_bad_version_0_66_0_and_0_66_1_patched(self):
249+
for version in ("0.66.0", "0.66.1"):
250+
with self.subTest(version=version):
251+
bindgen = self.generate_bindgen_version(f"bindgen {version}", True)
252+
result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen })
253+
234254
def test_bindgen_libclang_failure(self):
235255
bindgen = self.generate_bindgen_libclang_failure()
236256
result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })

0 commit comments

Comments
 (0)