Make NULs work for builtins (#9859)

* Make NULs work for builtins

This switches from passing a c-string to output_stream_t::append to
passing a proper string.

That means a builtin that prints a NUL no longer crashes with "thread '' panicked
at 'String contained intermediate NUL character: ".

Instead, it will actually handle the NUL, even as an argument.

That means something like

`echo foo\x00bar` will now actually print a NUL instead of truncating
after the `foo` because we passed c-strings around everywhere.

The former is *necessary* for e.g. `string`, the latter is a change
that on the whole makes dealing with NULs easier, but it is a
behavioral change.

To restore the c-string behavior we would have to truncate arguments
at NUL.

See #9739.

* Use AsRef instead of trait bound
This commit is contained in:
Fabian Boehm 2023-06-22 20:50:22 +02:00 committed by GitHub
parent a75de42f4b
commit 11c8d9684e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 8 additions and 3 deletions

View File

@ -1,7 +1,7 @@
use crate::builtins::{printf, wait};
use crate::ffi::{self, parser_t, wcstring_list_ffi_t, Repin, RustBuiltin};
use crate::wchar::{wstr, WString, L};
use crate::wchar_ffi::{c_str, empty_wstring, WCharFromFFI};
use crate::wchar_ffi::{c_str, empty_wstring, ToCppWString, WCharFromFFI};
use crate::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t};
use libc::c_int;
use std::os::fd::RawFd;
@ -86,9 +86,9 @@ impl output_stream_t {
unsafe { (*self.0).pin() }
}
/// Append a &wtr or WString.
/// Append a &wstr or WString.
pub fn append<Str: AsRef<wstr>>(&mut self, s: Str) -> bool {
self.ffi().append1(c_str!(s))
self.ffi().append(&s.as_ref().into_cpp())
}
/// Append a char.

View File

@ -955,3 +955,8 @@ string shorten -m0 foo bar asodjsaoidj
# CHECK: foo
# CHECK: bar
# CHECK: asodjsaoidj
echo foo\x00bar | string escape
# CHECK: foo\x00bar
echo foo\\x00bar | string escape
# CHECK: foo\\x00bar