From 866afd9c39527ec0bc540d8e9ecd1088d04f64ba Mon Sep 17 00:00:00 2001 From: diogotito Date: Sat, 20 Jun 2020 04:15:24 +0100 Subject: [PATCH] Handle quotes in item names The item names are being copied inside a jq string literal without being properly escaped, which causes problems when the names have quotes, backslashes or other weird characters in them. The optimal way to escape these names seems to be using jq itself to generate its own string literals. --- bwmenu | 4 ++-- lib-bwmenu | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bwmenu b/bwmenu index be2fa80..a700c56 100755 --- a/bwmenu +++ b/bwmenu @@ -175,13 +175,13 @@ show_folders() { folders=$(bw list folders --session "$BW_HASH") if folder=$(echo "$folders" | jq -r '.[] | .name' | rofi_menu); then - folder_id=$(echo "$folders" | jq -r ".[] | select(.name == \"$folder\").id") + folder_id=$(echo "$folders" | jq -r ".[] | select(.name == $(jq_escape "$folder")).id") ITEMS=$(bw list items --folderid "$folder_id" --session "$BW_HASH") show_items else rofi_exit_code="$?" - folder_id=$(echo "$folders" | jq -r ".[] | select(.name == \"$folder\").id") + folder_id=$(echo "$folders" | jq -r ".[] | select(.name == $(jq_escape "$folder")).id") item_array=$(bw list items --folderid "$folder_id" --session "$BW_HASH") on_rofi_exit "$rofi_exit_code" "$item_array" fi diff --git a/lib-bwmenu b/lib-bwmenu index ca2d234..d19a86d 100644 --- a/lib-bwmenu +++ b/lib-bwmenu @@ -1,17 +1,23 @@ #!/bin/bash # Helper functions +# Escape the argument into a valid jq string literal (with quotes included) +# $1: string to escape +jq_escape() { + echo -n "$1" | jq -Rs +} + # Extract item or items matching .name, including deduplication # $1: item name, prepended or not with deduplication mark array_from_name() { - item_name="$(echo "$1" | sed "s/$DEDUP_MARK //")" - echo "$ITEMS" | jq -r ". | map(select((.name == \"$item_name\") and (.type == $TYPE_LOGIN)))" + item_name=$(jq_escape "${1#$DEDUP_MARK }") + echo "$ITEMS" | jq -r "map(select((.name == $item_name) and (.type == $TYPE_LOGIN)))" } # Extract item matching .id # $1: string starting with ".id:" array_from_id() { - echo "$ITEMS" | jq -r ". | map(select(.id == \"$1\"))" + echo "$ITEMS" | jq -r ". | map(select(.id == $(jq_escape $1)))" } # Count the number of items in an array. Return true if more than 1 or none