]> git.eshelyaron.com Git - emacs.git/commitdiff
Check for null bytes in filenames in 'expand-file-name' (bug#49723)
authorFederico Tedin <federicotedin@gmail.com>
Tue, 14 Sep 2021 22:15:16 +0000 (00:15 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 18 Sep 2021 06:36:26 +0000 (09:36 +0300)
* src/fileio.c (expand-file-name): Check for null bytes for both
NAME and DEFAULT-DIRECTORY arguments.  Also check for null bytes
in buffer-local default-directory, assuming it is used.
* src/coding.c (encode_file_name): Use CHECK_STRING_NULL_BYTES.
* src/lisp.h (CHECK_STRING_NULL_BYTES): Add function for checking
for null bytes in Lisp strings.
* test/src/fileio-tests.el (fileio-test--expand-file-name-null-bytes):
Add test for new changes to expand-file-name.
* etc/NEWS: Announce changes.

etc/NEWS
src/coding.c
src/fileio.c
src/lisp.h
test/src/fileio-tests.el

index 515f8bac562b232bee0943e58995cf569039e18b..b93e87642b84e72f4ed9eea416bd27996a872680 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -294,6 +294,13 @@ personalize the uniquified buffer name.
 ---
 ** 'remove-hook' is now an interactive command.
 
+** 'expand-file-name' now checks for null bytes in filenames.
+The function will now check for null bytes in both NAME and
+DEFAULT-DIRECTORY arguments, as well as in the 'default-directory'
+buffer-local variable, assuming its value is used.  If null bytes are
+found, 'expand-file-name' will signal an error.
+
+---
 ** Frames
 
 +++
index d027c7d53997b71505a79811770d99069839b0a0..7030a53869a5351068e11811bca84fa5a74d68a4 100644 (file)
@@ -10430,8 +10430,7 @@ encode_file_name (Lisp_Object fname)
      cause subtle bugs because the system would silently use a
      different filename than expected.  Perform this check after
      encoding to not miss NUL bytes introduced through encoding.  */
-  CHECK_TYPE (memchr (SSDATA (encoded), '\0', SBYTES (encoded)) == NULL,
-              Qfilenamep, fname);
+  CHECK_STRING_NULL_BYTES (encoded);
   return encoded;
 }
 
index 0db8ed793b36313af0f4016dc941edd147045e1e..3c13d3fe416a0505ffbb9d9b158c4eaa63915578 100644 (file)
@@ -945,6 +945,7 @@ the root directory.  */)
   USE_SAFE_ALLOCA;
 
   CHECK_STRING (name);
+  CHECK_STRING_NULL_BYTES (name);
 
   /* If the file name has special constructs in it,
      call the corresponding file name handler.  */
@@ -993,7 +994,10 @@ the root directory.  */)
       if (STRINGP (dir))
        {
          if (file_name_absolute_no_tilde_p (dir))
-           default_directory = dir;
+           {
+             CHECK_STRING_NULL_BYTES (dir);
+             default_directory = dir;
+           }
          else
            {
              Lisp_Object absdir
index 7bfc69b647b195074660f6925d938f285ed78312..9716b34baeeca46c41a5a0cf7d8a1d975532a7ed 100644 (file)
@@ -1615,6 +1615,13 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
   XSTRING (string)->u.s.size = newsize;
 }
 
+INLINE void
+CHECK_STRING_NULL_BYTES (Lisp_Object string)
+{
+  CHECK_TYPE (memchr (SSDATA (string), '\0', SBYTES (string)) == NULL,
+             Qfilenamep, string);
+}
+
 /* A regular vector is just a header plus an array of Lisp_Objects.  */
 
 struct Lisp_Vector
index f4d123b42611e5bbdc1dc8d7dc2530d3cbc392c3..438ebebb76976745bf33f940a855c9340254adc5 100644 (file)
@@ -136,6 +136,15 @@ Also check that an encoding error can appear in a symlink."
     (should (and (file-name-absolute-p name)
                  (not (eq (aref name 0) ?~))))))
 
+(ert-deftest fileio-test--expand-file-name-null-bytes ()
+  "Test that expand-file-name checks for null bytes in filenames."
+  (should-error (expand-file-name (concat "file" (char-to-string ?\0) ".txt"))
+                :type 'wrong-type-argument)
+  (should-error (expand-file-name "file.txt" (concat "dir" (char-to-string ?\0)))
+                :type 'wrong-type-argument)
+  (let ((default-directory (concat "dir" (char-to-string ?\0))))
+    (should-error (expand-file-name "file.txt") :type 'wrong-type-argument)))
+
 (ert-deftest fileio-tests--file-name-absolute-p ()
   "Test file-name-absolute-p."
   (dolist (suffix '("" "/" "//" "/foo" "/foo/" "/foo//" "/foo/bar"))