diff options
| author | Paul Eggert | 2025-07-12 16:21:59 -0700 |
|---|---|---|
| committer | Paul Eggert | 2025-07-13 21:09:39 -0700 |
| commit | e98da5cc3f394aef21b7ad3c46b104e057a8954b (patch) | |
| tree | 1881455d401f7b236c16df01644a5c3dd8d963a2 /src | |
| parent | de0bb2e059f1c404ca328509f3eb90cdf90256c5 (diff) | |
| download | emacs-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.c | 32 |
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 | { |