mirror of
https://github.com/weechat/weechat.git
synced 2026-06-30 14:56:39 +02:00
core: fix buffer overflow in function utf8_next_char and return NULL for empty string
Now the function utf8_next_char with an empty string returns NULL instead of
the next char, which is most of the time after an allocated buffer.
And the function utf8_char_size with an empty string now returns 0 instead of
1.
This indirectly fixes a buffer overflow in function eval_string_range_chars
when the input string is empty (for example when doing `/eval -n ${chars:}`).
This commit is contained in:
@@ -323,9 +323,11 @@ gui_completion_nick_has_ignored_chars (const char *string)
|
||||
int char_size;
|
||||
char utf_char[16];
|
||||
|
||||
while (string[0])
|
||||
while (string && string[0])
|
||||
{
|
||||
char_size = utf8_char_size (string);
|
||||
if (char_size < 1)
|
||||
break;
|
||||
memcpy (utf_char, string, char_size);
|
||||
utf_char[char_size] = '\0';
|
||||
|
||||
@@ -352,9 +354,11 @@ gui_completion_nick_strdup_ignore_chars (const char *string)
|
||||
|
||||
result = malloc (strlen (string) + 1);
|
||||
pos = result;
|
||||
while (string[0])
|
||||
while (string && string[0])
|
||||
{
|
||||
char_size = utf8_char_size (string);
|
||||
if (char_size < 1)
|
||||
break;
|
||||
memcpy (utf_char, string, char_size);
|
||||
utf_char[char_size] = '\0';
|
||||
|
||||
@@ -915,13 +919,16 @@ gui_completion_find_context (struct t_gui_completion *completion,
|
||||
if (string_is_command_char (ptr_data))
|
||||
{
|
||||
ptr_data = utf8_next_char (ptr_data);
|
||||
if (ptr_data < data + pos)
|
||||
if (ptr_data)
|
||||
{
|
||||
if (string_is_command_char (ptr_data))
|
||||
ptr_data = utf8_next_char (ptr_data);
|
||||
if (ptr_data < data + pos)
|
||||
{
|
||||
if (string_is_command_char (ptr_data))
|
||||
ptr_data = utf8_next_char (ptr_data);
|
||||
}
|
||||
if (!string_is_command_char (ptr_data))
|
||||
ptr_command = ptr_data;
|
||||
}
|
||||
if (!string_is_command_char (ptr_data))
|
||||
ptr_command = ptr_data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+64
-19
@@ -871,10 +871,14 @@ gui_input_delete_next_char (struct t_gui_buffer *buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
pos = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
pos_next = (char *)utf8_next_char (pos);
|
||||
if (!pos_next)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
|
||||
char_size = pos_next - pos;
|
||||
size_to_move = strlen (pos_next);
|
||||
memmove (pos, pos_next, size_to_move);
|
||||
@@ -899,9 +903,13 @@ gui_input_delete_range (struct t_gui_buffer *buffer,
|
||||
char *start,
|
||||
char *end)
|
||||
{
|
||||
const char *ptr_next;
|
||||
int size_deleted, length_deleted;
|
||||
|
||||
size_deleted = utf8_next_char (end) - start;
|
||||
ptr_next = utf8_next_char (end);
|
||||
if (!ptr_next)
|
||||
return;
|
||||
size_deleted = ptr_next - start;
|
||||
length_deleted = utf8_strnlen (start, size_deleted);
|
||||
|
||||
gui_input_clipboard_copy (start, size_deleted);
|
||||
@@ -956,7 +964,8 @@ gui_input_delete_previous_word (struct t_gui_buffer *buffer)
|
||||
else
|
||||
string = buffer->input_buffer;
|
||||
|
||||
gui_input_delete_range (buffer, string, start);
|
||||
if (string)
|
||||
gui_input_delete_range (buffer, string, start);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -994,7 +1003,8 @@ gui_input_delete_previous_word_whitespace (struct t_gui_buffer *buffer)
|
||||
else
|
||||
string = buffer->input_buffer;
|
||||
|
||||
gui_input_delete_range (buffer, string, start);
|
||||
if (string)
|
||||
gui_input_delete_range (buffer, string, start);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1016,13 +1026,13 @@ gui_input_delete_next_word (struct t_gui_buffer *buffer)
|
||||
string = start;
|
||||
length_deleted = 0;
|
||||
/* move to the right until we reach a word char */
|
||||
while (string[0] && !string_is_word_char_input (string))
|
||||
while (string && string[0] && !string_is_word_char_input (string))
|
||||
{
|
||||
string = (char *)utf8_next_char (string);
|
||||
length_deleted++;
|
||||
}
|
||||
/* move to the right to skip the whole word */
|
||||
while (string[0] && string_is_word_char_input (string))
|
||||
while (string && string[0] && string_is_word_char_input (string))
|
||||
{
|
||||
string = (char *)utf8_next_char (string);
|
||||
length_deleted++;
|
||||
@@ -1060,12 +1070,14 @@ gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer)
|
||||
if (!buffer->input || (buffer->input_buffer_pos <= 0))
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
start = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
|
||||
beginning_of_line = (char *)utf8_beginning_of_line (buffer->input_buffer,
|
||||
start);
|
||||
if (!beginning_of_line)
|
||||
return;
|
||||
|
||||
if (beginning_of_line == start)
|
||||
{
|
||||
beginning_of_line = (char *)utf8_prev_char (buffer->input_buffer,
|
||||
@@ -1074,6 +1086,11 @@ gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer)
|
||||
beginning_of_line);
|
||||
}
|
||||
|
||||
if (!beginning_of_line)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
|
||||
size_deleted = start - beginning_of_line;
|
||||
length_deleted = utf8_strnlen (beginning_of_line, size_deleted);
|
||||
gui_input_clipboard_copy (beginning_of_line, size_deleted);
|
||||
@@ -1109,7 +1126,6 @@ gui_input_delete_end_of_line (struct t_gui_buffer *buffer)
|
||||
if (!buffer->input)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
start = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
|
||||
@@ -1117,7 +1133,14 @@ gui_input_delete_end_of_line (struct t_gui_buffer *buffer)
|
||||
end_of_line = (char *)utf8_next_char (start);
|
||||
else
|
||||
end_of_line = start;
|
||||
if (!end_of_line)
|
||||
return;
|
||||
|
||||
end_of_line = (char *)utf8_end_of_line (end_of_line);
|
||||
if (!end_of_line)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
|
||||
size_deleted = end_of_line - start;
|
||||
length_deleted = utf8_strnlen (start, size_deleted);
|
||||
@@ -1215,7 +1238,6 @@ gui_input_delete_line (struct t_gui_buffer *buffer)
|
||||
if (!buffer->input)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
start = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
|
||||
@@ -1223,6 +1245,11 @@ gui_input_delete_line (struct t_gui_buffer *buffer)
|
||||
start);
|
||||
end_of_line = (char *)utf8_end_of_line (start);
|
||||
|
||||
if (!beginning_of_line || !end_of_line)
|
||||
return;
|
||||
|
||||
gui_buffer_undo_snap (buffer);
|
||||
|
||||
size_deleted = end_of_line - beginning_of_line;
|
||||
length_deleted = utf8_strnlen (beginning_of_line, size_deleted);
|
||||
|
||||
@@ -1321,12 +1348,16 @@ gui_input_move_beginning_of_line (struct t_gui_buffer *buffer)
|
||||
buffer->input_buffer_pos);
|
||||
original_pos = pos;
|
||||
pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
if (pos == original_pos)
|
||||
{
|
||||
pos = (char *)utf8_prev_char (buffer->input_buffer, pos);
|
||||
pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
|
||||
}
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
@@ -1354,11 +1385,9 @@ gui_input_move_end_of_line (struct t_gui_buffer *buffer)
|
||||
pos = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
if (pos[0] && pos[0] == '\n')
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
}
|
||||
pos = (char *)utf8_end_of_line (pos);
|
||||
if (pos[0])
|
||||
if (pos && pos[0])
|
||||
{
|
||||
buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
@@ -1462,6 +1491,8 @@ gui_input_move_previous_word (struct t_gui_buffer *buffer)
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
else
|
||||
pos = buffer->input_buffer;
|
||||
if (!pos)
|
||||
return;
|
||||
buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
}
|
||||
@@ -1489,17 +1520,17 @@ gui_input_move_next_word (struct t_gui_buffer *buffer)
|
||||
|
||||
pos = (char *)utf8_add_offset (buffer->input_buffer,
|
||||
buffer->input_buffer_pos);
|
||||
while (pos[0] && !string_is_word_char_input (pos))
|
||||
while (pos && pos[0] && !string_is_word_char_input (pos))
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
}
|
||||
if (pos[0])
|
||||
if (pos && pos[0])
|
||||
{
|
||||
while (pos[0] && string_is_word_char_input (pos))
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
}
|
||||
if (pos[0])
|
||||
if (pos && pos[0])
|
||||
{
|
||||
buffer->input_buffer_pos =
|
||||
utf8_pos (buffer->input_buffer,
|
||||
@@ -1531,6 +1562,9 @@ gui_input_move_previous_line (struct t_gui_buffer *buffer)
|
||||
buffer->input_buffer_pos);
|
||||
pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
|
||||
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
if (pos != buffer->input_buffer)
|
||||
{
|
||||
beginning_of_line_pos = utf8_pos (buffer->input_buffer,
|
||||
@@ -1540,13 +1574,19 @@ gui_input_move_previous_line (struct t_gui_buffer *buffer)
|
||||
pos = (char *)utf8_prev_char (buffer->input_buffer, pos);
|
||||
pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
|
||||
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
for (i = 0;
|
||||
pos[0] && (pos[0] != '\n') && (i < length_from_beginning);
|
||||
pos && pos[0] && (pos[0] != '\n') && (i < length_from_beginning);
|
||||
i++)
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
}
|
||||
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
|
||||
@@ -1574,22 +1614,27 @@ gui_input_move_next_line (struct t_gui_buffer *buffer)
|
||||
buffer->input_buffer_pos);
|
||||
pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
|
||||
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
beginning_of_line_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
length_from_beginning = buffer->input_buffer_pos - beginning_of_line_pos;
|
||||
|
||||
pos = (char *)utf8_end_of_line (pos);
|
||||
if (pos[0])
|
||||
if (pos && pos[0])
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
|
||||
for (i = 0;
|
||||
pos[0] && (pos[0] != '\n') && (i < length_from_beginning);
|
||||
pos && pos[0] && (pos[0] != '\n') && (i < length_from_beginning);
|
||||
i++)
|
||||
{
|
||||
pos = (char *)utf8_next_char (pos);
|
||||
}
|
||||
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
|
||||
pos - buffer->input_buffer);
|
||||
|
||||
|
||||
+1
-1
@@ -1328,7 +1328,7 @@ gui_key_chunk_seems_valid (const char *chunk)
|
||||
if (!found)
|
||||
chunk = utf8_next_char (chunk);
|
||||
|
||||
if (chunk[0])
|
||||
if (chunk && chunk[0])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user