polybar/polybar

Escape Tokens in labels

Open

#2,067 opened on Apr 19, 2020

View on GitHub
 (4 comments) (0 reactions) (0 assignees)C++ (684 forks)batch import
featurehelp wanted

Repository metrics

Stars
 (13,262 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Currently, module tokens are being parsed inside action tags. I believe this is a bug.

Example with MPD

When I click on label-song, I want to be sent a notification with information about what's currently playing via mpc. In this example, I am send a notication with the name of the current album playing:

[module/mpd-nowplaying]
label-song = %{A1:notify-send "Currently Playing" "$(mpc -f "%album%" | head -1)":%album% - %title%%{A}

However, this config will interpret %album% and treat it like an mpd toke, expanding it to the name of the currently playing album:

notify-send "Currently Playing" "$(mpc -f "<currently playing album>" | head -1)"

For this specific usecase, you may think well what's the problem? Either polybar or mpc will end up expanding %album% to the album anyways, so it doesn't matter?

However, if the album contains a colon (:), it will not be escaped, and so the command will look like this:

notify-send "Currently Playing" "$(mpc -f "Example Album: Super Collection" | head -1)"

This leads to errors like this:

error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
error: Failed to parse contents (reason: Unrecognized token 'S')
...

Long story short, tokens that have the potential to contain colons are particularly dangerous and should not be parsed/expanded.

Trying to Escape the Token

If you escape the token with backslashes, the token is not interpreted, but the backslashes are not removed when sent to the shell, so the command will look like:

notify-send "Currently Playing" "$(mpc -f "\%album\%" | head -1)"

Since it is still escaped, mpc will not recognize it as a format tag.

Solutions

  1. Don't parse tokens inside action tags.
  2. Allow tokens like %album% to be escaped, like \%album\%, and remove the backslashes when parsing, similarly to how escaped colons' backslashes are deleted before the command is sent to the shell (e.g. \: becomes :, then is sent to shell).

Version Info

Output of polybar -vvv:

polybar 3.4.0-80-gc9a43dd

Features: +alsa +curl +i3 +mpd +network(libnl) +pulseaudio +xkeyboard

X extensions: +randr (+monitors) +composite +xkb +xrm +xcursor

Build type: Release
Compiler: /usr/bin/c++
Compiler flags:  -Wall -Wextra -Wpedantic -O3 -DNDEBUG
Linker flags:

Contributor guide