Module: wine Branch: master Commit: ffe6548d6c55f81918e1aa63228b724cbe72e567 URL: https://source.winehq.org/git/wine.git/?a=commit;h=ffe6548d6c55f81918e1aa632...
Author: Alexandre Julliard julliard@winehq.org Date: Sat Mar 21 11:57:39 2020 +0100
server: Store length of console history lines instead of null-terminating them.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
server/console.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-)
diff --git a/server/console.c b/server/console.c index e05bc9668c..5feb1c2ba7 100644 --- a/server/console.c +++ b/server/console.c @@ -42,6 +42,12 @@ struct screen_buffer; struct console_input_events;
+struct history_line +{ + data_size_t len; + WCHAR text[1]; +}; + struct console_input { struct object obj; /* object header */ @@ -54,7 +60,7 @@ struct console_input struct console_input_events *evt; /* synchronization event with renderer */ WCHAR *title; /* console title */ data_size_t title_len; /* length of console title */ - WCHAR **history; /* lines history */ + struct history_line **history; /* lines history */ int history_size; /* number of entries in history array */ int history_index; /* number of used entries in history array */ int history_mode; /* mode of history (non zero means remove doubled strings */ @@ -342,7 +348,7 @@ static struct object *create_console_input( struct thread* renderer, int fd ) console_input->title = NULL; console_input->title_len = 0; console_input->history_size = 50; - console_input->history = calloc( console_input->history_size, sizeof(WCHAR*) ); + console_input->history = calloc( console_input->history_size, sizeof(*console_input->history) ); console_input->history_index = 0; console_input->history_mode = 0; console_input->edition_mode = 0; @@ -798,15 +804,13 @@ static int set_console_input_info( const struct set_console_input_info_request * if ((req->mask & SET_CONSOLE_INPUT_INFO_HISTORY_SIZE) && console->history_size != req->history_size) { - WCHAR** mem = NULL; - int i; - int delta; + struct history_line **mem = NULL; + int i, delta;
if (req->history_size) { - mem = mem_alloc( req->history_size * sizeof(WCHAR*) ); - if (!mem) goto error; - memset( mem, 0, req->history_size * sizeof(WCHAR*) ); + if (!(mem = mem_alloc( req->history_size * sizeof(*mem) ))) goto error; + memset( mem, 0, req->history_size * sizeof(*mem) ); }
delta = (console->history_index > req->history_size) ? @@ -1081,31 +1085,26 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, /* appends a new line to history (history is a fixed size array) */ static void console_input_append_hist( struct console_input* console, const WCHAR* buf, data_size_t len ) { - WCHAR* ptr = mem_alloc( (len + 1) * sizeof(WCHAR) ); - - if (!ptr) - return; + struct history_line *ptr;
if (!console || !console->history_size) { set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ - free( ptr ); return; }
- memcpy( ptr, buf, len * sizeof(WCHAR) ); - ptr[len] = 0; - + len = (len / sizeof(WCHAR)) * sizeof(WCHAR); if (console->history_mode && console->history_index && - !strcmpW( console->history[console->history_index - 1], ptr )) + console->history[console->history_index - 1]->len == len && + !memcmp( console->history[console->history_index - 1]->text, buf, len )) { - /* ok, mode ask us to not use twice the same string... - * so just free mem and returns - */ + /* don't duplicate entry */ set_error( STATUS_ALIAS_EXISTS ); - free(ptr); return; } + if (!(ptr = mem_alloc( offsetof( struct history_line, text[len / sizeof(WCHAR)] )))) return; + ptr->len = len; + memcpy( ptr->text, buf, len );
if (console->history_index < console->history_size) { @@ -1115,7 +1114,7 @@ static void console_input_append_hist( struct console_input* console, const WCHA { free( console->history[0]) ; memmove( &console->history[0], &console->history[1], - (console->history_size - 1) * sizeof(WCHAR*) ); + (console->history_size - 1) * sizeof(*console->history) ); console->history[console->history_size - 1] = ptr; } } @@ -1128,8 +1127,8 @@ static data_size_t console_input_get_hist( struct console_input *console, int in if (index >= console->history_index) set_error( STATUS_INVALID_PARAMETER ); else { - ret = strlenW( console->history[index] ) * sizeof(WCHAR); - set_reply_data( console->history[index], min( ret, get_reply_max_size() )); + ret = console->history[index]->len; + set_reply_data( console->history[index]->text, min( ret, get_reply_max_size() )); } return ret; }