Skip to content

Applications: Properly parse desktop exec keys and stop shelling out#207

Open
sents wants to merge 5 commits intoanyrun-org:masterfrom
sents:master
Open

Applications: Properly parse desktop exec keys and stop shelling out#207
sents wants to merge 5 commits intoanyrun-org:masterfrom
sents:master

Conversation

@sents
Copy link
Copy Markdown

@sents sents commented Jan 16, 2025

https://specifications.freedesktop.org/desktop-entry-spec/latest/exec-variables.html describes how commands and their arguments are stored in the exec key. As the exec key is a string type as defined in
https://specifications.freedesktop.org/desktop-entry-spec/latest/value-types.html escapes code for certain characters have to be respected. After this there are rules which characters necessitate a quoted string and which characters need to be escaped in a quoted string. To use the exec key for executing we then need to unescape these characters and can collect the args in a vector. This enables us to stop shelling out when executing desktop files and instead call Command directly with the specified program and arguments.

@pope
Copy link
Copy Markdown

pope commented Feb 26, 2025

I just want to +1 this, as it's been sitting here a while. I have run into cases where the error in parsing means that .desktop files don't work.

pope added a commit to pope/personal that referenced this pull request Mar 1, 2025
Running the sents branch of anyrun, which fixes the parsing of desktop
files. anyrun-org/anyrun#207

Signed-off-by: K. Adam Christensen <pope@shifteleven.com>
@Kirottu
Copy link
Copy Markdown
Collaborator

Kirottu commented Jan 19, 2026

Sorry for the inactivity, I guess after a year of inactivity I should actually do something about this.

The PR needs a rebase, after which I will have a look at it.

https://specifications.freedesktop.org/desktop-entry-spec/latest/exec-variables.html
describes how commands and their arguments are stored in the exec key.
As the exec key is a string type as defined in
https://specifications.freedesktop.org/desktop-entry-spec/latest/value-types.html
escapes code for certain characters have to be respected. After this
there are rules which characters necessitate a quoted string and which
characters need to be escaped in a quoted string. To use the exec
key for executing we then need to unescape these characters and can
collect the args in a vector. This enables us to stop shelling out
when executing desktop files and instead call `Command` directly with
the specified program and arguments.
@sents
Copy link
Copy Markdown
Author

sents commented Jan 21, 2026

Thank you for looking at this PR. I have just rebased on master and accidentally closed the PR in the process.

I previously used a panic when a std::process:exit would suffice and added another commit to fix this.
Do you want me to squash the PR?

@sents
Copy link
Copy Markdown
Author

sents commented Jan 21, 2026

It seems with the new anyrun-provider ipc approach using std::process::exit(1) will not work as I expected,
as the launcher seems stuck in a state where it doesn't close but I can't connect either. Do you know how to handle this better?

@Kirottu
Copy link
Copy Markdown
Collaborator

Kirottu commented Jan 21, 2026

If an exec key can't be parsed, it should probably just emit an error and not do any process spawning. The launcher will close as long as HandleResult::Close is returned from the handler.

@sents
Copy link
Copy Markdown
Author

sents commented Jan 24, 2026

I have noticed the shell preprocess_exec_script feature introduced in #201 returns a string to be interpreted as a POSIX (I guess) shell command string. This means we would be back to calling a shell to start the application if we do not
split this command string again.

I've now used the shell-words crate to obtain the command and argument vector but I'm also open to:

  • Going back to shelling out, this PR would still benefit by correctly processing application exec entries
  • Implementing the parsing necessary to process POSIX shell commands inside anyrun

What is your opinion @Kirottu?

Copy link
Copy Markdown
Collaborator

@Kirottu Kirottu left a comment

Choose a reason for hiding this comment

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

I suspect using shell_words to split out the output should be good enough for most use cases. And not shelling out is probably a good idea anyways.

There are some more improvements that would definitely be good for maintainability, and I also need to test it in practice as well.

Escape,
}

fn unescape_exec(s: &str) -> Result<Vec<String>, ExecKeyError> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This kind of complex behavior could really benefit from some unit tests verifying that it works.

Comment thread plugins/applications/src/scrubber.rs Outdated
let argv_without_fieldcodes = argv
.to_vec()
.into_iter()
.map(|mut c| {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we are handling the exec keys to this extent already, some of the valid codes like %i for the icon name should be handled correctly as well.

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.

I added handling for the %i and %u keys.

Comment thread plugins/applications/src/scrubber.rs
@@ -93,23 +112,23 @@ pub fn handler(selection: Match, state: &State) -> HandleResult {
let sensible_terminals = &[
Terminal {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do all the terminals actually accept the commands in this way?

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.

The terminals do work this way only if args is a single arg without spaces (e.g. -e).
We could make the args field of Terminal a Vector, although that might break peoples ron configuration files if they had a custom Terminal with arg field.

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.

We could also keep args as a single String and use shell_words to split it. That way people would not need to change their configuration.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm I think if we are breaking it already (since the placeholders will be gone), we might as well do it properly with the args field being a vector of the args that precede whatever will be launched.

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.

3 participants