From 244d4c56768fcc60bd1b23fe45df7a57c7b293ec Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 16 May 2026 11:30:04 -0500 Subject: feat(gptel-tools): harden path validation with file-truename realpath Resolves PATH through file-truename before applying home-directory and read/write checks across the path-handling tools (git_status, git_log, git_diff, move_to_trash, read_text_file, update_text_file, write_text_file, list_directory_files, read_buffer, web_fetch). Without the resolve step, a symlink under HOME pointing outside HOME would pass the prefix check but the tool would act on the real target -- a symlink-escape. move_to_trash also tightens the trash-bin construction (treats empty file extensions correctly) and switches the "critical directories" list to truename-resolved canonical forms so a symlinked ~/.config can't be trashed via an aliased path. update_text_file fixes an off-by-one in the line-count derivation when the source content is empty. Each source change pairs with tests in tests/test-gptel-tools-*.el and tests/test-update-text-file.el covering the realpath escape paths, the empty-extension trash case, and the empty-content line- count edge. Combined coverage is now 100% across all ten gptel-tools source files: 516 / 516 executable lines, 217 tests. --- tests/test-gptel-tools-read-buffer.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tests/test-gptel-tools-read-buffer.el') diff --git a/tests/test-gptel-tools-read-buffer.el b/tests/test-gptel-tools-read-buffer.el index 75efd604..0a854835 100644 --- a/tests/test-gptel-tools-read-buffer.el +++ b/tests/test-gptel-tools-read-buffer.el @@ -40,6 +40,14 @@ (should (equal (cj/read-buffer--get-content (current-buffer)) "from buffer object")))) +(ert-deftest test-gptel-tools-read-buffer-boundary-widened-content () + "Boundary: returns the whole buffer even when the buffer is narrowed." + (with-temp-buffer + (insert "visible\nhidden\n") + (narrow-to-region (point-min) (line-end-position)) + (should (equal (cj/read-buffer--get-content (current-buffer)) + "visible\nhidden\n")))) + (ert-deftest test-gptel-tools-read-buffer-boundary-strips-text-properties () "Boundary: the returned string has no text properties." (with-temp-buffer @@ -56,5 +64,11 @@ (should-error (cj/read-buffer--get-content "test-gptel-tools-read-buffer-absent"))) +(ert-deftest test-gptel-tools-read-buffer-error-killed-buffer-object () + "Error: a killed buffer object signals clearly." + (let ((buffer (generate-new-buffer "test-gptel-tools-read-buffer-killed"))) + (kill-buffer buffer) + (should-error (cj/read-buffer--get-content buffer)))) + (provide 'test-gptel-tools-read-buffer) ;;; test-gptel-tools-read-buffer.el ends here -- cgit v1.2.3