diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-23 19:21:31 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-23 19:21:31 -0500 |
| commit | 64f349326454583a375a4f8d6df44966833e3512 (patch) | |
| tree | 93c69d404a96ee3122fe275c33bf43e29ae1961b /tests | |
| parent | b3dba452b13cddc51477f3bdcfef663783d3fa5b (diff) | |
| download | dotemacs-64f349326454583a375a4f8d6df44966833e3512.tar.gz dotemacs-64f349326454583a375a4f8d6df44966833e3512.zip | |
fix(dwim-shell): quote and validate user-controlled shell inputs
Several dwim-shell commands interpolated user-controlled strings straight into shell templates, so a value with spaces, quotes, or shell metacharacters could break out of the command. The worst was git-clone-clipboard-url, which dropped raw clipboard contents into "git clone <<cb>>".
I added three pure validators (git URL, ffmpeg timestamp, rename prefix) and fixed the interpolation sites. git-clone now validates the clipboard and passes the URL through shell-quote-argument instead of <<cb>>. The GPG recipient and the 7z archive name go through shell-quote-argument instead of hand-written single quotes. The thumbnail timestamp and the rename prefix are validated to a safe shape before they reach the command, so the unquoted interpolation that remains is constrained to digits, colons, and filename-safe characters.
The fifth case in the ticket, the video-concat filelist built with echo/tr/sed, is a redesign rather than a quoting fix and is filed as a follow-up.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-dwim-shell-config-input-safety.el | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/tests/test-dwim-shell-config-input-safety.el b/tests/test-dwim-shell-config-input-safety.el new file mode 100644 index 00000000..2ff2edc9 --- /dev/null +++ b/tests/test-dwim-shell-config-input-safety.el @@ -0,0 +1,71 @@ +;;; test-dwim-shell-config-input-safety.el --- Tests for input validators -*- lexical-binding: t; -*- + +;;; Commentary: +;; Covers the pure input validators that guard user-controlled strings before +;; they reach a shell command: git clone URLs, ffmpeg timestamps, and rename +;; prefixes. These reject shell metacharacters and malformed input so the +;; command-construction sites stay injection-safe. + +;;; Code: + +(when noninteractive + (package-initialize)) + +(require 'ert) +(require 'dwim-shell-config) + +;; --------------------------------------------------------------------------- +;;; cj/dwim-shell--valid-git-url-p +;; --------------------------------------------------------------------------- + +(ert-deftest test-dwim-valid-git-url-accepts-common-forms () + "Normal: https, scp-style, ssh, and git URLs are accepted." + (dolist (url '("https://github.com/user/repo.git" + "http://example.com/x" + "git@github.com:user/repo.git" + "ssh://git@host/path/repo.git" + "git://host/path")) + (should (cj/dwim-shell--valid-git-url-p url)))) + +(ert-deftest test-dwim-valid-git-url-rejects-empty-and-junk () + "Boundary: empty string and non-URL text are rejected." + (should-not (cj/dwim-shell--valid-git-url-p "")) + (should-not (cj/dwim-shell--valid-git-url-p "not a url")) + (should-not (cj/dwim-shell--valid-git-url-p " "))) + +(ert-deftest test-dwim-valid-git-url-rejects-shell-metacharacters () + "Error: URLs carrying shell metacharacters are rejected." + (should-not (cj/dwim-shell--valid-git-url-p "https://x.com;reboot")) + (should-not (cj/dwim-shell--valid-git-url-p "https://x.com; rm -rf /")) + (should-not (cj/dwim-shell--valid-git-url-p "https://x.com$(whoami)"))) + +;; --------------------------------------------------------------------------- +;;; cj/dwim-shell--valid-ffmpeg-timestamp-p +;; --------------------------------------------------------------------------- + +(ert-deftest test-dwim-valid-timestamp-accepts-seconds-and-clock () + "Normal: plain seconds and HH:MM:SS forms are accepted." + (dolist (ts '("5" "0" "90.5" "00:05" "00:00:05" "1:02:03.5")) + (should (cj/dwim-shell--valid-ffmpeg-timestamp-p ts)))) + +(ert-deftest test-dwim-valid-timestamp-rejects-bad-input () + "Error: non-numeric, negative, or metacharacter-bearing timestamps rejected." + (dolist (ts '("" "abc" "-5" "5; rm" "00:00:05; reboot")) + (should-not (cj/dwim-shell--valid-ffmpeg-timestamp-p ts)))) + +;; --------------------------------------------------------------------------- +;;; cj/dwim-shell--safe-rename-prefix-p +;; --------------------------------------------------------------------------- + +(ert-deftest test-dwim-safe-rename-prefix-accepts-filename-safe () + "Normal/Boundary: alphanumerics, spaces, dot, dash, underscore, and empty." + (dolist (p '("" "img_" "vacation 2026" "shot-01.")) + (should (cj/dwim-shell--safe-rename-prefix-p p)))) + +(ert-deftest test-dwim-safe-rename-prefix-rejects-unsafe () + "Error: quotes, slashes, semicolons, and newlines are rejected." + (dolist (p '("a'b" "a/b" "a;b" "a\nb")) + (should-not (cj/dwim-shell--safe-rename-prefix-p p)))) + +(provide 'test-dwim-shell-config-input-safety) +;;; test-dwim-shell-config-input-safety.el ends here |
