diff options
| author | Paul Eggert | 2025-07-12 14:22:02 -0700 |
|---|---|---|
| committer | Paul Eggert | 2025-07-13 21:09:39 -0700 |
| commit | 56091b6d5cccecf320796bd62e36adc64f45b614 (patch) | |
| tree | 632ebda8391ee84a277b5fcf54947db043c8595a /src | |
| parent | e6c684797361aec99b1b9eef139bab92679355ec (diff) | |
| download | emacs-56091b6d5cccecf320796bd62e36adc64f45b614.tar.gz emacs-56091b6d5cccecf320796bd62e36adc64f45b614.zip | |
Fix insert-file-contents integer overflows
* src/fileio.c (Finsert_file_contents): Change ‘total’ from
ptrdiff_t to off_t since it might not fit in ptrdiff_t.
Check for overflow when estimating the insertion size.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/fileio.c b/src/fileio.c index b639be1493b..3c371dea98d 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -4065,7 +4065,7 @@ by calling `format-decode', which see. */) | |||
| 4065 | specpdl_ref count = SPECPDL_INDEX (); | 4065 | specpdl_ref count = SPECPDL_INDEX (); |
| 4066 | Lisp_Object handler, val, insval, orig_filename, old_undo; | 4066 | Lisp_Object handler, val, insval, orig_filename, old_undo; |
| 4067 | Lisp_Object p; | 4067 | Lisp_Object p; |
| 4068 | ptrdiff_t total = 0; | 4068 | off_t total = 0; |
| 4069 | bool regular; | 4069 | bool regular; |
| 4070 | int save_errno = 0; | 4070 | int save_errno = 0; |
| 4071 | char read_buf[READ_BUF_SIZE]; | 4071 | char read_buf[READ_BUF_SIZE]; |
| @@ -4818,10 +4818,16 @@ by calling `format-decode', which see. */) | |||
| 4818 | move_gap_both (PT, PT_BYTE); | 4818 | move_gap_both (PT, PT_BYTE); |
| 4819 | 4819 | ||
| 4820 | /* Ensure the gap is at least one byte larger than needed for the | 4820 | /* Ensure the gap is at least one byte larger than needed for the |
| 4821 | estimated file size, so that in the usual case we read to EOF | 4821 | estimated insertion, so that in the usual case we read |
| 4822 | without reallocating. */ | 4822 | without reallocating. */ |
| 4823 | if (GAP_SIZE <= total) | 4823 | off_t inserted_estimate = min (end_offset, file_size_hint) - beg_offset; |
| 4824 | make_gap (total - GAP_SIZE + 1); | 4824 | if (GAP_SIZE <= inserted_estimate) |
| 4825 | { | ||
| 4826 | ptrdiff_t growth; | ||
| 4827 | if (ckd_sub (&growth, inserted_estimate, GAP_SIZE - 1)) | ||
| 4828 | buffer_overflow (); | ||
| 4829 | make_gap (growth); | ||
| 4830 | } | ||
| 4825 | 4831 | ||
| 4826 | if (beg_offset != 0 || (!NILP (replace) | 4832 | if (beg_offset != 0 || (!NILP (replace) |
| 4827 | && !BASE_EQ (replace, Qunbound))) | 4833 | && !BASE_EQ (replace, Qunbound))) |