From 612356183dc27d8610d70762db370701565d33f1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 20 Jul 2025 12:38:43 -0700 Subject: [PATCH] Fix insert-file-contents infloop with unlucky END MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This partially reverts 55f41ca3aa8fe487d10730708a7396137a2c9d18, which was a partial fix for Bug#77315. * src/fileio.c (Finsert_file_contents): Go back to accepting partial reads when doing the optimized way when code conversion is not needed. This avoids an unlikely bug when END happens to lie at a buffer boundary, causing an infloop. For consistency, do the same when doing code conversion (though there’s no bug in then), as there’s not a real need for emacs_full_read there either. (cherry picked from commit 27e0f0f79b9c97796fc89fedf3c05517532f0475) --- src/fileio.c | 67 +++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index 9b47b565458..76e5e56190e 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4454,42 +4454,10 @@ by calling `format-decode', which see. */) bytes_to_read = min (bytes_to_read, end_offset - curpos); ptrdiff_t nread = (bytes_to_read <= 0 ? 0 - : emacs_full_read (fd, read_buf, bytes_to_read)); + : emacs_fd_read (fd, read_buf, bytes_to_read)); if (nread < 0) report_file_error ("Read error", orig_filename); - - if (0 < nread) - { - curpos += nread; - - if (CODING_REQUIRE_DETECTION (&coding)) - { - coding_system - = detect_coding_system ((unsigned char *) read_buf, - nread, nread, 1, 0, - coding_system); - setup_coding_system (coding_system, &coding); - } - - if (CODING_REQUIRE_DECODING (&coding)) - /* We found that the file should be decoded somehow. - Let's give up here. */ - { - giveup_match_end = true; - break; - } - - ptrdiff_t bufpos = 0; - ptrdiff_t bufposlim = min (nread, same_at_end - same_at_start); - while (bufpos < bufposlim - && FETCH_BYTE (same_at_start) == read_buf[bufpos]) - same_at_start++, bufpos++; - /* If we found a discrepancy, stop the scan. */ - if (bufpos != nread) - break; - } - - if (nread < bytes_to_read) + else if (nread == 0) { /* Data inserted from the file match the buffer's leading bytes, so there's no need to replace anything. */ @@ -4500,6 +4468,33 @@ by calling `format-decode', which see. */) del_range_byte (same_at_start, same_at_end); goto handled; } + + curpos += nread; + + if (CODING_REQUIRE_DETECTION (&coding)) + { + coding_system = detect_coding_system ((unsigned char *) read_buf, + nread, nread, 1, 0, + coding_system); + setup_coding_system (coding_system, &coding); + } + + if (CODING_REQUIRE_DECODING (&coding)) + /* We found that the file should be decoded somehow. + Let's give up here. */ + { + giveup_match_end = true; + break; + } + + ptrdiff_t bufpos = 0; + ptrdiff_t bufposlim = min (nread, same_at_end - same_at_start); + while (bufpos < bufposlim + && FETCH_BYTE (same_at_start) == read_buf[bufpos]) + same_at_start++, bufpos++; + /* If we found a discrepancy, stop the scan. */ + if (bufpos != nread) + break; } off_t same_at_start_pos = beg_offset + (same_at_start - BEGV_BYTE); @@ -4692,7 +4687,7 @@ by calling `format-decode', which see. */) quitting while reading a huge file. */ ptrdiff_t trial = sizeof read_buf - unprocessed; - this = emacs_full_read (fd, read_buf + unprocessed, trial); + this = emacs_fd_read (fd, read_buf + unprocessed, trial); if (this < 0) report_file_error ("Read error", orig_filename); if (this == 0) @@ -4706,8 +4701,6 @@ by calling `format-decode', which see. */) unprocessed = coding.carryover_bytes; if (coding.carryover_bytes > 0) memcpy (read_buf, coding.carryover, unprocessed); - if (this < trial) - break; } emacs_fd_close (fd); -- 2.39.5