Skip to content

fix: read user-dirs.dirs as shell assignments, not INI - #545

Open
darrenhuai wants to merge 4 commits into
tox-dev:mainfrom
darrenhuai:fix-user-dirs-parsing
Open

fix: read user-dirs.dirs as shell assignments, not INI#545
darrenhuai wants to merge 4 commits into
tox-dev:mainfrom
darrenhuai:fix-user-dirs-parsing

Conversation

@darrenhuai

Copy link
Copy Markdown
Contributor

_get_user_dirs_folder parses ~/.config/user-dirs.dirs with ConfigParser under a fake [top] section. The file is a shell fragment written by xdg-user-dirs-update, and the reference reader in xdg-user-dirs (xdg-user-dir-lookup.c) scans it line by line, so the two disagree on files that are perfectly normal for that tool:

user-dirs.dirs contains main xdg-user-dir
the same key assigned twice (hand-edited file, old line left in) DuplicateOptionError last one wins
a line that is not key=value ParsingError skipped
an indented assignment swallowed as a continuation of the previous value read normally
XDG_DOCUMENTS_DIR="$HOME/Docs" # was "$HOME/Old" ~/Docs" # was "$HOME/Old ~/Docs
XDG_DOCUMENTS_DIR="$HOME/My \"Docs\"" (xdg-user-dirs-update escapes $, `, " and \) ~/My \"Docs\" ~/My "Docs"

#542 turned interpolation off to stop % breaking it, which fixed one symptom of the same mismatch.

This replaces the parser with a line matcher that does what the C reader does: the last assignment wins, escapes inside the quotes are undone, anything after the closing quote is ignored, and a value that is neither $HOME-relative nor absolute is skipped so an earlier valid line still counts. Unquoted values are still accepted, as before; Debian's xdg-user-dir is a sh script that sources the file and accepts them too.

I ran the new cases through Ubuntu's xdg-user-dir and GLib's g_get_user_special_dir on the same files. Wherever those two agree, this now agrees with them; where they differ, it follows the C source. Existing tests pass on Windows and Linux.

_get_user_dirs_folder fed ~/.config/user-dirs.dirs to ConfigParser under
a fake [top] section. The file is a shell fragment written by
xdg-user-dirs-update, and the reference reader in xdg-user-dirs
(xdg-user-dir-lookup.c) scans it line by line, so the two disagree in
ways that either crash or hand back a wrong directory: a second
assignment to the same key raises DuplicateOptionError, any line that is
not key=value raises ParsingError, an indented assignment is swallowed
as a continuation of the previous value, text after the closing quote
stays in the path, and the backslash escapes xdg-user-dirs-update writes
for $, `, " and \ are kept literally. tox-dev#542 turned interpolation off to
stop percent signs breaking it, which fixed one symptom of the same
mismatch.

Replace the parser with a line matcher that does what the C reader does:
the last assignment wins, escapes inside the quotes are undone, anything
after the closing quote is ignored, and a value that is neither
$HOME-relative nor absolute is skipped so an earlier valid line still
counts. Unquoted values are still accepted, as before, since Debian's
xdg-user-dir is a sh script that sources the file and accepts them too.
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.

1 participant