From 8c6a26fc23ba66e5bea05796711e4c67f9a76ed7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Janis=20Daniel=20Da=CC=88hne?=
 <janis.daehne2@student.uni-halle.de>
Date: Mon, 29 Jul 2019 18:38:15 +0200
Subject: [PATCH] - removed max lines to read/write in favor of max characters
 limit

---
 api.php                      | 74 +++++++++++++++++++-----------------
 bootstrap.php                |  3 --
 constants.php                | 35 +++++++++++++++--
 do_blackBoxTest_func.php     | 20 +++++-----
 do_compareFilesTest_func.php | 22 +++++------
 do_compileTest_func.php      |  9 ++++-
 do_regexTest_func.php        | 12 +++++-
 helpers.php                  |  5 ++-
 protocolHeaderPartParser.php | 13 ++++++-
 readme.md                    | 40 ++++++++-----------
 stats/private.php            |  3 --
 stats/public.php             |  3 --
 12 files changed, 140 insertions(+), 99 deletions(-)

diff --git a/api.php b/api.php
index 33c3c05..abec091 100644
--- a/api.php
+++ b/api.php
@@ -182,8 +182,16 @@ if (!isset($body[$s_arg_pLang])) {
     exit(1);
 }
 
+if (!isset($body[$s_arg_characterLimitProtocol])) {
+    endTransaction($conn, $config, $transactionKey, $rootDirName);
+    output($status_code_ArgumentInvalidOrMissing, "argument '" . $s_arg_characterLimitProtocol . "' missing");
+    exit(1);
+}
+
 $arg_pLang = $body[$s_arg_pLang];
 
+$arg_characterLimitProtocol = $body[$s_arg_characterLimitProtocol];
+
 
 # check if the p lang is supported...
 # ...get the script to execute from the db like domjudge
@@ -288,7 +296,8 @@ foreach ($testCases as $test) {
             FALSE, FALSE, NULL,
             NULL, NULL, NULL,
             100, '',
-            NULL, NULL
+            NULL, NULL,
+            false, $arg_characterLimitProtocol
         );
 
         array_push($testResults, $result);
@@ -305,7 +314,8 @@ foreach ($testCases as $test) {
             FALSE, FALSE, NULL,
             NULL, NULL, NULL,
             100, '',
-            NULL, NULL
+            NULL, NULL,
+            false, $arg_characterLimitProtocol
         );
         array_push($testResults, $result);
         continue;
@@ -319,7 +329,8 @@ foreach ($testCases as $test) {
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
                 100, '',
-                NULL, NULL
+                NULL, NULL,
+                false, $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
             continue;
@@ -337,7 +348,8 @@ foreach ($testCases as $test) {
                     FALSE, FALSE, NULL,
                     NULL, NULL, NULL,
                     100, '',
-                    NULL, NULL
+                    NULL, NULL,
+                    false, $arg_characterLimitProtocol
                 );
                 array_push($testResults, $result);
                 continue;
@@ -353,7 +365,8 @@ foreach ($testCases as $test) {
 
             try {
                 $_result = do_compile($arg_mainFileNameWithExtension, $fullWorkingDirPath, $min_compileTimeout,
-                    $compileCmd, $sourceFileExtensions, $requestDistinctionString, $showTestRunnerDebugOutput, $compilerOptions);
+                    $compileCmd, $sourceFileExtensions, $requestDistinctionString, $showTestRunnerDebugOutput, $compilerOptions,
+                    $arg_characterLimitProtocol);
             } catch (Exception $e) {
                 //critical error, abort execution (all other tests are likely to fail)
                 output($status_code_InternalServerError, "error executing regex test: " . $e->getMessage());
@@ -364,7 +377,8 @@ foreach ($testCases as $test) {
                 $_result[$s_return_val] === 0, $_result[$s_return_val] !== 50 && $_result[$s_return_val] !== 7, $_result[$s_user_program_exit_code],
                 $_result[$s_timeForCompiling], $_result[$s_timeForUserProgram], $_result[$s_runnerVersion],
                 $_result[$s_return_val], formatOutput($_result[$s_output]),
-                $_result[$s_compileTimeoutInMsUsed], NULL
+                $_result[$s_compileTimeoutInMsUsed], NULL,
+                $_result[$s_characterLimitExceeded], $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
 
@@ -384,7 +398,7 @@ foreach ($testCases as $test) {
         try {
             //no need to write any files ... can all be handled in memory
             //$_result = do_regexTest_json($arg_allFiles, $testContent);
-            $_result = do_regexTest_format2($arg_allFiles, $testContent, $showTestRunnerDebugOutput);
+            $_result = do_regexTest_format2($arg_allFiles, $testContent, $showTestRunnerDebugOutput, $arg_characterLimitProtocol);
         } catch (Exception $e) {
             //critical error, abort execution (all other tests are likely to fail)
             output($status_code_InternalServerError, "error executing regex test: " . $e->getMessage());
@@ -394,8 +408,9 @@ foreach ($testCases as $test) {
         $result = create_test_result($status_code_Ok, '', $testId,
             $_result[$s_return_val] === 0, $_result[$s_return_val] !== 50 && $_result[$s_return_val] !== 7, NULL,
             NULL, NULL, NULL,
-            $_result[$s_return_val], formatOutput($_result[$s_output]),
-            NULL, NULL
+            $_result[$s_return_val], $_result[$s_output],
+            NULL, NULL,
+            $_result[$s_characterLimitExceeded], $arg_characterLimitProtocol
         );
         array_push($testResults, $result);
 
@@ -411,7 +426,8 @@ foreach ($testCases as $test) {
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
                 100, '',
-                NULL, NULL
+                NULL, NULL,
+                false, $arg_characterLimitProtocol
 
             );
             array_push($testResults, $result);
@@ -424,7 +440,8 @@ foreach ($testCases as $test) {
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
                 100, '',
-                NULL, NULL
+                NULL, NULL,
+                false, $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
             continue;
@@ -441,7 +458,8 @@ foreach ($testCases as $test) {
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
                 100, '',
-                NULL, NULL
+                NULL, NULL,
+                false, $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
             continue;
@@ -456,7 +474,8 @@ foreach ($testCases as $test) {
             $result = create_test_result($status_code_ArgumentInvalidOrMissing, "argument '" . $s_test_diskSpaceLimitInKb . "' missing", $testId,
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
-                100, '', $versionString
+                100, '', $versionString,
+                false, $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
             continue;
@@ -471,7 +490,8 @@ foreach ($testCases as $test) {
                 FALSE, FALSE, NULL,
                 NULL, NULL, NULL,
                 100, '',
-                NULL, NULL
+                NULL, NULL,
+                false, $arg_characterLimitProtocol
             );
             array_push($testResults, $result);
             continue;
@@ -503,21 +523,6 @@ foreach ($testCases as $test) {
             $min_diskSpaceLimit = min($arg_DiskSpaceLimit, $hardDiskSpaceLimitInKb);
         }
 
-        $maxLinesToRead = -1;
-        if (isset($config['maxLinesToRead'])) {
-            $maxLinesToRead = $config['maxLinesToRead'];
-        }
-
-        $maxErrLinesToRead = -1;
-        if (isset($config['maxErrLinesToRead'])) {
-            $maxErrLinesToRead = $config['maxErrLinesToRead'];
-        }
-
-        $maxLinesToWrite = -1;
-        if (isset($config['maxLinesToWrite'])) {
-            $maxLinesToWrite = $config['maxLinesToWrite'];
-        }
-
 
         # was just a test...
         #output("t" . $min_timeout . " m" . $min_memoryLimit . " d" . $min_diskSpaceLimit . " dd: " . $arg_DiskSpaceLimit);
@@ -555,10 +560,10 @@ foreach ($testCases as $test) {
                     $_result = do_compareFilesTest($arg_mainFileNameWithExtension, $test, $fullWorkingDirPath,
                         $min_timeout, $min_compileTimeout, $min_memoryLimit, $min_diskSpaceLimit,
                         $compileCmd, $execCmd, $sourceFileExtensions, $needCompilation,
-                        $maxLinesToRead, $maxErrLinesToRead, $maxLinesToWrite,
                         $requestDistinctionString,
                         $showTestRunnerDebugOutput,
-                        $compilerOptions
+                        $compilerOptions,
+                        $arg_characterLimitProtocol
                     );
                 } catch (Exception $e) {
                     //critical error, abort execution (all other tests are likely to fail)
@@ -572,11 +577,11 @@ foreach ($testCases as $test) {
                     $_result = do_blackBoxTest($arg_mainFileNameWithExtension, $test, $fullWorkingDirPath,
                         $min_timeout, $min_compileTimeout, $min_memoryLimit, $min_diskSpaceLimit,
                         $compileCmd, $execCmd, $sourceFileExtensions, $needCompilation,
-                        $maxLinesToRead, $maxErrLinesToRead, $maxLinesToWrite,
                         ($arg_command === $s_command_justRunTest),
                         $requestDistinctionString,
                         $showTestRunnerDebugOutput,
-                        $compilerOptions
+                        $compilerOptions,
+                        $arg_characterLimitProtocol
                     );
                 } catch (Exception $e) {
                     //critical error, abort execution (all other tests are likely to fail)
@@ -592,7 +597,8 @@ foreach ($testCases as $test) {
             $_result[$s_return_val] === 0, $_result[$s_return_val] !== 50 && $_result[$s_return_val] !== 7, $_result[$s_user_program_exit_code],
             $_result[$s_timeForCompiling], $_result[$s_timeForUserProgram], $_result[$s_runnerVersion],
             $_result[$s_return_val], formatOutput($_result[$s_output]),
-            $_result[$s_compileTimeoutInMsUsed], $_result[$s_timeoutInMsUsed]
+            $_result[$s_compileTimeoutInMsUsed], $_result[$s_timeoutInMsUsed],
+            $_result[$s_characterLimitExceeded], $arg_characterLimitProtocol
         );
 
         if ($needCompilation) {
diff --git a/bootstrap.php b/bootstrap.php
index 17f9824..7b91ffd 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -68,10 +68,7 @@ $config[$s_arg_hardDiskSpaceLimitInKb] = $row[$s_arg_hardDiskSpaceLimitInKb];
 $config['maxParallelTests'] = $row['maxParallelTests'];
 $config['maxNumberOfTestsWithOneRequest'] = $row['maxNumberOfTestsWithOneRequest'];
 $config['runner'] = $row['runner'];
-$config['maxLinesToRead'] = $row['maxLinesToRead'];
 
-$config['maxErrLinesToRead'] = $row['maxErrLinesToRead'];
-$config['maxLinesToWrite'] = $row['maxLinesToWrite'];
 $config['showTestRunnerDebugOutput'] = $row['showTestRunnerDebugOutput'] === '1';
 $config['environmentVars'] = $row['environmentVars'];
 
diff --git a/constants.php b/constants.php
index 72cba2b..bb72c60 100644
--- a/constants.php
+++ b/constants.php
@@ -3,7 +3,7 @@
 # variables
 
 //use this to know which version we published
-$versionString = '2.3.0';
+$versionString = '2.4.0';
 $rootDirNameToUseString = 'work';
 
 $isDebug = false; //logs debug to STDOUT
@@ -59,6 +59,7 @@ $availableRegexConnectors = [$regexAndConnector, $regexOrConnector];
 $regexNegatePrefix = '!';
 $regexMathAllFilesAttribute = '*';
 $responseNewLineString = '\r\n'; //to match interface
+$runnerNewLineString = "\\r\\n"; //starting with runner version 2.4
 
 
 # known error codes
@@ -113,6 +114,8 @@ $s_arg_mainFileNameWithExtension = 'mainFileNameWithExtension'; # the main file
 #NO USED $s_arg_dirName = 'dirName'; # the dir name to use
 $s_arg_allFiles = 'allFiles'; # all files to use
 
+$s_arg_characterLimitProtocol = 'characterLimitProtocol'; # the character limit for the test result protocol
+
 # a number to help the this server to separate two requests in case they arrive at the same time (and micro time would return the same value)
 $s_requestDistinctionNumber = 'requestDistinctionString';
 # end variables
@@ -140,8 +143,10 @@ $s_compileTimeoutInMsUsed = 'compileTimeoutInMsUsed';
 $s_timeForCompiling = 'timeForCompiling';
 $s_timeForUserProgram = 'timeForUserProgram';
 $s_output_without_header_part = 'stripedOutput';
+$s_characterLimitExceeded = 'characterLimitExceeded';
+$s_characterLimitUsed = 'characterLimitUsed';
 
-$s_header_part_separator = "---\n";
+$s_header_part_separator = "---\\r\\n";
 
 /**
  * outputs a message via echo (if debug is enabled outputs the message to stdout)
@@ -197,11 +202,31 @@ function warn($message)
 
 }
 
+/**
+ * creates a test result object
+ * @param $testServerCode
+ * @param $testServerMessage
+ * @param $testId
+ * @param $passed
+ * @param $hasCompiled
+ * @param $programExitCode
+ * @param $timeForCompiling
+ * @param $timeForUserProgram
+ * @param $runnerVersion
+ * @param $testResultCode
+ * @param $protocol
+ * @param $compileTimeoutInMsUsed
+ * @param $timeoutInMsUsed
+ * @param $characterLimitExceeded
+ * @param $characterLimitUsed
+ * @return array
+ */
 function create_test_result($testServerCode, $testServerMessage, $testId,
                             $passed, $hasCompiled, $programExitCode,
                             $timeForCompiling, $timeForUserProgram, $runnerVersion,
                             $testResultCode, $protocol,
-                            $compileTimeoutInMsUsed, $timeoutInMsUsed
+                            $compileTimeoutInMsUsed, $timeoutInMsUsed,
+                            $characterLimitExceeded, $characterLimitUsed
 
 )
 {
@@ -220,6 +245,8 @@ function create_test_result($testServerCode, $testServerMessage, $testId,
     global $s_timeoutInMsUsed;
     global $s_compileTimeoutInMsUsed;
     global $versionString;
+    global $s_characterLimitExceeded;
+    global $s_characterLimitUsed;
 
 
     return array(
@@ -237,6 +264,8 @@ function create_test_result($testServerCode, $testServerMessage, $testId,
         $s_output_test_server_version => $versionString,
         $s_compileTimeoutInMsUsed => $compileTimeoutInMsUsed,
         $s_timeoutInMsUsed => $timeoutInMsUsed,
+        $s_characterLimitExceeded => $characterLimitExceeded,
+        $s_characterLimitUsed => $characterLimitUsed,
     );
 
 }
\ No newline at end of file
diff --git a/do_blackBoxTest_func.php b/do_blackBoxTest_func.php
index 6e04891..abf6f2f 100644
--- a/do_blackBoxTest_func.php
+++ b/do_blackBoxTest_func.php
@@ -15,13 +15,11 @@ require_once __DIR__ . '/protocolHeaderPartParser.php';
  * @param string $execCmd the command to execute to run the test
  * @param $sourceFileExtensions array the list with the file extensions from the source files for the p language
  * @param $needCompilation bool true: should compile sources, false: not (this assumes the sources are already compiled)
- * @param $maxLinesToRead int the max lines to read from the user program (passed to the runner)
- * @param $maxErrLinesToRead int the max lines to read from the user program (from stderr) (passed to the runner)
- * @param $maxLinesToWrite int the max lines to write the user program (passed to the runner)
  * @param $justRun true: just run test, false: normal back box test
  * @param $uniqueSessionId string the unique session id for the test runner to handle sandbox file system management
  * @param $showTestRunnerDebugOutput 1: show internal debug output from the test runner (included in the test response)
  * @param $compilerOptions string the options for the compiler
+ * @param $arg_characterLimitProtocol
  * @return array the result
  * @internal param array $allFiles all files to copy in teh dir to use
  * Format: array[int] => {fileName: string, fileContent: string}
@@ -29,11 +27,11 @@ require_once __DIR__ . '/protocolHeaderPartParser.php';
 function do_blackBoxTest($mainFileNameWithExtension, $test, $fullWorkingDirPath,
                          $timeout, $compileTimeout, $memoryLimit, $diskSpaceLimit,
                          $compileCmd, $execCmd, $sourceFileExtensions, $needCompilation,
-                         $maxLinesToRead, $maxErrLinesToRead, $maxLinesToWrite,
                          $justRun,
                          $uniqueSessionId,
                          $showTestRunnerDebugOutput,
-                         $compilerOptions
+                         $compilerOptions,
+                         $arg_characterLimitProtocol
 
 
 )
@@ -54,6 +52,7 @@ function do_blackBoxTest($mainFileNameWithExtension, $test, $fullWorkingDirPath,
     global $s_timeoutInMsUsed;
     global $s_compileTimeoutInMsUsed;
     global $s_output_without_header_part;
+    global $s_characterLimitExceeded;
 
 
     $command_to_execute_string = $s_command_blackBoxTest;
@@ -98,12 +97,10 @@ function do_blackBoxTest($mainFileNameWithExtension, $test, $fullWorkingDirPath,
         . ' ' . escapeshellarg($diskSpaceLimit)                                   # arg[8] the disk limit
         . ' ' . escapeshellarg(implode(',', $sourceFileExtensions))         # arg[9] the source file extensions
         . ' ' . escapeshellarg($needCompilation ? 'true' : 'false')          # arg[10] true: compile program new, false: not
-        . ' ' . escapeshellarg($maxLinesToRead)                                   # arg[11] max lines to read from the user program (inclusive)
-        . ' ' . escapeshellarg($maxErrLinesToRead)                                # arg[12] max lines to read from the user program stderr (inclusive)
-        . ' ' . escapeshellarg($maxLinesToWrite)                                  # arg[13]  max lines to write to the user program (inclusive)
-        . ' ' . escapeshellarg($uniqueSessionId)                                  # arg[14] a unique session id
-        . ' ' . escapeshellarg(($showTestRunnerDebugOutput === TRUE ? 1 : 0))     # arg[15] showTestRunnerDebugOutput
-        . ' ' . escapeshellarg($compilerOptions)                                  # arg[8] options for the compiler
+        . ' ' . escapeshellarg($uniqueSessionId)                                  # arg[11] a unique session id
+        . ' ' . escapeshellarg(($showTestRunnerDebugOutput === TRUE ? 1 : 0))     # arg[12] showTestRunnerDebugOutput
+        . ' ' . escapeshellarg($compilerOptions)                                  # arg[13] options for the compiler
+        . ' ' . escapeshellarg($arg_characterLimitProtocol)                       # arg[14]  character limit for the test protocol, output cut after the limit
 
     ;
 
@@ -190,5 +187,6 @@ function do_blackBoxTest($mainFileNameWithExtension, $test, $fullWorkingDirPath,
         $s_timeForUserProgram => $headerPart[$s_timeForUserProgram],
         $s_timeoutInMsUsed => $timeout,
         $s_compileTimeoutInMsUsed => $compileTimeout,
+        $s_characterLimitExceeded => $headerPart[$s_characterLimitExceeded]
     );
 }
diff --git a/do_compareFilesTest_func.php b/do_compareFilesTest_func.php
index 88e4346..f43c3f4 100644
--- a/do_compareFilesTest_func.php
+++ b/do_compareFilesTest_func.php
@@ -15,12 +15,10 @@ require_once __DIR__ . '/protocolHeaderPartParser.php';
  * @param string $execCmd the command to execute to run the test
  * @param $sourceFileExtensions array the list with the file extensions from the source files for the p language
  * @param $needCompilation bool true: should compile sources, false: not (this assumes the sources are already compiled)
- * @param $maxLinesToRead int the max lines to read from the user program (passed to the runner)
- * @param $maxErrLinesToRead int the max lines to read from the user program (from stderr) (passed to the runner)
- * @param $maxLinesToWrite int the max lines to write the user program (passed to the runner)
  * @param $uniqueSessionId string the unique session id for the test runner to handle sandbox file system management
  * @param $showTestRunnerDebugOutput 1: show internal debug output from the test runner (included in the test response)
  * @param $compilerOptions string the options for the compiler
+ * @param $arg_characterLimitProtocol
  * @return array the result
  * @internal param array $allFiles all files to copy in teh dir to use
  * Format: array[int] => {fileName: string, fileContent: string}
@@ -28,10 +26,10 @@ require_once __DIR__ . '/protocolHeaderPartParser.php';
 function do_compareFilesTest($mainFileNameWithExtension, $test, $fullWorkingDirPath,
                              $timeout, $compileTimeout, $memoryLimit, $diskSpaceLimit,
                              $compileCmd, $execCmd, $sourceFileExtensions, $needCompilation,
-                             $maxLinesToRead, $maxErrLinesToRead, $maxLinesToWrite,
                              $uniqueSessionId,
                              $showTestRunnerDebugOutput,
-                             $compilerOptions
+                             $compilerOptions,
+                             $arg_characterLimitProtocol
 
 
 )
@@ -53,6 +51,7 @@ function do_compareFilesTest($mainFileNameWithExtension, $test, $fullWorkingDirP
     global $s_timeoutInMsUsed;
     global $s_compileTimeoutInMsUsed;
     global $s_output_without_header_part;
+    global $s_characterLimitExceeded;
 
     $command_to_execute_string = $s_command_compareFilesTest;
 
@@ -99,13 +98,11 @@ function do_compareFilesTest($mainFileNameWithExtension, $test, $fullWorkingDirP
         . ' ' . escapeshellarg($diskSpaceLimit)                                  # arg[8] the disk limit
         . ' ' . escapeshellarg(implode(',', $sourceFileExtensions))         # arg[9] the source file extensions
         . ' ' . escapeshellarg($needCompilation ? 'true' : 'false')          # arg[10] true: compile program new, false: not
-        . ' ' . escapeshellarg($maxLinesToRead)                                   # arg[11] max lines to read from the user program (inclusive)
-        . ' ' . escapeshellarg($maxErrLinesToRead)                                # arg[12] max lines to read from the user program stderr (inclusive)
-        . ' ' . escapeshellarg($maxLinesToWrite)                                  # arg[13]  max lines to write to the user program (inclusive)
-        . ' ' . escapeshellarg($uniqueSessionId)                                  # arg[14] a unique session id
-        . ' ' . escapeshellarg($showTestRunnerDebugOutput === TRUE ? 1 : 0)  # arg[15] showTestRunnerDebugOutput
-        . ' ' . escapeshellarg($fileHashInfo)                                     # arg[16] file:hash list
-        . ' ' . escapeshellarg($compilerOptions)                                  # arg[8] options for the compiler
+        . ' ' . escapeshellarg($uniqueSessionId)                                  # arg[11] a unique session id
+        . ' ' . escapeshellarg($showTestRunnerDebugOutput === TRUE ? 1 : 0)  # arg[12] showTestRunnerDebugOutput
+        . ' ' . escapeshellarg($compilerOptions)                                  # arg[13] options for the compiler
+        . ' ' . escapeshellarg($arg_characterLimitProtocol)                       # arg[14]  character limit for the test protocol, output cut after the limit
+        . ' ' . escapeshellarg($fileHashInfo)                                     # arg[15] file:hash list
 
     ;
 
@@ -192,5 +189,6 @@ function do_compareFilesTest($mainFileNameWithExtension, $test, $fullWorkingDirP
         $s_timeForUserProgram => $headerPart[$s_timeForUserProgram],
         $s_timeoutInMsUsed => $timeout,
         $s_compileTimeoutInMsUsed => $compileTimeout,
+        $s_characterLimitExceeded => $headerPart[$s_characterLimitExceeded]
     );
 }
diff --git a/do_compileTest_func.php b/do_compileTest_func.php
index 513c160..3076e15 100644
--- a/do_compileTest_func.php
+++ b/do_compileTest_func.php
@@ -13,7 +13,8 @@ require_once __DIR__ . '/protocolHeaderPartParser.php';
  * @param $uniqueSessionId string the unique session id for the test runner to handle sandbox file system management
  * @param $showTestRunnerDebugOutput true: show internal debug output from the test runner (included in the test response)
  * @param $compilerOptions string the options for the compiler
- * @return array
+ * @param $characterLimitProtocol int the max characters for the test result protocol
+ * @return array Format: return_var: process exit value, output the output of the process
  * Format: return_var: process exit value, output the output of the process
  * @internal param array $allFiles all files to copy in teh dir to use
  * Format: array[int] => {fileName: string, fileContent: string}
@@ -23,7 +24,8 @@ function do_compile($mainFileNameWithExtension, $fullWorkingDirPath,
                     $compileCmd, $sourceFileExtensions,
                     $uniqueSessionId,
                     $showTestRunnerDebugOutput,
-                    $compilerOptions
+                    $compilerOptions,
+                    $characterLimitProtocol
 )
 {
 
@@ -39,6 +41,7 @@ function do_compile($mainFileNameWithExtension, $fullWorkingDirPath,
     global $s_timeoutInMsUsed;
     global $s_compileTimeoutInMsUsed;
     global $s_output_without_header_part;
+    global $s_characterLimitExceeded;
 
     $command_to_execute_string = $s_command_compile;
 
@@ -55,6 +58,7 @@ function do_compile($mainFileNameWithExtension, $fullWorkingDirPath,
         . ' ' . escapeshellarg($uniqueSessionId)                                    # arg[6] a unique session id
         . ' ' . escapeshellarg($showTestRunnerDebugOutput === TRUE ? 1 : 0)    # arg[7] showTestRunnerDebugOutput
         . ' ' . escapeshellarg($compilerOptions)                                    # arg[8] options for the compiler
+        . ' ' . escapeshellarg($characterLimitProtocol)                             # arg[9] character limit for the test protocol, output cut after the limit
     ;
 
 
@@ -102,5 +106,6 @@ function do_compile($mainFileNameWithExtension, $fullWorkingDirPath,
         $s_timeForUserProgram => $headerPart[$s_timeForUserProgram],
         $s_timeoutInMsUsed => $headerPart[$s_timeoutInMsUsed],
         $s_compileTimeoutInMsUsed => $compileTimeout,
+        $s_characterLimitExceeded => $headerPart[$s_characterLimitExceeded],
     );
 }
diff --git a/do_regexTest_func.php b/do_regexTest_func.php
index 828ddb4..c5cebca 100644
--- a/do_regexTest_func.php
+++ b/do_regexTest_func.php
@@ -210,9 +210,10 @@ function do_regexTest_json_DEPRECATED($allFiles, $testContent, $showTestRunnerDe
  * Format: array[int] => {fileName: string, fileContent: string}
  * @param $testContent string the test content
  * @param $showTestRunnerDebugOutput true show internal debug output from the test runner (included in the test response)
+ * @param $characterLimitProtocol
  * @return array
  */
-function do_regexTest_format2($allFiles, $testContent, $showTestRunnerDebugOutput)
+function do_regexTest_format2($allFiles, $testContent, $showTestRunnerDebugOutput, $characterLimitProtocol)
 {
 
     global $availableRegexModes;
@@ -230,6 +231,7 @@ function do_regexTest_format2($allFiles, $testContent, $showTestRunnerDebugOutpu
     global $s_fileName;
     global $s_fileContent;
     global $config;
+    global $s_characterLimitExceeded;
 
     # removes leading and trailing whitespaces ??
     $unformattedTestContent = $testContent; //trim(preg_replace('/\s\s+/', ' ', $testContent));
@@ -452,9 +454,15 @@ function do_regexTest_format2($allFiles, $testContent, $showTestRunnerDebugOutpu
 
     handleOutputLabel:
 
+    $output_string = formatOutput($output);
+
+    $characterLimitExceeded = strlen($output_string) > $characterLimitProtocol;
+
+
     return array(
         $s_return_val => $return_var,
-        $s_output => $output
+        $s_output => $output_string,
+        $s_characterLimitExceeded => $characterLimitExceeded
     );
 
     #handleExecOutput($output, $return_var, $config, $conn, $rootDirName, $transactionKey);
diff --git a/helpers.php b/helpers.php
index 2c2ad5d..db5b973 100644
--- a/helpers.php
+++ b/helpers.php
@@ -22,7 +22,10 @@ function formatOutput($output) {
         debug('output: ' . $formattedOutput);
     } else {
         //should be just 1 line string
-        $formattedOutput = str_replace("\n", $responseNewLineString, $formattedOutput);
+//        $formattedOutput = str_replace("\n", $responseNewLineString, $formattedOutput);
+
+        //with runner version 2.4 the runner uses \r\n already
+        $formattedOutput = $output;
         debug('output: ' . $formattedOutput);
     }
 
diff --git a/protocolHeaderPartParser.php b/protocolHeaderPartParser.php
index 008c4e7..1ff7dc3 100644
--- a/protocolHeaderPartParser.php
+++ b/protocolHeaderPartParser.php
@@ -9,6 +9,8 @@ function parseHeaderPart($output)
     global $s_timeForCompiling;
     global $s_timeForUserProgram;
     global $s_output_without_header_part;
+    global $s_characterLimitExceeded;
+    global $runnerNewLineString;
 
 
     //if we have no header tuples we might have only so ---\n
@@ -21,9 +23,10 @@ function parseHeaderPart($output)
     $runnerVersion = NULL;
     $timeForCompiling = NULL;
     $timeForUserProgram = NULL;
+    $characterLimitExceeded = FALSE;
 
 
-    $headerPartLines = explode("\n", $headerPartText);
+    $headerPartLines = explode($runnerNewLineString, $headerPartText);
 
     //empty lines will be ignored because no case matches
 
@@ -57,6 +60,13 @@ function parseHeaderPart($output)
 
             $timeForUserProgram = intval($val, 10);
 
+        } else if (strpos($line, $s_characterLimitExceeded) === 0) {
+
+            $val = getTuple($line);
+            if ($val === null) continue;
+
+            $characterLimitExceeded = strtolower($val) === 'true';
+
         }
     }
 
@@ -67,6 +77,7 @@ function parseHeaderPart($output)
         $s_timeForCompiling => $timeForCompiling,
         $s_timeForUserProgram => $timeForUserProgram,
         $s_output_without_header_part => $stripedOutput,
+        $s_characterLimitExceeded => $characterLimitExceeded
     );
 }
 
diff --git a/readme.md b/readme.md
index dd02818..b5fb0d7 100644
--- a/readme.md
+++ b/readme.md
@@ -518,7 +518,7 @@ Depending on the method the Runner will receive different command line arguments
 
 arg[0] = test type method (string) = compile | executeBlackBox | regex | justrun
 
-## Black Box Test
+## Black Box Test / Just run Test
 method name: **blackBoxTest**
 
 arg[1] = the absolute directory path containing all files (including the main file)
@@ -546,21 +546,14 @@ e.g. "cpp, h"
 
 arg[10] = **true** to let the runner compile the sources, **false** to skip compilation (when running multiple tests skipping increases performance)
 
-arg[11] = max lines to read from the user program (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
-
-arg[12] = max lines to read from the user program stderr (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
-
-arg[13] = max lines to write to the user program (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
+arg[11] = a unique session id (e.g. used with firejail to manage overlay fs names)
 
-arg[14] = a unique session id (e.g. used with firejail to manage overlay fs names)
-
-arg[15] = "true" to enable debug output (this will leak internal paths!!) or "false" to disable debug output. 
+arg[12] = "true" to enable debug output (this will leak internal paths!!) or "false" to disable debug output. 
 The debug output will be normal lines starting with " [Test-Runner]"
 
-arg[16] = (**string**) options for the compiler (whitespace separated like normal program args, whitespaces could be escaped by `-a "-b c"`)
+arg[13] = (**string**) options for the compiler (whitespace separated like normal program args, whitespaces could be escaped by `-a "-b c"`)
+
+arg[14] = (int) character limit for the test protocol, output cut after the limit
 
 ## Compile Test (or Syntax Test)
 method name: **compileTest**
@@ -583,6 +576,8 @@ The debug output will be normal lines starting with " [Test-Runner]"
 
 arg[8] = (string) options for the compiler (whitespace separated like normal program args, whitespaces could be escaped by `-a "-b c"`)
 
+arg[9] = (int) character limit for the test protocol, output cut after the limit
+
 ## Regex Test
 method name: **regexTest**
 
@@ -593,6 +588,8 @@ arg[2] = the main file name to use
 arg[3] = "true" to enable debug output (this will leak internal paths!!) or "false" to disable debug output.
 The debug output will be normal lines starting with " [Test-Runner]"
 
+**Reference implementation does not support this. This is done in the Test Server!**
+
 ## Compare Files Test
 
 
@@ -621,25 +618,20 @@ e.g. "cpp, h"
 
 arg[10] = **true** to let the runner compile the sources, **false** to skip compilation (when running multiple tests skipping increases performance)
 
-arg[11] = max lines to read from the user program (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
 
-arg[12] = max lines to read from the user program stderr (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
+arg[11] = a unique session id (e.g. used with firejail to manage overlay fs names)
 
-arg[13] = max lines to write to the user program (inclusive) (int) e.g. 100  
-negative or 0 is treated as unlimited
+arg[12] = **"true"** to enable debug output (this will leak internal paths!!) or **"false"** to disable debug output. 
+The debug output will be normal lines starting with " [Test-Runner]"
 
-arg[14] = a unique session id (e.g. used with firejail to manage overlay fs names)
+arg[13] = (**string**) options for the compiler (whitespace separated like normal program args, whitespaces could be escaped by `-a "-b c"`)
 
-arg[15] = **"true"** to enable debug output (this will leak internal paths!!) or **"false"** to disable debug output. 
-The debug output will be normal lines starting with " [Test-Runner]"
+arg[14] = (int) character limit for the test protocol, output cut after the limit
 
-arg[16] = "file1:hash1 file2:hash2" a list of `file:hash` pairs separated with a single whitespace.   
+arg[15] = "file1:hash1 file2:hash2" a list of `file:hash` pairs separated with a single whitespace.   
 These are the files for the test (the assets) with the pre calculated hash or `null` (if not pre calculated).
 The test runner decides of the hash needs to be calculated or not (only files that should be compared need to be hashed).
 
-arg[17] = (**string**) options for the compiler (whitespace separated like normal program args, whitespaces could be escaped by `-a "-b c"`)
 
 ## For all tests
 
diff --git a/stats/private.php b/stats/private.php
index 47021c5..e2ae124 100644
--- a/stats/private.php
+++ b/stats/private.php
@@ -22,9 +22,6 @@ $response = array(
     "maxParallelTests" => $config["maxParallelTests"],
     "maxNumberOfTestsWithOneRequest" => $config["maxNumberOfTestsWithOneRequest"],
     //"runner" => $config["runner"], //maybe not needed
-    "maxLinesToRead" => $config["maxLinesToRead"],
-    "maxErrLinesToRead" => $config["maxErrLinesToRead"],
-    "maxLinesToWrite" => $config["maxLinesToWrite"],
     "showTestRunnerDebugOutput" => $config["showTestRunnerDebugOutput"],
 
     "dbServer" => $config["dbServer"],
diff --git a/stats/public.php b/stats/public.php
index 0f1ac72..2d0f902 100644
--- a/stats/public.php
+++ b/stats/public.php
@@ -19,9 +19,6 @@ $response = array(
     $s_arg_hardMemoryLimitInKb => $config[$s_arg_hardMemoryLimitInKb],
 
     "maxNumberOfTestsWithOneRequest" => $config["maxNumberOfTestsWithOneRequest"],
-    "maxLinesToRead" => $config["maxLinesToRead"],
-    "maxErrLinesToRead" => $config["maxErrLinesToRead"],
-    "maxLinesToWrite" => $config["maxLinesToWrite"],
     "showTestRunnerDebugOutput" => $config["showTestRunnerDebugOutput"],
 );
 
-- 
GitLab