summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2025-01-22 11:06:06 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2025-07-13 21:09:38 -0700
commit0a3c8a4df3f9e15737e4e5b4aecd2e63d2abbc4f (patch)
treecec0652bfdb92bfd6f470753a83820cfd79a6a57
parentffd65be2277b9a30e77a00ad69c9ba21459f72c5 (diff)
Don’t trust st_size when scanning file head+tail
* src/fileio.c (Finsert_file_contents): Do not look at st_size when scanning the file’s head and tail for a coding system comment. Instead, just use read and SEEK_END and don’t worry if the latter fails. st_size and lseek might not work in a /proc file system.
-rw-r--r--src/fileio.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 82ee22d2187..a3a49d179c4 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4271,24 +4271,21 @@ by calling `format-decode', which see. */)
{
/* Find a coding system specified in the heading two
lines or in the tailing several lines of the file.
- We assume that the 1K-byte and 3K-byte for heading
+ Assume that the 1 KiB and 3 KiB for heading
and tailing respectively are sufficient for this
- purpose. */
- int nread;
-
- if (st.st_size <= (1024 * 4))
- nread = emacs_fd_read (fd, read_buf, 1024 * 4);
- else
+ purpose. Because the file may be in /proc,
+ do not use st_size or report any SEEK_END failure. */
+ ptrdiff_t nread = emacs_fd_read (fd, read_buf, 4 * 1024);
+ if (nread == 4 * 1024)
{
- nread = emacs_fd_read (fd, read_buf, 1024);
- if (nread == 1024)
+ off_t tailoff = emacs_fd_lseek (fd, - 3 * 1024, SEEK_END);
+ if (tailoff < 0)
+ seekable = false;
+ else if (1024 < tailoff)
{
- int ntail;
- if (emacs_fd_lseek (fd, st.st_size - 1024 * 3, SEEK_CUR) < 0)
- report_file_error ("Setting file position",
- orig_filename);
- ntail = emacs_fd_read (fd, read_buf + nread, 1024 * 3);
- nread = ntail < 0 ? ntail : nread + ntail;
+ ptrdiff_t ntail = emacs_fd_read (fd, read_buf + 1024,
+ 3 * 1024);
+ nread = ntail < 0 ? ntail : 1024 + ntail;
}
}