diff --git a/include/util/sanitize_str.hpp b/include/util/sanitize_str.hpp new file mode 100644 index 00000000..bb45c353 --- /dev/null +++ b/include/util/sanitize_str.hpp @@ -0,0 +1,6 @@ +#pragma once +#include + +namespace waybar::util { +std::string sanitize_string(std::string str); +} // namespace waybar::util diff --git a/meson.build b/meson.build index 420606aa..ccea0502 100644 --- a/meson.build +++ b/meson.build @@ -154,7 +154,8 @@ src_files = files( 'src/client.cpp', 'src/config.cpp', 'src/group.cpp', - 'src/util/ustring_clen.cpp' + 'src/util/ustring_clen.cpp', + 'src/util/sanitize_str.cpp' ) if is_linux diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 5463508b..e82bd7e9 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "modules/hyprland/backend.hpp" namespace waybar::modules::hyprland { @@ -48,16 +50,6 @@ void Language::onEvent(const std::string& ev) { if (config_.isMember("keyboard-name") && keebName != config_["keyboard-name"].asString()) return; // ignore - auto replaceAll = [](std::string str, const std::string& from, - const std::string& to) -> std::string { - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - } - return str; - }; - const auto BRIEFNAME = getShortFrom(layoutName); if (config_.isMember("format-" + BRIEFNAME)) { @@ -67,7 +59,7 @@ void Language::onEvent(const std::string& ev) { layoutName = fmt::format(format_, layoutName); } - layoutName = replaceAll(layoutName, "&", "&"); + layoutName = waybar::util::sanitize_string(layoutName); if (layoutName == layoutName_) return; diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index c2923335..c20b31d3 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -2,6 +2,8 @@ #include +#include + #include "modules/hyprland/backend.hpp" namespace waybar::modules::hyprland { @@ -39,17 +41,7 @@ void Window::onEvent(const std::string& ev) { std::lock_guard lg(mutex_); auto windowName = ev.substr(ev.find_first_of(',') + 1).substr(0, 256); - auto replaceAll = [](std::string str, const std::string& from, - const std::string& to) -> std::string { - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - } - return str; - }; - - windowName = replaceAll(windowName, "&", "&"); + windowName = waybar::util::sanitize_string(windowName); if (windowName == lastView) return; diff --git a/src/modules/mpd/mpd.cpp b/src/modules/mpd/mpd.cpp index 0f58343d..053b9edb 100644 --- a/src/modules/mpd/mpd.cpp +++ b/src/modules/mpd/mpd.cpp @@ -4,6 +4,9 @@ #include #include +#include +using namespace waybar::util; + #include "modules/mpd/state.hpp" #if defined(MPD_NOINLINE) namespace waybar::modules { @@ -135,12 +138,12 @@ void waybar::modules::MPD::setLabel() { stateIcon = getStateIcon(); - artist = getTag(MPD_TAG_ARTIST); - album_artist = getTag(MPD_TAG_ALBUM_ARTIST); - album = getTag(MPD_TAG_ALBUM); - title = getTag(MPD_TAG_TITLE); - date = getTag(MPD_TAG_DATE); - filename = getFilename(); + artist = sanitize_string(getTag(MPD_TAG_ARTIST)); + album_artist = sanitize_string(getTag(MPD_TAG_ALBUM_ARTIST)); + album = sanitize_string(getTag(MPD_TAG_ALBUM)); + title = sanitize_string(getTag(MPD_TAG_TITLE)); + date = sanitize_string(getTag(MPD_TAG_DATE)); + filename = sanitize_string(getFilename()); song_pos = mpd_status_get_song_pos(status_.get()) + 1; volume = mpd_status_get_volume(status_.get()); if (volume < 0) { diff --git a/src/util/sanitize_str.cpp b/src/util/sanitize_str.cpp new file mode 100644 index 00000000..72c72f84 --- /dev/null +++ b/src/util/sanitize_str.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +namespace waybar::util { +// replaces ``<>&"'`` with their encoded counterparts +std::string sanitize_string(std::string str) { + // note: it's important that '&' is replaced first; therefor we *can't* use std::map + const std::pair replacement_table[] = { + {'&', "&"}, {'<', "<"}, {'>', ">"}, {'"', """}, {'\'', "'"}}; + size_t startpoint; + for (size_t i = 0; i < (sizeof(replacement_table) / sizeof(replacement_table[0])); ++i) { + startpoint = 0; + std::pair pair = replacement_table[i]; + while ((startpoint = str.find(pair.first, startpoint)) != std::string::npos) { + str.replace(startpoint, 1, pair.second); + startpoint += pair.second.length(); + } + } + + return str; +} +} // namespace waybar::util