From 9cb4134203984d36c2258323b01a7ca7b82cf2b2 Mon Sep 17 00:00:00 2001 From: JustMe Date: Mon, 19 Oct 2026 23:36:54 +0800 Subject: [PATCH] Build from commits that are checked, and refuse unsafe paths The plugin runs inside the input method and sees everything that is typed, so what it is built from matters. build.sh used to download a tag archive and a yoga archive without checking them. It now fetches both by commit hash and verifies the hash afterwards: a tag can be moved and an archive swapped, a commit hash cannot be faked. A version without a pinned commit is refused unless FCITX_COMMIT is given. Archive checksums were not used on purpose, GitHub does not keep the bytes of generated archives stable. enable-autostart.sh writes paths into an Exec line and a service file and now refuses paths that would need quoting there. Co-Authored-By: Claude Sonnet 5.5 --- scripts/build.sh | 49 +++++++++++++++++++++++++++---------- scripts/enable-autostart.sh | 5 ++++ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index c5036b4..7059fb7 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -8,24 +8,47 @@ set -euo pipefail root=$(cd "$(dirname "$0")/.." && pwd) work=${WORK_DIR:-$root/build} version=${FCITX_VERSION:-$(pkg-config --modversion Fcitx5Core)} + +die() { echo "build.sh: $*" >&2; exit 1; } +command -v git >/dev/null || die "git is needed to fetch the sources" + +# The sources are fetched by commit hash and the hash is checked afterwards. A +# tag can be moved and a downloaded archive can be swapped, a commit hash cannot +# be faked, Git verifies the content against it. This plugin runs inside the +# input method and sees everything that is typed, so what it is built from +# matters. +# +# Commit the Fcitx5 release tag points to, check it yourself when adding one: +# git ls-remote https://github.com/fcitx/fcitx5 "refs/tags/^{}" +declare -A known_commits=( + ["5.1.23"]="27cca6e0239938b2d53937061d0980c087856b22" +) +commit=${FCITX_COMMIT:-${known_commits[$version]:-}} +[ -n "$commit" ] || die "no pinned commit for Fcitx5 $version. Look up the commit of its tag and pass it as FCITX_COMMIT=" # Commit of the yoga submodule pinned by Fcitx5 (third_party/yoga). yoga_commit=${YOGA_COMMIT:-042f5013152eb81c1552dec945b88f7b95ca350f} +# fetch_commit , leaves checked out at exactly +fetch_commit() { + local url=$1 dir=$2 want=$3 + if [ -d "$dir/.git" ] && [ "$(git -C "$dir" rev-parse HEAD 2>/dev/null)" = "$want" ]; then + return 0 + fi + rm -rf "$dir" + mkdir -p "$dir" + git -C "$dir" init -q + git -C "$dir" fetch -q --depth 1 "$url" "$want" || die "could not fetch $want from $url" + git -C "$dir" checkout -q FETCH_HEAD + [ "$(git -C "$dir" rev-parse HEAD)" = "$want" ] || die "$url gave a different commit than $want" +} + srcdir=$work/fcitx5-$version mkdir -p "$work" - -if [ ! -d "$srcdir" ]; then - echo ">> fetching Fcitx5 $version" - curl -fsSL "https://github.com/fcitx/fcitx5/archive/refs/tags/$version.tar.gz" | - tar -xz -C "$work" -fi -if [ ! -f "$srcdir/third_party/yoga/yoga/CMakeLists.txt" ]; then - echo ">> fetching yoga $yoga_commit" - rm -rf "$srcdir/third_party/yoga" - mkdir -p "$srcdir/third_party/yoga" - curl -fsSL "https://github.com/facebook/yoga/archive/$yoga_commit.tar.gz" | - tar -xz -C "$srcdir/third_party/yoga" --strip-components=1 -fi +echo ">> fetching Fcitx5 $version ($commit)" +fetch_commit https://github.com/fcitx/fcitx5 "$srcdir" "$commit" +echo ">> fetching yoga ($yoga_commit)" +fetch_commit https://github.com/facebook/yoga "$srcdir/third_party/yoga" "$yoga_commit" +[ -z "${FETCH_ONLY:-}" ] || { echo ">> sources are in place"; exit 0; } echo ">> overlaying m3ui" rm -rf "$srcdir/src/ui/m3ui" diff --git a/scripts/enable-autostart.sh b/scripts/enable-autostart.sh index f927541..af67144 100755 --- a/scripts/enable-autostart.sh +++ b/scripts/enable-autostart.sh @@ -17,6 +17,11 @@ addondir=$(dirname "$lib") system_addondir=$(pkg-config --variable=addondir Fcitx5Core 2>/dev/null || true) system_addondir=${system_addondir:-/usr/lib64/fcitx5} dirs="$addondir:$system_addondir" +# The paths are written into an Exec line and a service file, refuse anything +# that would need quoting there instead of producing a broken or surprising line. +case $dirs in + *[[:space:]\"\'\\\$\`%]*) echo "unsupported characters in $dirs" >&2; exit 1 ;; +esac autostart=$config/autostart/org.fcitx.Fcitx5.desktop service=$data/dbus-1/services/org.fcitx.Fcitx5.service