Reject filenames containing NUL bytes.

Such filenames are dangerous, as Emacs would silently only use the
part up to the first NUL byte.  Reject them explicitly instead.

* src/coding.c (encode_file_name_1): New helper function.
(encode_file_name): Check that encoded filename doesn't contain a
NUL byte.
(syms_of_coding): Define 'filenamep' symbol.

* test/src/fileio-tests.el (fileio-tests/null-character): New unit
test.

* etc/NEWS: Document change.
This commit is contained in:
Philipp Stephani 2020-12-23 12:00:46 +01:00
parent 3edc4fd53f
commit 3cbd4169d6
3 changed files with 26 additions and 2 deletions

View file

@ -2212,6 +2212,10 @@ presented to users or passed on to other applications.
** 'start-process-shell-command' and 'start-file-process-shell-command'
do not support the old calling conventions any longer.
** Functions operating on local filenames now check that the filenames
don't contain any NUL bytes. This avoids subtle bugs caused by
silently using only the part of the filename until the first NUL byte.
* Changes in Emacs 28.1 on Non-Free Operating Systems

View file

@ -10354,8 +10354,8 @@ decode_file_name (Lisp_Object fname)
#endif
}
Lisp_Object
encode_file_name (Lisp_Object fname)
static Lisp_Object
encode_file_name_1 (Lisp_Object fname)
{
/* This is especially important during bootstrap and dumping, when
file-name encoding is not yet known, and therefore any non-ASCII
@ -10380,6 +10380,19 @@ encode_file_name (Lisp_Object fname)
#endif
}
Lisp_Object
encode_file_name (Lisp_Object fname)
{
Lisp_Object encoded = encode_file_name_1 (fname);
/* No system accepts NUL bytes in filenames. Allowing them can
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);
return encoded;
}
DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
2, 4, 0,
doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.
@ -11780,6 +11793,7 @@ syms_of_coding (void)
DEFSYM (Qignored, "ignored");
DEFSYM (Qutf_8_string_p, "utf-8-string-p");
DEFSYM (Qfilenamep, "filenamep");
defsubr (&Scoding_system_p);
defsubr (&Sread_coding_system);

View file

@ -155,3 +155,9 @@ Also check that an encoding error can appear in a symlink."
(write-region "hello\n" nil f nil 'silent)
(should-error (insert-file-contents f) :type 'circular-list)
(delete-file f)))
(ert-deftest fileio-tests/null-character ()
(should-error (file-exists-p "/foo\0bar")
:type 'wrong-type-argument))
;;; fileio-tests.el ends here