Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmds:output: fix quoted defs not stripped #5932

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

paul-ri
Copy link
Contributor

@paul-ri paul-ri commented Jan 6, 2021

Someone found the issue on here: https://www.reddit.com/r/swaywm/comments/kr2b42/use_variable_in_swaymsg/
After investigating:

With the following config:

def $abc "wayland wayland "

The following command would fail to be executed:

swaymsg -- output '$abc' scale 2

The definition $abc is replaced with it content, including the quotes,
which fails to match real output names.

We now strip quotes early in the output command.

@paul-ri paul-ri force-pushed the fix-output-quotes branch 3 times, most recently from a28ba37 to dc515f7 Compare January 6, 2021 09:20
@paul-ri paul-ri changed the title cmds:output: fix quotes defs not stripped cmds:output: fix quoted defs not stripped Jan 6, 2021
@emersion
Copy link
Member

emersion commented Jan 6, 2021

Doesn't the issue also apply to commands that aren't output commands? Like this for instance:

swaymsg -- input '$abc' events disabled

@rpigott
Copy link
Member

rpigott commented Jan 6, 2021

By def $abc do you mean set $abc?

The following works for me:

$ swaymsg -s $TESTSOCK set '$screen' '"wayland wayland "'
$ swaymsg -s $TESTSOCK output '$screen' scale 2

and records in the debug output:

[sway/commands.c:255] Handling command 'set $screen "wayland wayland "'
[...]
[sway/commands.c:255] Handling command 'output $screen scale 2'
[...]
[sway/config/output.c:227] Config stored for output wayland wayland  (enabled: -1) ...

Similarly, the following works in the config because the quotes are handled later in config_command:

set $screen "wayland wayland "
output $screen scale 2

What doesn't work: set $screen "wayland wayland " in the config and

$ swaymsg output '$screen' scale 2 # matches literal output '"wayland wayland "'

because then the quotes are never stripped.

We would want to specify the value with a trailing space and no extra quotes, but in this example the value of $screen should be "wayland wayland " it is "wayland wayland" instead

# the following line has a trailing space that sway discards and i3 does not
set $screen wayland wayland 

I'd say the real bug is:

  1. sway's quote handling is inconsistent between swaymsg and the config config
  2. sway's parser is incompatible with i3's definition of the set command. i3 interprets every character between the first space following the identifier and the final newline as the variable value, whereas sway parses the line and stitches tokens back together to form the variable value, possibly discarding some whitespace.

Stripping quotes around device identifiers in input/output doesn't technically address either of these issues, but it might still be a decent idea to change those commands under the assumption a real device identifier will never contain quotes.

@paul-ri
Copy link
Contributor Author

paul-ri commented Jan 6, 2021

Thanks! I was hoping exactly for this kind of insight from someone in the know.

By def $abc do you mean set $abc?

Indeed! My bad.

the assumption a real device identifier will never contain quotes

I'll try and investigate if there's a way to validate that assumption somehow if I can.

That or strip quotes from the output name too.

I won't delve into addressing the real bugs you're mentioning though.

With the following config:

    set $abc "wayland wayland "
    set $def "0:0:wayland-seat0"

The following command would fail to be executed:

    swaymsg -- output '$abc' scale 2
    swaymsg -- input '$def' repeat_rate 2

The definition `$abc` is replaced with its content, including the quotes,
which fails to match real output names. Same for `$def`

We now strip quotes early in the output command.

The behaviour was inconsistent between config_command() and execute_command().
* config_command() strips quotes before do_var_replacement() and also after,
  under some conditions.
* execute_command() strips them only before.

execute_command() is run after receiving swaymsg command hence the
failing example mentioned above.

Since we now strip quotes in cmd_output and cmd_input we prevent
config_command() from stripping them twice.
Might as well use that function in case it needs handling special cases
in the future.
@paul-ri
Copy link
Contributor Author

paul-ri commented Jan 15, 2021

@rpigott

The latest changes don't address the "real bug" you have mentioned.

I have updated the commit message for better details.

It's an attempt at keeping a consistent behaviour for cmd_output & cmd_input whether or not the command is from the config loading or execute_command.

Thanks for the pointer about config_command. I found out that it was stripping the quotes anyways for output/input commands. So it definitely felt like it was a good idea to stop that and leave it to cmd_output & cmd_input to handle the formatting of their inputs.

Let me know if you'd do it any differently.

@emersion : stripping quotes for cmd_input. The command was broken there too. Cheers!

@emersion
Copy link
Member

stripping quotes for cmd_input. The command was broken there too

Well, input was just an example. This patch doesn't fix the underlying issue, other commands are still broken.

@emersion
Copy link
Member

emersion commented Jan 15, 2021

In other words: I'd prefer to see a patch that fixes the underlying issue rather than add a workaround for each command argument that might contain spaces.

@rpigott
Copy link
Member

rpigott commented Jan 15, 2021

Yes, we should address the swaymsg issue and i3 compatibility first.

Basically, input/output commands don't exist in i3, so I figure there is a chance that using strict i3-style parsing may make them cumbersome to use, or render previously reasonably quoted commands in users' configs unusable. That is undesirable and we have the freedom to change the command to avoid that, if needed/wanted. But we should fix these issues first.

The "wayland wayland " display is a potential example. Requiring the user to keep a trailing space on their set line seems pretty lame, but that's how set works in i3 so that's how set should work in sway. Changing the definition of an input/output identifier to strip quotes is just one possible remedy to consider, if we want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants