From ae765430e980ff2a1daafcb8a3d28930c9e162ac Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Tue, 15 May 2018 09:13:00 +0200
Subject: [PATCH] Fixed #4647: nsc_context_free must not access possibly
 uninitialized fields.

---
 libfreerdp/codec/nsc.c      | 47 ++++++++++++++++++++++-----------------------
 libfreerdp/utils/profiler.c |  7 ++++---
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c
index 567b72c2de..b674548d5a 100644
--- a/libfreerdp/codec/nsc.c
+++ b/libfreerdp/codec/nsc.c
@@ -248,13 +248,13 @@ static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
 	return TRUE;
 }
 
-static void nsc_profiler_print(NSC_CONTEXT* context)
+static void nsc_profiler_print(NSC_CONTEXT_PRIV* priv)
 {
 	PROFILER_PRINT_HEADER
-	PROFILER_PRINT(context->priv->prof_nsc_rle_decompress_data)
-	PROFILER_PRINT(context->priv->prof_nsc_decode)
-	PROFILER_PRINT(context->priv->prof_nsc_rle_compress_data)
-	PROFILER_PRINT(context->priv->prof_nsc_encode)
+	PROFILER_PRINT(priv->prof_nsc_rle_decompress_data)
+	PROFILER_PRINT(priv->prof_nsc_decode)
+	PROFILER_PRINT(priv->prof_nsc_rle_compress_data)
+	PROFILER_PRINT(priv->prof_nsc_encode)
 	PROFILER_PRINT_FOOTER
 }
 
@@ -279,7 +279,7 @@ NSC_CONTEXT* nsc_context_new(void)
 	context->priv = (NSC_CONTEXT_PRIV*) calloc(1, sizeof(NSC_CONTEXT_PRIV));
 
 	if (!context->priv)
-		goto error_priv;
+		goto error;
 
 	context->priv->log = WLog_Get("com.freerdp.codec.nsc");
 	WLog_OpenAppender(context->priv->log);
@@ -289,7 +289,7 @@ NSC_CONTEXT* nsc_context_new(void)
 	context->priv->PlanePool = BufferPool_New(TRUE, 0, 16);
 
 	if (!context->priv->PlanePool)
-		goto error_PlanePool;
+		goto error;
 
 	PROFILER_CREATE(context->priv->prof_nsc_rle_decompress_data,
 	                "nsc_rle_decompress_data")
@@ -303,34 +303,33 @@ NSC_CONTEXT* nsc_context_new(void)
 	/* init optimized methods */
 	NSC_INIT_SIMD(context);
 	return context;
-error_PlanePool:
-	free(context->priv);
-error_priv:
-	free(context);
+error:
+	nsc_context_free(context);
 	return NULL;
 }
 
 void nsc_context_free(NSC_CONTEXT* context)
 {
-	int i;
+	size_t i;
 
-	for (i = 0; i < 4; i++)
+	if (!context)
+		return;
+
+	if (context->priv)
 	{
-		if (context->priv->PlaneBuffers[i])
-		{
+		for (i = 0; i < 4; i++)
 			free(context->priv->PlaneBuffers[i]);
-			context->priv->PlaneBuffers[i] = NULL;
-		}
+
+		BufferPool_Free(context->priv->PlanePool);
+		nsc_profiler_print(context->priv);
+		PROFILER_FREE(context->priv->prof_nsc_rle_decompress_data)
+		PROFILER_FREE(context->priv->prof_nsc_decode)
+		PROFILER_FREE(context->priv->prof_nsc_rle_compress_data)
+		PROFILER_FREE(context->priv->prof_nsc_encode)
+		free(context->priv);
 	}
 
 	free(context->BitmapData);
-	BufferPool_Free(context->priv->PlanePool);
-	nsc_profiler_print(context);
-	PROFILER_FREE(context->priv->prof_nsc_rle_decompress_data)
-	PROFILER_FREE(context->priv->prof_nsc_decode)
-	PROFILER_FREE(context->priv->prof_nsc_rle_compress_data)
-	PROFILER_FREE(context->priv->prof_nsc_encode)
-	free(context->priv);
 	free(context);
 }
 
diff --git a/libfreerdp/utils/profiler.c b/libfreerdp/utils/profiler.c
index ce3f6eb8c6..61b7a5298b 100644
--- a/libfreerdp/utils/profiler.c
+++ b/libfreerdp/utils/profiler.c
@@ -51,7 +51,9 @@ PROFILER* profiler_create(char* name)
 
 void profiler_free(PROFILER* profiler)
 {
-	stopwatch_free(profiler->stopwatch);
+	if (profiler)
+		stopwatch_free(profiler->stopwatch);
+
 	free(profiler);
 }
 
@@ -76,9 +78,8 @@ void profiler_print(PROFILER* profiler)
 {
 	double s = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch);
 	double avg = profiler->stopwatch->count == 0 ? 0 : s / profiler->stopwatch->count;
-
 	WLog_INFO(TAG, "%-30s | %10u | %10.4fs | %8.6fs | %6.0f",
-		profiler->name, profiler->stopwatch->count, s, avg, profiler->stopwatch->count / s);
+	          profiler->name, profiler->stopwatch->count, s, avg, profiler->stopwatch->count / s);
 }
 
 void profiler_print_footer(void)

