From 9c34a8f0d881833f9c972d0bdc91717c5ff31ef6 Mon Sep 17 00:00:00 2001 From: Edwin Kofler Date: Tue, 15 Aug 2023 12:42:24 -0700 Subject: [PATCH] fix: Interpret most escape sequence within JSON strings --- lib/install/install.sh | 7 ++++--- lib/json/JSON.sh | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/install/install.sh b/lib/install/install.sh index e6e4133..9b7c60a 100755 --- a/lib/install/install.sh +++ b/lib/install/install.sh @@ -164,7 +164,7 @@ bpkg_install () { did_fail=0 continue fi - + ## Check each remote in order local i=0 for remote in "${BPKG_REMOTES[@]}"; do @@ -381,8 +381,9 @@ bpkg_install_from_remote () { if (( 1 == needs_global )); then if (( has_pkg_json > 0 )); then ## install bin if needed - build="$(echo -n "$json" | bpkg-json -b | grep '\["install"\]' | awk '{$1=""; print $0 }' | tr -d '\"')" - build="$(echo -n "$build" | sed -e 's/^ *//' -e 's/ *$//')" + build="$(echo -n "$json" | bpkg-json -b -f='"install"')" + build=${build#\"} + build=${build%\"} fi if [[ -z "$build" ]]; then diff --git a/lib/json/JSON.sh b/lib/json/JSON.sh index 1b5451b..78a8f4c 100755 --- a/lib/json/JSON.sh +++ b/lib/json/JSON.sh @@ -8,18 +8,36 @@ throw () { BRIEF=0 LEAFONLY=0 PRUNE=0 +FILTER= usage() { echo - echo "Usage: JSON.sh [-b] [-l] [-p] [-h]" + echo "Usage: JSON.sh [-b] [-l] [-p] [-f=] [-h]" echo echo "-p - Prune empty. Exclude fields with empty values." echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-f - Filter. Only print the values for the keys that match the specified filter" echo "-h - This help text." echo } +escape_string() { + local str=$1 + + str=${str//\\\"/\"} + str=${str//\\\\/\\} + str=${str//\\\//\/} + str=${str//\\b/$'\b'} + str=${str//\\f/$'\f'} + str=${str//\\n/$'\n'} + str=${str//\\r/$'\r'} + str=${str//\\t/$'\t'} + # TODO: unicode escaping + + REPLY=$str +} + parse_options() { set -- "$@" local ARGN=$# @@ -37,6 +55,8 @@ parse_options() { ;; -p) PRUNE=1 ;; + -f=*) FILTER=${1#-f=} + ;; ?*) echo "ERROR: Unknown option." usage exit 0 @@ -126,7 +146,7 @@ parse_object () { while : do case "$token" in - '"'*'"') key=$token ;; + '"'*'"') escape_string "$token"; key=$REPLY ;; *) throw "EXPECTED string GOT ${token:-EOF}" ;; esac read -r token @@ -158,7 +178,7 @@ parse_value () { '[') parse_array "$jpath" ;; # At this point, the only valid single-character tokens are digits. ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; - *) value=$token + *) escape_string "$token"; value=$REPLY isleaf=1 [ "$value" = '""' ] && isempty=1 ;; @@ -169,8 +189,17 @@ parse_value () { [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 - [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" - : + + if [ "$print" -eq 1 ]; then + # FILTER + if [ -n "$FILTER" ]; then + if [ "$FILTER" = "$jpath" ]; then + printf '%s\n' "$value" + fi + else + printf "[%s]\t%s\n" "$jpath" "$value" + fi + fi } parse () {