From 1880ceb3544de8cf194163394c8291b60924a2e6 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 12 Nov 2026 20:25:15 +0000 Subject: populate: cope with unusual names and paths Names and paths with characters that mean something to shells, to find, or in URLs get handled as what they are, or refused: - Pruning, and removing state that sources don't need anymore, list entries with find instead of a loop reading names, which strips blanks at the ends of names and splits names at newlines. So an entry named "trail " gets pruned instead of reported as pruned and left. - Pruning doesn't make entries writable before removing them, which would change the mode of files elsewhere that are hard links to files therein. - Source names are portable file names: letters, digits, and ._-, not starting with -. nixpkgs' writers accept nothing else in the names of the scripts populating the sources, which contain the source names, and fail with an assertion that doesn't mention the source. - Paths get percent-encoded where they go into URLs for Nix, which refuses blanks there and takes ? and # for delimiters. - rsync gets the target path protected from the target's shell (--protect-args), which expands wildcards in it otherwise: a file source delivered to /var/src/a?c ends up in /var/src/abc if that exists. A safety scenario deploys every kind of state to a target path with a blank, wildcards, #, and %. An edge case prunes entries with blanks at the ends of their names, with a newline, and with wildcards, and the scenario pruning links also prunes hard links to a read-only file outside, and lists what's left in the C locale, where ls sorts .populate first. The scenario with unusual source names also draws inputs from a source named self. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'README.md') diff --git a/README.md b/README.md index 7fdd8eb..f7d5cbe 100644 --- a/README.md +++ b/README.md @@ -297,9 +297,9 @@ whatever is at the target path of a source, and with `prune` it removes everything else. It doesn't change or remove anything outside: * Target paths must be absolute, must not be the root directory, and must not - contain `..`. Source names must be file names other than `.`, `..`, and - `.populate`, without slashes and control characters. Anything else fails - when evaluating. + contain `..`. Source names must consist of letters, digits, and the + characters `._-`, not start with `-`, and be neither `.`, `..`, nor + `.populate`. Anything else fails when evaluating. * A symlink at the target path of a source gets replaced by what the source delivers, not followed, and populate says so. To keep a source elsewhere, -- cgit v1.3.1