aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2025-07-12 16:21:59 -0700
committerPaul Eggert2025-07-13 21:09:39 -0700
commite98da5cc3f394aef21b7ad3c46b104e057a8954b (patch)
tree1881455d401f7b236c16df01644a5c3dd8d963a2 /src
parentde0bb2e059f1c404ca328509f3eb90cdf90256c5 (diff)
downloademacs-e98da5cc3f394aef21b7ad3c46b104e057a8954b.tar.gz
emacs-e98da5cc3f394aef21b7ad3c46b104e057a8954b.zip
insert-file-contents do not rely on st_size
This fix was prompted by Bug#77315. * src/fileio.c (Finsert_file_contents): Do not rely on st_size for anything other than a hint about the file size. Trust only the file size as revealed by a read that returns 0.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c32
1 files changed, 4 insertions, 28 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 6292960b07b..ae033797aa3 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4225,20 +4225,6 @@ by calling `format-decode', which see. */)
4225 orig_filename); 4225 orig_filename);
4226 } 4226 }
4227 4227
4228 if (end_offset == TYPE_MAXIMUM (off_t))
4229 {
4230 if (regular)
4231 {
4232 end_offset = file_size_hint;
4233
4234 /* The file size returned from fstat may be zero, but data
4235 may be readable nonetheless, for example when this is a
4236 file in the /proc filesystem. */
4237 if (end_offset == 0)
4238 end_offset = READ_BUF_SIZE;
4239 }
4240 }
4241
4242 /* Check now whether the buffer will become too large, 4228 /* Check now whether the buffer will become too large,
4243 in the likely case where the file's length is not changing. 4229 in the likely case where the file's length is not changing.
4244 This saves a lot of needless work before a buffer overflow. */ 4230 This saves a lot of needless work before a buffer overflow. */
@@ -4817,16 +4803,7 @@ by calling `format-decode', which see. */)
4817 goto handled; 4803 goto handled;
4818 } 4804 }
4819 4805
4820 /* From here on, treat a file with zero or unknown size as not seekable. 4806 total = end_offset - beg_offset;
4821 This causes us to read until we actually hit EOF. */
4822 if (file_size_hint <= 0)
4823 seekable = false;
4824
4825 if (seekable || end_offset < TYPE_MAXIMUM (off_t))
4826 total = end_offset - beg_offset;
4827 else
4828 /* All we can do is guess. */
4829 total = READ_BUF_SIZE;
4830 4807
4831 if (NILP (visit) && total > 0) 4808 if (NILP (visit) && total > 0)
4832 { 4809 {
@@ -4874,7 +4851,7 @@ by calling `format-decode', which see. */)
4874 { 4851 {
4875 ptrdiff_t gap_size = GAP_SIZE; 4852 ptrdiff_t gap_size = GAP_SIZE;
4876 4853
4877 while (end_offset == TYPE_MAXIMUM (off_t) || inserted < total) 4854 while (inserted < total)
4878 { 4855 {
4879 ptrdiff_t this; 4856 ptrdiff_t this;
4880 4857
@@ -4886,9 +4863,8 @@ by calling `format-decode', which see. */)
4886 } 4863 }
4887 4864
4888 /* 'try' is reserved in some compilers (Microsoft C). */ 4865 /* 'try' is reserved in some compilers (Microsoft C). */
4889 ptrdiff_t trytry = min (gap_size, READ_BUF_SIZE); 4866 ptrdiff_t trytry = min (gap_size,
4890 if (seekable || end_offset < TYPE_MAXIMUM (off_t)) 4867 min (total - inserted, READ_BUF_SIZE));
4891 trytry = min (trytry, total - inserted);
4892 4868
4893 if (!seekable && end_offset == TYPE_MAXIMUM (off_t)) 4869 if (!seekable && end_offset == TYPE_MAXIMUM (off_t))
4894 { 4870 {