Alexandre Julliard : server: Store length of console history lines instead of null-terminating them.

Alexandre Julliard julliard at winehq.org
Mon Mar 23 15:47:09 CDT 2020


Module: wine
Branch: master
Commit: ffe6548d6c55f81918e1aa63228b724cbe72e567
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ffe6548d6c55f81918e1aa63228b724cbe72e567

Author: Alexandre Julliard <julliard at 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 at 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;
 }




More information about the wine-cvs mailing list