Skip to content

xargs: correct method of spawning - #26

Merged
jgarzik merged 1 commit into
mainfrom
hacking
Mar 27, 2024
Merged

xargs: correct method of spawning#26
jgarzik merged 1 commit into
mainfrom
hacking

Conversation

@jgarzik

@jgarzik jgarzik commented Mar 27, 2024

Copy link
Copy Markdown
Contributor

No description provided.

@jgarzik jgarzik added the bug Something isn't working label Mar 27, 2024
@jgarzik jgarzik self-assigned this Mar 27, 2024
@jgarzik
jgarzik merged commit 6b0a605 into main Mar 27, 2024
@jgarzik
jgarzik deleted the hacking branch March 27, 2024 01:34
grisenti pushed a commit to grisenti/posixutils-rs that referenced this pull request Jul 31, 2026
… time

pax never called setlocale, so LC_MESSAGES was inert and the `-v` listing time
was rendered by a hand-rolled days_to_ymd that ignored TZ and LC_TIME.

main() now initializes the locale (setlocale(LC_ALL, "") + textdomain +
bind_textdomain_codeset) and calls tzset() once — glibc's localtime_r, unlike
localtime, does not call tzset itself, so $TZ would otherwise be ignored.

User-facing diagnostics route their fixed clause through gettext: the PaxError
Display arms and the "not found" / "unsupported file type" messages. The
variable detail (pathnames, wrapped errors) is interpolated outside, and in the
C locale gettext returns the message unchanged, so output stays byte-identical.

The `-v` listing time formatter and the listopt %t/%T (traditional and ISO)
formatters were replaced with plib::locale::strftime (libc localtime_r +
strftime), so TZ and LC_TIME (month names) now take effect — verified against
date(1) for America/Los_Angeles and Asia/Tokyo. The hand-rolled days_to_ymd /
is_leap_year helpers in list.rs and options.rs are removed.

rustcoreutils#26 (non-UTF-8 path bytes via to_string_lossy; cpio TRAILER c_mode cosmetic) is
documented as a known WON'T-FIX in audit.md. Tick audit.md rustcoreutils#24.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
grisenti pushed a commit to grisenti/posixutils-rs that referenced this pull request Jul 31, 2026
…dited

All pax/audit.md findings are remediated across the eight fix phases. Add a
remediation banner to pax/audit.md, tick the remaining per-mode/per-format
matrix rows and the test-coverage checklist (now closed by the regression tests
added per phase), and mark rustcoreutils#26 (non-UTF-8 path bytes; cpio TRAILER c_mode) as
the sole documented WON'T-FIX.

Promote pax from README "Stage 3 — Test coverage" to "Stage 6 — Audited"
(alphabetically placed), and update the audits.md §9 entry to note the
remediation and Stage-6 promotion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
grisenti pushed a commit to grisenti/posixutils-rs that referenced this pull request Jul 31, 2026
- rustcoreutils#9 ${x:=word} now expands/assigns word only when actually needed (no
  spurious side effects when the variable is already set).
- rustcoreutils#10 `return` with no operand defaults to $? (was 0).
- rustcoreutils#11/rustcoreutils#45 break/continue no longer escape a function: exec_function
  saves/zeroes/restores loop_depth; break/continue with no enclosing loop is a
  non-fatal no-op (dash/bash-compatible); `continue` now names itself correctly.
- rustcoreutils#26 arithmetic unary operators chain (!!0, - -1, ~~5).
- rustcoreutils#30 tilde leaves `~` literal when HOME is unset instead of erroring.
- rustcoreutils#39 ${#param} counts characters, not bytes.
- rustcoreutils#40 arithmetic comma operator (top level and in parentheses).
- rustcoreutils#59 ${param:?word} emits the supplied word as the diagnostic; the command
  lexer consumes blanks/operators inside ${...} up to '}', so words/patterns in
  ${x:-a b}, ${x:?my msg}, ${x:=d e}, ${x#a b} etc. parse correctly.

Adds 8 regression tests. sh suite green (253 unit + 159 integration), clippy
clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jgarzik added a commit that referenced this pull request Aug 7, 2026
POSIX defines `-o invalid=binary` as generating a hdrcharset=BINARY extended
header record for a member whose name cannot be represented in the header
character set, and recording that name as unencoded bytes. pax did neither: the
name went through to_string_lossy before any format saw it, so every invalid
byte became U+FFFD irreversibly and `binary`, `UTF-8` and `write` all produced
byte-identical output. The hdrcharset plumbing existed on both sides and was
simply never fed.

A pathname is a byte string on Unix, and PathBuf already carries it losslessly
-- only the lossy conversion destroyed it. So ExtendedHeader.path and .linkpath
become Vec<u8>, the record writer gains a raw-bytes form (record lengths count
bytes either way), the parser keeps a pathname record's bytes verbatim rather
than lossily converting them, and from_entry declares hdrcharset=BINARY when
the name or link target is not valid UTF-8. A non-UTF-8 name also always needs
the path record now, regardless of length, since no ustar spelling of it is
faithful.

serialize's two record emitters become plain functions: both now append to the
same buffer, which two closures cannot.

Still lossy for -x ustar and -x cpio, which have nowhere to record the
encoding; the ustar name field beside the record likewise stays best-effort,
for readers that do not parse extended headers. audit.md #26 is updated from
WON'T-FIX accordingly.

Test is Linux-only: APFS and HFS+ reject a filename that is not well-formed
UTF-8, so the fixture cannot exist on macOS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant