The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=705a88a717272c52c897c3d28dc2997980ee67f4

commit 705a88a717272c52c897c3d28dc2997980ee67f4
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-07-06 13:16:32 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-07-06 13:18:13 +0000

    ee: Improve handling of malformed UTF-8 characters
    
    In delete(), when copying the deleted character to the d_char buffer,
    don't assume that it fits.  utf8_prev() may return a sequence of more
    than 5 bytes.
    
    In insert_utf8(), fix the copy-up of the line.  We extended the line by
    "len" bytes, so "temp" has to be repositioned accordingly.  Compare with
    plain insert().
    
    Use sizeof when copying to buffers instead of hard-coding buffer sizes.
    
    Don't dynamically allocate d_char, there is no need.
    
    Fixes:          62fba0054d9e ("ee: add unicode support")
    Reported by:    Sayono Hiragi (overflow in delete())
    Reviewed by:    bapt
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D57996
---
 contrib/ee/ee.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/contrib/ee/ee.c b/contrib/ee/ee.c
index 13a554bf0146..94bb296bcd65 100644
--- a/contrib/ee/ee.c
+++ b/contrib/ee/ee.c
@@ -194,7 +194,7 @@ unsigned char *srch_2;              /* pointer to next 
character of string  */
 unsigned char *srch_3;
 unsigned char *in_file_name = NULL;    /* name of input file           */
 char *tmp_file;        /* temporary file name                  */
-unsigned char *d_char;         /* deleted character                    */
+unsigned char d_char[5];       /* deleted character                    */
 unsigned char *d_word;         /* deleted word                         */
 unsigned char *d_line;         /* deleted line                         */
 char in_string[513];   /* buffer for reading a file            */
@@ -598,7 +598,6 @@ main(int argc, char *argv[])
        signal(SIGCHLD, SIG_DFL);
        signal(SIGSEGV, SIG_DFL);
        signal(SIGINT, edit_abort);
-       d_char = malloc(5);     /* UTF-8 chars can be up to 4 bytes + NUL */
        d_word = malloc(150);
        *d_word = '\0';
        d_line = NULL;
@@ -832,7 +831,6 @@ insert_utf8(const unsigned char *mb, int len)
 {
        int counter;
        unsigned char *temp;
-       unsigned char *temp2;
        int i;
 
        text_changes = TRUE;
@@ -848,17 +846,18 @@ insert_utf8(const unsigned char *mb, int len)
                counter++;
                temp++;
        }
-       temp++;
-       while (point < temp)
+       temp += len;
+       while (point + len - 1 < temp)
        {
+               unsigned char *temp2;
+
                temp2 = temp - len;
                *temp = *temp2;
                temp--;
        }
 
        /* copy all bytes of the UTF-8 character */
-       for (i = 0; i < len; i++)
-               point[i] = mb[i];
+       memmove(point, mb, len);
 
        /* display the character before advancing past it */
        wclrtoeol(text_win);
@@ -931,8 +930,10 @@ delete(int disp)
                scr_pos = scr_horz;
                if (in == 8)
                {
-                       memcpy(d_char, point, del_width);
-                       d_char[del_width] = '\0';
+                       size_t width = min(del_width, 4);
+
+                       memcpy(d_char, point, width);
+                       d_char[width] = '\0';
                }
                while (temp_pos <= curr_line->line_length)
                {
@@ -2993,7 +2994,7 @@ del_word(void)
        if (d_word != NULL)
                free(d_word);
        d_word = malloc(curr_line->line_length);
-       memcpy(tmp_char, d_char, 5);
+       memcpy(tmp_char, d_char, sizeof(tmp_char));
        d_word3 = point;
        d_word2 = d_word;
        tposit = position;
@@ -3026,7 +3027,7 @@ del_word(void)
        curr_line->line_length -= difference;
        *d_word2 = '\0';
        draw_line(scr_vert, scr_horz,point,position,curr_line->line_length);
-       memcpy(d_char, tmp_char, 5);
+       memcpy(d_char, tmp_char, sizeof(d_char));
        text_changes = TRUE;
        formatted = FALSE;
 }
@@ -4141,7 +4142,7 @@ Format(void)
        unsigned char *temp_dword;
        unsigned char temp_d_char[5];
 
-       memcpy(temp_d_char, d_char, 5);
+       memcpy(temp_d_char, d_char, sizeof(temp_d_char));
 
 /*
  |     if observ_margins is not set, or the current line is blank,
@@ -4336,7 +4337,7 @@ Format(void)
        case_sen = temp_case;
        free(srch_str);
        srch_str = tmp_srchstr;
-       memcpy(d_char, temp_d_char, 5);
+       memcpy(d_char, temp_d_char, sizeof(d_char));
        auto_format = tmp_af;
 
        midscreen(scr_vert, point);
@@ -4720,7 +4721,7 @@ Auto_Format(void)
        unsigned char temp_d_char[5];
        unsigned char *tmp_d_line;
 
-       memcpy(temp_d_char, d_char, 5);
+       memcpy(temp_d_char, d_char, sizeof(temp_d_char));
 
 /*
  |     if observ_margins is not set, or the current line is blank, 
@@ -4946,7 +4947,7 @@ Auto_Format(void)
        case_sen = temp_case;
        free(srch_str);
        srch_str = tmp_srchstr;
-       memcpy(d_char, temp_d_char, 5);
+       memcpy(d_char, temp_d_char, sizeof(d_char));
        auto_format = TRUE;
        dlt_line->line_length = tmp_d_line_length;
        d_line = tmp_d_line;

Reply via email to