Skip to content

Conversation

@sents
Copy link

@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

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
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
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
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
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
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
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
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.

let argv_without_fieldcodes = argv
.to_vec()
.into_iter()
.map(|mut c| {
Copy link
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.

Escape,
}

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

Choose a reason for hiding this comment

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

This would benefit from testing as well.

@@ -93,23 +112,23 @@ pub fn handler(selection: Match, state: &State) -> HandleResult {
let sensible_terminals = &[
Terminal {
Copy link
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?

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