Merge pull request #10720 from 0xMillyByte/refactor/digest-reader-reading-mode

uucore: refactor digest_reader to use ReadingMode enum
This commit is contained in:
Dorian Péron
2026-02-05 02:57:00 +01:00
committed by GitHub
3 changed files with 55 additions and 51 deletions
@@ -10,7 +10,9 @@ use std::fs::File;
use std::io::{self, BufReader, Read, Write};
use std::path::Path;
use crate::checksum::{AlgoKind, ChecksumError, SizedAlgoKind, digest_reader, escape_filename};
use crate::checksum::{
AlgoKind, ChecksumError, ReadingMode, SizedAlgoKind, digest_reader, escape_filename,
};
use crate::error::{FromIo, UResult, USimpleError};
use crate::line_ending::LineEnding;
use crate::sum::DigestOutput;
@@ -36,33 +38,6 @@ pub struct ChecksumComputeOptions {
pub line_ending: LineEnding,
}
/// Reading mode used to compute digest.
///
/// On most linux systems, this is irrelevant, as there is no distinction
/// between text and binary files. Refer to GNU's cksum documentation for more
/// information.
///
/// As discussed in #9168, we decide to ignore the reading mode to compute the
/// digest, both on Windows and UNIX. The reason for that is that this is a
/// legacy feature that is poorly documented and used. This enum is kept
/// nonetheless to still take into account the flags passed to cksum when
/// generating untagged lines.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadingMode {
Binary,
Text,
}
impl ReadingMode {
#[inline]
fn as_char(self) -> char {
match self {
Self::Binary => '*',
Self::Text => ' ',
}
}
}
/// Whether to write the digest as hexadecimal or encoded in base64.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DigestFormat {
@@ -315,7 +290,7 @@ where
// Always compute the "binary" version of the digest, i.e. on Windows,
// never handle CRLFs specifically.
let (digest_output, sz) = digest_reader(&mut digest, &mut file, /* binary: */ true)
let (digest_output, sz) = digest_reader(&mut digest, &mut file, ReadingMode::Binary)
.map_err_context(|| translate!("checksum-error-failed-to-read-input"))?;
// Encodes the sum if df is Base64, leaves as-is otherwise.
+29 -2
View File
@@ -417,10 +417,37 @@ impl UError for ChecksumError {
}
}
/// Reading mode used to compute digest.
///
/// On most linux systems, this is irrelevant, as there is no distinction
/// between text and binary files. Refer to GNU's cksum documentation for more
/// information.
///
/// As discussed in #9168, we decide to ignore the reading mode to compute the
/// digest, both on Windows and UNIX. The reason for that is that this is a
/// legacy feature that is poorly documented and used. This enum is kept
/// nonetheless to still take into account the flags passed to cksum when
/// generating untagged lines.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadingMode {
Binary,
Text,
}
impl ReadingMode {
#[inline]
fn as_char(self) -> char {
match self {
Self::Binary => '*',
Self::Text => ' ',
}
}
}
pub fn digest_reader<T: Read>(
digest: &mut Box<dyn Digest>,
reader: &mut T,
binary: bool,
mode: ReadingMode,
) -> io::Result<(DigestOutput, usize)> {
digest.reset();
@@ -436,7 +463,7 @@ pub fn digest_reader<T: Read>(
// `DigestWriter` and only written if the following character is
// "\n". But when "\r" is the last character read, we need to force
// it to be written.)
let mut digest_writer = DigestWriter::new(digest, binary);
let mut digest_writer = DigestWriter::new(digest, mode == ReadingMode::Binary);
let output_size = io::copy(reader, &mut digest_writer)? as usize;
digest_writer.finalize();
@@ -14,7 +14,9 @@ use std::io::{self, BufReader, Read, Write, stderr, stdin};
use os_display::Quotable;
use crate::checksum::{AlgoKind, ChecksumError, SizedAlgoKind, digest_reader, unescape_filename};
use crate::checksum::{
AlgoKind, ChecksumError, ReadingMode, SizedAlgoKind, digest_reader, unescape_filename,
};
use crate::error::{FromIo, UError, UIoError, UResult, USimpleError};
use crate::quoting_style::{QuotingStyle, locale_aware_escape_name};
use crate::sum::DigestOutput;
@@ -679,28 +681,28 @@ fn compute_and_check_digest_from_file(
// Read the file and calculate the checksum
let mut digest = algo.create_digest();
// TODO: improve function signature to use ReadingMode instead of binary bool
// Set binary to false because --binary is not supported with --check
let (calculated_checksum, _) = match digest_reader(&mut digest, &mut file_reader, false) {
Ok(result) => result,
Err(err) => {
show!(err.map_err_context(|| {
locale_aware_escape_name(&real_filename_to_check, QuotingStyle::SHELL_ESCAPE)
.to_string_lossy()
.to_string()
}));
let (calculated_checksum, _) =
match digest_reader(&mut digest, &mut file_reader, ReadingMode::Text) {
Ok(result) => result,
Err(err) => {
show!(err.map_err_context(|| {
locale_aware_escape_name(&real_filename_to_check, QuotingStyle::SHELL_ESCAPE)
.to_string_lossy()
.to_string()
}));
write_file_report(
io::stdout(),
filename,
FileChecksumResult::CantOpen,
prefix,
opts.verbose,
);
return Err(LineCheckError::CantOpenFile);
}
};
write_file_report(
io::stdout(),
filename,
FileChecksumResult::CantOpen,
prefix,
opts.verbose,
);
return Err(LineCheckError::CantOpenFile);
}
};
// Do the checksum validation
let checksum_correct = match calculated_checksum {