From b1b09298f48d910bd7e2945ae2643e7d0e3c107c Mon Sep 17 00:00:00 2001 From: David Rebbe <1187684+ic3man5@users.noreply.github.com> Date: Tue, 27 May 2025 20:54:24 -0400 Subject: [PATCH 1/3] dd: should terminate with error if skip argument is too large fixed clippy warning --- src/uu/dd/src/parseargs.rs | 16 ++++++++++++++++ tests/by-util/test_dd.rs | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index e76b2c09718..2e8c104ff57 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -47,6 +47,8 @@ pub enum ParseError { BsOutOfRange(String), #[error("{}", translate!("dd-error-invalid-number", "input" => .0.clone()))] InvalidNumber(String), + #[error("invalid number: ‘{0}’: {1}")] + InvalidNumberWithErrMsg(String, String), } /// Contains a temporary state during parsing of the arguments @@ -243,11 +245,25 @@ impl Parser { .skip .force_bytes_if(self.iflag.skip_bytes) .to_bytes(ibs as u64); + // GNU coreutils has a limit of i64 (intmax_t) + if skip > i64::MAX as u64 { + return Err(ParseError::InvalidNumberWithErrMsg( + format!("{skip}"), + "Value too large for defined data type".to_string(), + )); + } let seek = self .seek .force_bytes_if(self.oflag.seek_bytes) .to_bytes(obs as u64); + // GNU coreutils has a limit of i64 (intmax_t) + if seek > i64::MAX as u64 { + return Err(ParseError::InvalidNumberWithErrMsg( + format!("{seek}"), + "Value too large for defined data type".to_string(), + )); + } let count = self.count.map(|c| c.force_bytes_if(self.iflag.count_bytes)); diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 0bce976dc80..a6a52e66fb5 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1830,3 +1830,13 @@ fn test_oflag_direct_partial_block() { at.remove(input_file); at.remove(output_file); } + +#[test] +fn test_skip_overflow() { + new_ucmd!() + .args(&["bs=1", "skip=9223372036854775808", "count=0"]) + .fails() + .stderr_contains( + "dd: invalid number: ‘9223372036854775808’: Value too large for defined data type", + ); +} From 316c2b632c6d996af8ada6e49c58b302c15f40bf Mon Sep 17 00:00:00 2001 From: Mauro Fontana Date: Tue, 4 Nov 2025 23:07:54 +0100 Subject: [PATCH 2/3] dd: Add test for seek argument overflow --- tests/by-util/test_dd.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index a6a52e66fb5..37f7f429c26 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1840,3 +1840,13 @@ fn test_skip_overflow() { "dd: invalid number: ‘9223372036854775808’: Value too large for defined data type", ); } + +#[test] +fn test_seek_overflow() { + new_ucmd!() + .args(&["bs=1", "seek=9223372036854775809", "count=0"]) + .fails() + .stderr_contains( + "dd: invalid number: ‘9223372036854775809’: Value too large for defined data type", + ); +} From 3ebbac21316e11f2387ae76001699113cbe9aff8 Mon Sep 17 00:00:00 2001 From: Mauro Fontana Date: Sat, 15 Nov 2025 21:13:46 +0100 Subject: [PATCH 3/3] dd: Fix localization for too large `skip|seek` --- src/uu/dd/locales/en-US.ftl | 1 + src/uu/dd/locales/fr-FR.ftl | 1 + src/uu/dd/src/parseargs.rs | 16 ++++++---------- tests/by-util/test_dd.rs | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/uu/dd/locales/en-US.ftl b/src/uu/dd/locales/en-US.ftl index 8a21f1b595f..c2079551b72 100644 --- a/src/uu/dd/locales/en-US.ftl +++ b/src/uu/dd/locales/en-US.ftl @@ -142,6 +142,7 @@ dd-error-status-not-recognized = status=LEVEL not recognized -> { $level } dd-error-unimplemented = feature not implemented on this system -> { $feature } dd-error-bs-out-of-range = { $param }=N cannot fit into memory dd-error-invalid-number = invalid number: ‘{ $input }’ +dd-error-invalid-number-too-large = invalid number: { $input }: Value too large for defined data type # Progress messages dd-progress-records-in = { $complete }+{ $partial } records in diff --git a/src/uu/dd/locales/fr-FR.ftl b/src/uu/dd/locales/fr-FR.ftl index fb68f809bf8..6931eab9d65 100644 --- a/src/uu/dd/locales/fr-FR.ftl +++ b/src/uu/dd/locales/fr-FR.ftl @@ -142,6 +142,7 @@ dd-error-status-not-recognized = status=NIVEAU non reconnu -> { $level } dd-error-unimplemented = fonctionnalité non implémentée sur ce système -> { $feature } dd-error-bs-out-of-range = { $param }=N ne peut pas tenir en mémoire dd-error-invalid-number = nombre invalide : ‘{ $input }‘ +dd-error-invalid-number-too-large = nombre invalide : { $input }: Valeur trop grande pour le type défini de données # Progress messages dd-progress-records-in = { $complete }+{ $partial } enregistrements en entrée diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 2e8c104ff57..9efdbf966ab 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -47,8 +47,10 @@ pub enum ParseError { BsOutOfRange(String), #[error("{}", translate!("dd-error-invalid-number", "input" => .0.clone()))] InvalidNumber(String), - #[error("invalid number: ‘{0}’: {1}")] - InvalidNumberWithErrMsg(String, String), + // Add surrounding quotes in here to get around this bug in Fluent: + // https://github.com/projectfluent/fluent-rs/issues/337 + #[error("{}", translate!("dd-error-invalid-number-too-large", "input" => format!("‘{}’", .0.clone())))] + InvalidNumberTooLarge(String), } /// Contains a temporary state during parsing of the arguments @@ -247,10 +249,7 @@ impl Parser { .to_bytes(ibs as u64); // GNU coreutils has a limit of i64 (intmax_t) if skip > i64::MAX as u64 { - return Err(ParseError::InvalidNumberWithErrMsg( - format!("{skip}"), - "Value too large for defined data type".to_string(), - )); + return Err(ParseError::InvalidNumberTooLarge(format!("{skip}"))); } let seek = self @@ -259,10 +258,7 @@ impl Parser { .to_bytes(obs as u64); // GNU coreutils has a limit of i64 (intmax_t) if seek > i64::MAX as u64 { - return Err(ParseError::InvalidNumberWithErrMsg( - format!("{seek}"), - "Value too large for defined data type".to_string(), - )); + return Err(ParseError::InvalidNumberTooLarge(format!("{seek}"))); } let count = self.count.map(|c| c.force_bytes_if(self.iflag.count_bytes)); diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 37f7f429c26..5b95abdb589 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1837,7 +1837,7 @@ fn test_skip_overflow() { .args(&["bs=1", "skip=9223372036854775808", "count=0"]) .fails() .stderr_contains( - "dd: invalid number: ‘9223372036854775808’: Value too large for defined data type", + "dd: invalid number: ‘9223372036854775808’: Value too large for defined data type\n", ); } @@ -1847,6 +1847,6 @@ fn test_seek_overflow() { .args(&["bs=1", "seek=9223372036854775809", "count=0"]) .fails() .stderr_contains( - "dd: invalid number: ‘9223372036854775809’: Value too large for defined data type", + "dd: invalid number: ‘9223372036854775809’: Value too large for defined data type\n", ); }