From db0fe92aaabcffc640e77121aecebf4b32a4ce35 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 17 Apr 2021 22:44:17 +0200 Subject: [PATCH] completions/dnf: cautiously complete RPM files Complete RPM files instead of pacakges if there is either 1. a slash in the token, which precludes package names 2. no matching package To enable 2, pass the commandline token to the dnf query, instead of an undefined variable. This allows SQL injection; not sure if we care. We could always complete RPM files but maybe that's too noisy. Also, isn't that what the "rpm" command is for? Closes #7928 --- share/completions/dnf.fish | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/share/completions/dnf.fish b/share/completions/dnf.fish index 19bfc9a56..00461fd63 100644 --- a/share/completions/dnf.fish +++ b/share/completions/dnf.fish @@ -7,17 +7,28 @@ function __dnf_list_installed_packages end function __dnf_list_available_packages + set -l tok (commandline -ct | string collect) + if string match -q -- '*/*' $tok + # Fast path - package names can't contain slashes, so show files. + __fish_complete_suffix rpm + return + end + set -l results # dnf --cacheonly list --available gives a list of non-installed packages dnf is aware of, # but it is slow as molasses. Unfortunately, sqlite3 is not available oob (Fedora Server 32). if type -q sqlite3 # This schema is bad, there is only a "pkg" field with the full # packagename-version-release.fedorarelease.architecture # tuple. We are only interested in the packagename. - sqlite3 /var/cache/dnf/packages.db "SELECT pkg FROM available WHERE pkg LIKE \"$cur%\"" 2>/dev/null | - string replace -r -- '-[^-]*-[^-]*$' '' + set results (sqlite3 /var/cache/dnf/packages.db "SELECT pkg FROM available WHERE pkg LIKE \"$tok%\"" 2>/dev/null | + string replace -r -- '-[^-]*-[^-]*$' '') else - dnf repoquery --cacheonly "$cur*" --qf "%{NAME}" --available 2>/dev/null + set results (dnf repoquery --cacheonly "$tok*" --qf "%{NAME}" --available 2>/dev/null) end + if not set -q results[1] + set results (__fish_complete_suffix .rpm) + end + string join \n $results end function __dnf_list_transactions @@ -103,11 +114,11 @@ end # Info complete -c dnf -n __fish_use_subcommand -xa info -d "Describes the given package" -complete -c dnf -n "__fish_seen_subcommand_from info; and not __fish_seen_subcommand_from history" -xa "(__dnf_list_available_packages)" +complete -c dnf -n "__fish_seen_subcommand_from info; and not __fish_seen_subcommand_from history" -k -xa "(__dnf_list_available_packages)" # Install complete -c dnf -n __fish_use_subcommand -xa install -d "Install package" -complete -c dnf -n "__fish_seen_subcommand_from install" -xa "(__dnf_list_available_packages)" +complete -c dnf -n "__fish_seen_subcommand_from install" -k -xa "(__dnf_list_available_packages)" # List complete -c dnf -n __fish_use_subcommand -xa list -d "Lists all packages"