diff --git a/Cargo.lock b/Cargo.lock index 4cff737eed3..74559cdf7bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -283,9 +283,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "calendrical_calculations" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abbd6eeda6885048d357edc66748eea6e0268e3dd11f326fff5bd248d779c26" +checksum = "3a0b39595c6ee54a8d0900204ba4c401d0ab4eb45adaf07178e8d017541529e7" dependencies = [ "core_maths", "displaydoc", @@ -1084,9 +1084,9 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed_decimal" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd" +checksum = "35eabf480f94d69182677e37571d3be065822acfafd12f2f085db44fbbcc8e57" dependencies = [ "displaydoc", "smallvec", @@ -1382,9 +1382,9 @@ dependencies = [ [[package]] name = "icu_calendar" -version = "2.2.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45" +checksum = "d6f0e52e009b6b16ba9c0693578796f2dd4aaa59a7f8f920423706714a89ac4e" dependencies = [ "calendrical_calculations", "displaydoc", @@ -1399,15 +1399,15 @@ dependencies = [ [[package]] name = "icu_calendar_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d" +checksum = "527f04223b17edfe0bd43baf14a0cb1b017830db65f3950dc00224860a9a446d" [[package]] name = "icu_collator" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b521b92a2666061ddda902769d8a4cf730b5c9529a845cc1b69770b12a6c9a71" +checksum = "32eed11a5572f1088b63fa21dc2e70d4a865e5739fc2d10abc05be93bae97019" dependencies = [ "icu_collator_data", "icu_collections", @@ -1424,19 +1424,18 @@ dependencies = [ [[package]] name = "icu_collator_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038ed8e5817f2059c2f3efb0945ba78d060d3d25e8f1a1bea5139f821a21a2f0" +checksum = "5ab06f0e83a613efddba3e4913e00e43ed4001fae651cb7d40fc7e66b83b6fb9" [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", - "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1444,9 +1443,9 @@ dependencies = [ [[package]] name = "icu_datetime" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72" +checksum = "1b9d49f41ded8e63761b6b4c3120dfdc289415a1ed10107db6198eb311057ca5" dependencies = [ "displaydoc", "fixed_decimal", @@ -1467,22 +1466,20 @@ dependencies = [ [[package]] name = "icu_datetime_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b" +checksum = "46597233625417b7c8052a63d916e4fdc73df21614ac0b679492a5d6e3b01aeb" [[package]] name = "icu_decimal" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4" +checksum = "a38c52231bc348f9b982c1868a2af3195199623007ba2c7650f432038f5b3e8e" dependencies = [ - "displaydoc", "fixed_decimal", "icu_decimal_data", "icu_locale", "icu_locale_core", - "icu_plurals", "icu_provider", "writeable", "zerovec", @@ -1490,15 +1487,15 @@ dependencies = [ [[package]] name = "icu_decimal_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22" +checksum = "2905b4044eab2dd848fe84199f9195567b63ab3a93094711501363f63546fef7" [[package]] name = "icu_locale" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26" +checksum = "532b11722e350ab6bf916ba6eb0efe3ee54b932666afec989465f9243fe6dd60" dependencies = [ "icu_collections", "icu_locale_core", @@ -1525,15 +1522,15 @@ dependencies = [ [[package]] name = "icu_locale_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993" +checksum = "1c5f1d16b4c3a2642d3a719f18f6b06070ab0aef246a6418130c955ae08aa831" [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1548,15 +1545,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_pattern" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb" +checksum = "7a7ff8c0ff6f61cdce299dcb54f557b0a251adbc78f6f0c35a21332c452b4a1b" dependencies = [ "displaydoc", "either", @@ -1567,9 +1564,9 @@ dependencies = [ [[package]] name = "icu_plurals" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103" +checksum = "4f9cfe49f5b1d1163cc58db451562339916a9ca5cbcaae83924d41a0bf839474" dependencies = [ "fixed_decimal", "icu_locale", @@ -1580,15 +1577,15 @@ dependencies = [ [[package]] name = "icu_plurals_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d" +checksum = "f018a98dccf7f0eb02ba06ac0ff67d102d8ded80734724305e924de304e12ff0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1600,9 +1597,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -1623,9 +1620,9 @@ dependencies = [ [[package]] name = "icu_time" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a" +checksum = "8242b00da3b3b6678f731437a11c8833a43c821ae081eca60ba1b7579d45b6d8" dependencies = [ "calendrical_calculations", "displaydoc", @@ -1640,9 +1637,9 @@ dependencies = [ [[package]] name = "icu_time_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2f8aeca682d874a5247084aa4fb7d1cef9ba45d889c21209a8818dcaaa0ec9" +checksum = "3e10b0e5e87a2c84bd5fa407705732052edebe69291d347d0c3033785470edbf" [[package]] name = "id-arena" @@ -1871,13 +1868,12 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.11.0", "libc", - "plain", "redox_syscall 0.7.0", ] @@ -2293,12 +2289,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "platform-info" version = "2.1.0" diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 8b321b55d53..1213a3840b1 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -2045,27 +2045,36 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { path: files0_from.clone(), error, })?; - let f = std::str::from_utf8(&line) - .expect("Could not parse string from zero terminated input."); - match f { - STDIN_FILE => { - return Err(SortError::MinusInStdIn.into()); + + if line.is_empty() { + return Err(SortError::ZeroLengthFileName { + file: files0_from, + line_num: line_num + 1, } - "" => { - return Err(SortError::ZeroLengthFileName { - file: files0_from, - line_num: line_num + 1, - } - .into()); + .into()); + } + + let f: OsString = { + #[cfg(unix)] + { + OsStr::from_bytes(&line).to_os_string() + } + #[cfg(not(unix))] + { + OsString::from(String::from_utf8_lossy(&line).into_owned()) + } + }; + + match f.to_str() { + Some(s) if s == STDIN_FILE => { + return Err(SortError::MinusInStdIn.into()); } _ => {} } - files.push(OsString::from( - std::str::from_utf8(&line) - .expect("Could not parse string from zero terminated input."), - )); + files.push(f); } + if files.is_empty() { return Err(SortError::EmptyInputFile { file: files0_from }.into()); } diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index 27548688987..5eee5d28f34 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -591,23 +591,10 @@ pub enum CharByte { Byte(u8), } -impl From for CharByte { - fn from(value: char) -> Self { - Self::Char(value) - } -} - -impl From for CharByte { - fn from(value: u8) -> Self { - Self::Byte(value) - } -} - -impl From<&u8> for CharByte { - fn from(value: &u8) -> Self { - Self::Byte(*value) - } -} +impl_from_for_enum!(CharByte: + char => Char; + u8 => Byte, ref +); struct Utf8ChunkIterator<'a> { iter: Box + 'a>, diff --git a/src/uucore/src/lib/macros.rs b/src/uucore/src/lib/macros.rs index bd234768e4b..20f3c4df436 100644 --- a/src/uucore/src/lib/macros.rs +++ b/src/uucore/src/lib/macros.rs @@ -194,3 +194,68 @@ macro_rules! show_warning_caps( let _ = writeln!(error, $($args)+); }) ); + +/// Implement [`From`] for an enum with simple variant mappings. +/// +/// This macro generates `From` implementations for the specified enum, +/// mapping each input type to a corresponding enum variant. Optionally, +/// it can also generate `From<&T>` implementations by copying the value. +/// +/// # Syntax +/// +/// ```ignore +/// impl_from_for_enum!(EnumName: +/// Type1 => Variant1, +/// Type2 => Variant2, ref +/// ); +/// ``` +/// +/// - `Type => Variant` generates `impl From for Enum`. +/// - Adding `, ref` additionally generates `impl From<&Type> for Enum`, +/// dereferencing the input value. +/// +/// # Examples +/// +/// ```ignore +/// impl_from_for_enum!(CharByte: +/// char => Char, +/// u8 => Byte, ref +/// ); +/// ``` +/// +/// This expands roughly to: +/// +/// ```ignore +/// impl From for CharByte { ... } +/// impl From for CharByte { ... } +/// impl From<&u8> for CharByte { ... } +/// ``` +/// +/// # Notes +/// +/// - The referenced implementations (`From<&T>`) require `T: Copy`. +/// - This macro is intended for simple enum wrappers where variants +/// directly wrap the input type. +#[macro_export] +macro_rules! impl_from_for_enum { + ( @step $enum:ident, $type:ty => $variant:ident, ref ) => { + impl From<$type> for $enum { + fn from(value: $type) -> Self { $enum::$variant(value) } + } + impl From<&$type> for $enum { + fn from(value: &$type) -> Self { $enum::$variant(*value) } + } + }; + + ( @step $enum:ident, $type:ty => $variant:ident ) => { + impl From<$type> for $enum { + fn from(value: $type) -> Self { $enum::$variant(value) } + } + }; + + ( $enum:ident : $( $type:ty => $variant:ident $(, $r:ident)? );* $(;)? ) => { + $( + $crate::impl_from_for_enum!(@step $enum, $type => $variant $(, $r)?); + )* + }; +} diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index b0e7602fd7f..45384d20032 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -1851,6 +1851,25 @@ fn test_files0_from_2a() { .stdout_only("a\na\n"); } +#[test] +// Test for GNU tests/sort/sort-files0-from.pl "non-utf8" +#[cfg(unix)] +fn test_files0_from_non_utf8() { + use std::os::unix::ffi::OsStringExt; + let (at, mut ucmd) = at_and_ucmd!(); + + // non-UTF-8 bytes (0xFF) + let filename = std::ffi::OsString::from_vec(b"a\xffb".into()); + std::fs::write(at.plus(&filename), b"20\n10\n").unwrap(); + + let list_contents = vec![b'a', 0xFF, b'b', 0]; + at.write_bytes("list0", &list_contents); + + ucmd.args(&["--files0-from", "list0"]) + .succeeds() + .stdout_only("10\n20\n"); +} + #[test] // Test for GNU tests/sort/sort-files0-from.pl "zero-len" fn test_files0_from_zero_length() {