Skip to content

date: report errors while reading date files - #14783

Open
ddy314 wants to merge 3 commits into
uutils:mainfrom
ddy314:fix/date-file-read-errors
Open

ddy314 wants to merge 3 commits into
uutils:mainfrom
ddy314:fix/date-file-read-errors

Conversation

@ddy314

@ddy314 ddy314 commented Sep 21, 2026

Copy link
Copy Markdown

Propagate file/stdin read failures instead of treating them as EOF. Flush completed output, report the input and read error, and exit unsuccessfully. Invalid date lines still allow processing to continue.

Fixes #12672.

Validation: 164 date tests passed, 7 ignored; 37 date unit tests passed, including a reader failing after valid and invalid lines. Clippy and rustfmt passed.

AI-assisted with Codex.

Copilot AI lite review requested due to automatic review settings September 21, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Propagates input read failures in date (file/stdin) instead of treating them as EOF, while continuing past invalid date lines; adds user-facing error reporting and tests to validate behavior.

Changes:

  • Introduce DateInputError to distinguish invalid date lines from I/O read failures.
  • Make the date reader iterator surface read errors and stop iteration after the first read failure.
  • Add unit/integration tests and a new localized error string for read-failure reporting.
File Description
tests/​by-util/​test_date.rs Adds a Linux integration test asserting a read error is reported for a problematic input file.
src/​uu/​date/​src/​date.rs Adds DateInputError, propagates read errors distinctly, and adds a unit test for reader failure after valid/invalid lines.
src/​uu/​date/​locales/​en-US.ftl Adds localized message template for read errors.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/by-util/test_date.rs Outdated
Comment thread src/uu/date/src/date.rs Outdated
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/df/skip-rootfs. tests/df/skip-rootfs is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/id/smack. tests/id/smack is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/mkdir/smack-root. tests/mkdir/smack-root is passing on 'main'. Maybe you have to rebase?

when using an option to specify date(s), any non-option
argument must be a format string beginning with '+'

date-error-read = {$path}: read error: {$error}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you check the exact GNU wording/exit code with LANG=C?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. With LANG=C, GNU coreutils 9.12 exits 1, writes no stdout, and reports gnudate: /proc/self/mem: read error: Input/output error on this glibc host. The uutils result matches after normalizing the executable name. The test keeps the OS error suffix flexible because musl spells it I/O error.

Comment thread src/uu/date/src/date.rs Outdated
});
}
Err(DateInputError::Read(error)) => {
stdout.flush().map_err(DateError::Write)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just above we do let _ = stdout.flush(), could we be consistent?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this consistent with the invalid-date arm by using let _ = stdout.flush() in f4a7f1d.

Comment thread src/uu/date/src/date.rs Outdated
}
Err(DateInputError::Read(error)) => {
stdout.flush().map_err(DateError::Write)?;
let path = match &settings.date_source {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please carry the path in DateInputError::Read? re-deriving it from date_source with a hardcoded "-" fallback is fragile

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DateInputError::Read now carries the input path, including the explicit stdin name, in f4a7f1d.

Comment thread src/uu/date/src/date.rs Outdated
DateSource::File(path) => path.as_os_str().maybe_quote().to_string(),
_ => "-".to_string(),
};
return Err(uucore::error::USimpleError::new(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a Read variant to DateError instead of USimpleError here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added DateError::Read and removed the USimpleError construction in f4a7f1d.

Comment thread src/uu/date/src/date.rs Outdated
Box::new(lines.map_while(Result::ok).map(move |mut bytes| {
) -> Box<dyn Iterator<Item = Result<ParsedDateTime, DateInputError>> + '_> {
let mut lines = BufReader::new(reader).split(b'\n');
let mut failed = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the manual failed flag + from_fn is a bit heavy, can't we just fuse after the error?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the manual flag and from_fn with a mapped iterator plus scan that yields the first read error and then stops in f4a7f1d.

Copilot AI review requested due to automatic review settings September 22, 2026 06:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

parse_dates_from_reader currently uses matches!(result, ...) in a way that moves result, which makes the iterator scan closure not compile as written.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Low severity

Open (2)
Resolved since last review (2)

Comment thread src/uu/date/src/date.rs
Comment on lines +1289 to 1294
if *failed {
None
} else {
*failed = matches!(result, Err(DateInputError::Read { .. }));
Some(result)
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in cdf4e79 by matching on a shared reference to result, so the value remains available for Some(result). cargo test -p uu_date (37 tests) and clippy both pass.

Comment thread src/uu/date/src/date.rs
Comment on lines +693 to +696
return Err(Box::new(DateError::Read {
path,
error: strip_errno(&error).clone(),
}));

@ddy314 ddy314 Sep 22, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in cdf4e79 by moving the owned String returned by strip_errno directly into DateError::Read.

Copilot AI review requested due to automatic review settings September 22, 2026 06:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review effort: Lite
Findings: 1 High severity · 2 Medium severity · 1 Low severity

Open (4)

when using an option to specify date(s), any non-option
argument must be a format string beginning with '+'

date-error-read = {$path}: read error: {$error}
Comment on lines +3453 to +3458
new_ucmd!()
.env("LC_ALL", "C")
.args(&["-f", "/proc/self/mem"])
.fails_with_code(1)
.no_stdout()
.stderr_contains("/proc/self/mem: read error:");

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(date): -f with /proc/self/mem errors are ignored

3 participants