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 e76b2c09718..9efdbf966ab 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -47,6 +47,10 @@ pub enum ParseError { BsOutOfRange(String), #[error("{}", translate!("dd-error-invalid-number", "input" => .0.clone()))] InvalidNumber(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 @@ -243,11 +247,19 @@ 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::InvalidNumberTooLarge(format!("{skip}"))); + } 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::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 0bce976dc80..5b95abdb589 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1830,3 +1830,23 @@ 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\n", + ); +} + +#[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\n", + ); +}