mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
uucore: use wasi OsStrExt/OsStringExt for byte-level access on wasm
WASI provides std::os::wasi::ffi::{OsStrExt, OsStringExt} with the same
as_bytes()/from_bytes()/into_vec()/from_vec() API as Unix. Without this,
os_str_as_bytes() fell into the not(unix) path requiring UTF-8 validation
via to_str(), causing failures like:
echo 'π,π,π,π₯' => "invalid UTF-8 input encountered"
This commit is contained in:
+16
-14
@@ -142,6 +142,8 @@ use std::io::{BufRead, BufReader};
|
||||
use std::iter;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
||||
#[cfg(target_os = "wasi")]
|
||||
use std::os::wasi::ffi::{OsStrExt, OsStringExt};
|
||||
use std::str;
|
||||
use std::str::Utf8Chunk;
|
||||
use std::sync::{LazyLock, atomic::Ordering};
|
||||
@@ -434,12 +436,12 @@ impl error::UError for NonUtf8OsStrError {}
|
||||
///
|
||||
/// This always succeeds on unix platforms,
|
||||
/// and fails on other platforms if the string can't be coerced to UTF-8.
|
||||
#[cfg_attr(unix, expect(clippy::unnecessary_wraps))]
|
||||
#[cfg_attr(any(unix, target_os = "wasi"), expect(clippy::unnecessary_wraps))]
|
||||
pub fn os_str_as_bytes(os_string: &OsStr) -> Result<&[u8], NonUtf8OsStrError> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
return Ok(os_string.as_bytes());
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
os_string
|
||||
.to_str()
|
||||
.ok_or_else(|| NonUtf8OsStrError {
|
||||
@@ -453,10 +455,10 @@ pub fn os_str_as_bytes(os_string: &OsStr) -> Result<&[u8], NonUtf8OsStrError> {
|
||||
/// This is always lossless on unix platforms,
|
||||
/// and wraps [`OsStr::to_string_lossy`] on non-unix platforms.
|
||||
pub fn os_str_as_bytes_lossy(os_string: &OsStr) -> Cow<'_, [u8]> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
return Cow::from(os_string.as_bytes());
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
match os_string.to_string_lossy() {
|
||||
Cow::Borrowed(slice) => Cow::from(slice.as_bytes()),
|
||||
Cow::Owned(owned) => Cow::from(owned.into_bytes()),
|
||||
@@ -468,12 +470,12 @@ pub fn os_str_as_bytes_lossy(os_string: &OsStr) -> Cow<'_, [u8]> {
|
||||
///
|
||||
/// This always succeeds on unix platforms,
|
||||
/// and fails on other platforms if the bytes can't be parsed as UTF-8.
|
||||
#[cfg_attr(unix, expect(clippy::unnecessary_wraps))]
|
||||
#[cfg_attr(any(unix, target_os = "wasi"), expect(clippy::unnecessary_wraps))]
|
||||
pub fn os_str_from_bytes(bytes: &[u8]) -> error::UResult<Cow<'_, OsStr>> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
return Ok(Cow::Borrowed(OsStr::from_bytes(bytes)));
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
Ok(Cow::Owned(OsString::from(str::from_utf8(bytes).map_err(
|
||||
|_| error::UUsageError::new(1, "Unable to transform bytes into OsStr"),
|
||||
)?)))
|
||||
@@ -483,12 +485,12 @@ pub fn os_str_from_bytes(bytes: &[u8]) -> error::UResult<Cow<'_, OsStr>> {
|
||||
///
|
||||
/// This always succeeds on unix platforms,
|
||||
/// and fails on other platforms if the bytes can't be parsed as UTF-8.
|
||||
#[cfg_attr(unix, expect(clippy::unnecessary_wraps))]
|
||||
#[cfg_attr(any(unix, target_os = "wasi"), expect(clippy::unnecessary_wraps))]
|
||||
pub fn os_string_from_vec(vec: Vec<u8>) -> error::UResult<OsString> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
return Ok(OsString::from_vec(vec));
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
Ok(OsString::from(String::from_utf8(vec).map_err(|_| {
|
||||
error::UUsageError::new(1, "invalid UTF-8 was detected in one or more arguments")
|
||||
})?))
|
||||
@@ -498,11 +500,11 @@ pub fn os_string_from_vec(vec: Vec<u8>) -> error::UResult<OsString> {
|
||||
///
|
||||
/// This always succeeds on unix platforms,
|
||||
/// and fails on other platforms if the bytes can't be parsed as UTF-8.
|
||||
#[cfg_attr(unix, expect(clippy::unnecessary_wraps))]
|
||||
#[cfg_attr(any(unix, target_os = "wasi"), expect(clippy::unnecessary_wraps))]
|
||||
pub fn os_string_to_vec(s: OsString) -> error::UResult<Vec<u8>> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
let v = s.into_vec();
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
let v = s
|
||||
.into_string()
|
||||
.map_err(|_| {
|
||||
|
||||
Reference in New Issue
Block a user