--- lbbs/src/editor.c 2025/06/13 13:39:46 1.19 +++ lbbs/src/editor.c 2025/06/15 04:43:33 1.22 @@ -79,7 +79,7 @@ EDITOR_DATA *editor_data_load(const char { EDITOR_DATA *p_editor_data; char *p_data_line = NULL; - long line_offsets[MAX_EDITOR_DATA_LINES]; + long line_offsets[MAX_EDITOR_DATA_LINES + 1]; long current_data_line_length = 0; long i; @@ -96,7 +96,7 @@ EDITOR_DATA *editor_data_load(const char return NULL; } - p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES); + p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES + 1); for (i = 0; i < p_editor_data->display_line_total; i++) { @@ -128,8 +128,8 @@ EDITOR_DATA *editor_data_load(const char current_data_line_length += p_editor_data->display_line_lengths[i]; // Trim \n from last line - if (i + 1 == p_editor_data->display_line_total && - p_editor_data->display_line_lengths[i] > 0 && + if (i + 1 == p_editor_data->display_line_total && + p_editor_data->display_line_lengths[i] > 0 && p_editor_data->p_display_lines[i][p_editor_data->display_line_lengths[i] - 1] == '\n') { p_editor_data->display_line_lengths[i]--; @@ -227,6 +227,14 @@ int editor_data_insert(EDITOR_DATA *p_ed return -1; } + // Validate str + if ((str_len == 1 && str[0] <= 0) || + (str_len == 2 && (str[0] >= 0 || str[1] >= 0))) + { + log_error("Invalid input str, len=%d\n", str_len); + return -2; + } + // Get accurate offset of first character of CJK at offset position for (i = 0; i < offset; i++) { @@ -411,6 +419,19 @@ int editor_data_insert(EDITOR_DATA *p_ed } } + // Prevent the last display line from being over-length + if (p_editor_data->display_line_total == MAX_EDITOR_DATA_LINES) + { + len = split_line(p_editor_data->p_display_lines[p_editor_data->display_line_total - 1], SCREEN_COLS - 1, &eol, &display_len); + p_editor_data->p_display_lines[p_editor_data->display_line_total - 1][len] = '\0'; + p_editor_data->display_line_lengths[p_editor_data->display_line_total - 1] = len; + if (*p_display_line + 1 >= p_editor_data->display_line_total) + { + *p_offset = MIN(*p_offset, len); + *p_display_line = p_editor_data->display_line_total - 1; + } + } + return 0; } @@ -671,15 +692,16 @@ int editor_display(EDITOR_DATA *p_editor input_str[str_len] = (char)(ch - 256); str_len++; } - else + else if (str_len > 0) { + log_error("Received %d character over 127 followed by character less than 127\n", str_len); str_len = 0; } if ((ch >= 32 && ch < 127) || (ch > 127 && ch <= 255 && str_len == 2) || // Printable character or GBK ch == CR || ch == KEY_ESC) // Special character { - if (str_len == 0) + if (str_len == 0) // ch >= 32 && ch < 127 { input_str[0] = (char)ch; str_len = 1; @@ -704,12 +726,9 @@ int editor_display(EDITOR_DATA *p_editor input_str, str_len, &last_updated_line) < 0) { log_error("editor_data_insert(str_len=%d) error\n", str_len); - str_len = 0; } else { - str_len = 0; - output_end_row = MIN(SCREEN_ROWS - 1, output_current_row + (int)(last_updated_line - line_current)); line_current -= (output_current_row - row_pos); output_current_row = (int)row_pos; @@ -740,6 +759,7 @@ int editor_display(EDITOR_DATA *p_editor col_pos = offset_out + 1; } + str_len = 0; continue; } else if (ch == KEY_DEL || ch == BACKSPACE) // Del @@ -807,6 +827,7 @@ int editor_display(EDITOR_DATA *p_editor clrline(output_current_row, output_end_row); } + str_len = 0; continue; } @@ -824,6 +845,12 @@ int editor_display(EDITOR_DATA *p_editor break; case Ctrl('E'): // End of line case KEY_CTRL_RIGHT: + if (line_current + (screen_row_total - (output_current_row - screen_begin_row)) >= p_editor_data->display_line_total) // Reach end + { + // last display line does NOT have \n in the end + col_pos = p_editor_data->display_line_lengths[line_current - output_current_row + row_pos] + 1; + break; + } col_pos = MAX(1, p_editor_data->display_line_lengths[line_current - output_current_row + row_pos]); break; case Ctrl('T'): // Top of screen