From 3cbd4169d6dd370b4fa8180fc2adfbf426f57837 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Wed, 23 Dec 2020 12:00:46 +0100 Subject: 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. --- src/coding.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/coding.c') diff --git a/src/coding.c b/src/coding.c index 1afa4aa4749..8c2443889d4 100644 --- a/src/coding.c +++ b/src/coding.c @@ -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); -- cgit v1.2.1