From 3f2342a3d397905db7c2eb4bd77244a303f88bff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Damian=20B=C3=BCchel?= <damian.buechel@let.ethz.ch>
Date: Wed, 17 Aug 2022 14:40:41 +0200
Subject: [PATCH] SEBWIN-592, #421: Fixed crash caused by non-ASCII characters
 (e.g. Hebrew) in client log file path.

---
 SafeExamBrowser.Client/CompositionRoot.cs     | 30 +++++++++++--------
 .../Operations/ClientOperation.cs             | 13 ++++----
 2 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs
index e5c63dda..d42391ad 100644
--- a/SafeExamBrowser.Client/CompositionRoot.cs
+++ b/SafeExamBrowser.Client/CompositionRoot.cs
@@ -9,6 +9,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Text;
 using SafeExamBrowser.Applications;
 using SafeExamBrowser.Browser;
 using SafeExamBrowser.Client.Communication;
@@ -175,27 +176,32 @@ namespace SafeExamBrowser.Client
 		{
 			var args = Environment.GetCommandLineArgs();
 			var hasFive = args?.Length >= 5;
+			var valid = false;
 
 			if (hasFive)
 			{
-				var hasLogfilePath = Uri.TryCreate(args[1], UriKind.Absolute, out Uri filePath) && filePath.IsFile;
-				var hasLogLevel = Enum.TryParse(args[2], out LogLevel level);
-				var hasHostUri = Uri.TryCreate(args[3], UriKind.Absolute, out Uri hostUri) && hostUri.IsWellFormedOriginalString();
-				var hasAuthenticationToken = Guid.TryParse(args[4], out Guid token);
+				var logFilePath = Encoding.UTF8.GetString(Convert.FromBase64String(args[1]));
+				var hasLogFilePath = Uri.TryCreate(logFilePath, UriKind.Absolute, out var filePath) && filePath.IsFile;
+				var hasLogLevel = Enum.TryParse(args[2], out LogLevel logLevel);
+				var hasHostUri = Uri.TryCreate(args[3], UriKind.Absolute, out var runtimeHostUri) && runtimeHostUri.IsWellFormedOriginalString();
+				var hasAuthenticationToken = Guid.TryParse(args[4], out var authenticationToken);
 
-				if (hasLogfilePath && hasLogLevel && hasHostUri && hasAuthenticationToken)
+				if (hasLogFilePath && hasLogLevel && hasHostUri && hasAuthenticationToken)
 				{
-					logFilePath = args[1];
-					logLevel = level;
-					runtimeHostUri = args[3];
-					authenticationToken = token;
-					uiMode = args.Length == 6 && Enum.TryParse(args[5], out uiMode) ? uiMode : UserInterfaceMode.Desktop;
+					this.authenticationToken = authenticationToken;
+					this.logFilePath = logFilePath;
+					this.logLevel = logLevel;
+					this.runtimeHostUri = args[3];
+					this.uiMode = args.Length == 6 && Enum.TryParse(args[5], out uiMode) ? uiMode : UserInterfaceMode.Desktop;
 
-					return;
+					valid = true;
 				}
 			}
 
-			throw new ArgumentException("Invalid arguments! Required: SafeExamBrowser.Client.exe <logfile path> <log level> <host URI> <token>");
+			if (!valid)
+			{
+				throw new ArgumentException("Invalid arguments! Required: SafeExamBrowser.Client.exe <logfile path> <log level> <host URI> <token>");
+			}
 		}
 
 		private void InitializeLogging()
diff --git a/SafeExamBrowser.Runtime/Operations/ClientOperation.cs b/SafeExamBrowser.Runtime/Operations/ClientOperation.cs
index 167535e5..fb94a474 100644
--- a/SafeExamBrowser.Runtime/Operations/ClientOperation.cs
+++ b/SafeExamBrowser.Runtime/Operations/ClientOperation.cs
@@ -7,6 +7,7 @@
  */
 
 using System;
+using System.Text;
 using System.Threading;
 using SafeExamBrowser.Communication.Contracts;
 using SafeExamBrowser.Communication.Contracts.Events;
@@ -23,11 +24,11 @@ namespace SafeExamBrowser.Runtime.Operations
 {
 	internal class ClientOperation : SessionOperation
 	{
-		private int timeout_ms;
-		private ILogger logger;
-		private IProcessFactory processFactory;
-		private IProxyFactory proxyFactory;
-		private IRuntimeHost runtimeHost;
+		private readonly ILogger logger;
+		private readonly IProcessFactory processFactory;
+		private readonly IProxyFactory proxyFactory;
+		private readonly IRuntimeHost runtimeHost;
+		private readonly int timeout_ms;
 
 		private IProcess ClientProcess
 		{
@@ -99,7 +100,7 @@ namespace SafeExamBrowser.Runtime.Operations
 		{
 			var authenticationToken = Context.Next.ClientAuthenticationToken.ToString("D");
 			var executablePath = Context.Next.AppConfig.ClientExecutablePath;
-			var logFilePath = $"{'"' + Context.Next.AppConfig.ClientLogFilePath + '"'}";
+			var logFilePath = $"{'"' + Convert.ToBase64String(Encoding.UTF8.GetBytes(Context.Next.AppConfig.ClientLogFilePath)) + '"'}";
 			var logLevel = Context.Next.Settings.LogLevel.ToString();
 			var runtimeHostUri = Context.Next.AppConfig.RuntimeAddress;
 			var uiMode = Context.Next.Settings.UserInterfaceMode.ToString();