diff --git a/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php b/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php index 7265bab13bb01..6aa215f56dbec 100644 --- a/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php +++ b/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php @@ -193,9 +193,15 @@ private function getCurlCommand(array $trace): ?string $dataArg = []; if ($json = $trace['options']['json'] ?? null) { - $dataArg[] = '--data '.escapeshellarg(self::jsonEncode($json)); + if (!$this->argMaxLengthIsSafe($payload = self::jsonEncode($json))) { + return null; + } + $dataArg[] = '--data '.escapeshellarg($payload); } elseif ($body = $trace['options']['body'] ?? null) { if (\is_string($body)) { + if (!$this->argMaxLengthIsSafe($body)) { + return null; + } try { $dataArg[] = '--data '.escapeshellarg($body); } catch (\ValueError) { @@ -204,7 +210,10 @@ private function getCurlCommand(array $trace): ?string } elseif (\is_array($body)) { $body = explode('&', self::normalizeBody($body)); foreach ($body as $value) { - $dataArg[] = '--data '.escapeshellarg(urldecode($value)); + if (!$this->argMaxLengthIsSafe($payload = urldecode($value))) { + return null; + } + $dataArg[] = '--data '.escapeshellarg($payload); } } else { return null; @@ -240,4 +249,14 @@ private function getCurlCommand(array $trace): ?string return implode(" \\\n ", $command); } + + /** + * Let's be defensive : we authorize only size of 8kio on Windows for escapeshellarg() argument to avoid a fatal error + * + * @see https://github.com/php/php-src/blob/9458f5f2c8a8e3d6c65cc181747a5a75654b7c6e/ext/standard/exec.c#L397 + */ + private function argMaxLengthIsSafe(string $payload): bool + { + return \strlen($payload) < ('\\' === \DIRECTORY_SEPARATOR ? 8100 : 256000); + } } diff --git a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php index 18b08473aa2f2..3cb5278bbd5b4 100755 --- a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php +++ b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php @@ -417,6 +417,28 @@ public function testItDoesNotGeneratesCurlCommandsForNotEncodableBody() self::assertNull($curlCommand); } + /** + * @requires extension openssl + */ + public function testItDoesNotGeneratesCurlCommandsForTooBigData() + { + $sut = new HttpClientDataCollector(); + $sut->registerClient('http_client', $this->httpClientThatHasTracedRequests([ + [ + 'method' => 'POST', + 'url' => 'http://localhost:8057/json', + 'options' => [ + 'body' => str_repeat('1', 257000), + ], + ], + ])); + $sut->collect(new Request(), new Response()); + $collectedData = $sut->getClients(); + self::assertCount(1, $collectedData['http_client']['traces']); + $curlCommand = $collectedData['http_client']['traces'][0]['curlCommand']; + self::assertNull($curlCommand); + } + private function httpClientThatHasTracedRequests($tracedRequests): TraceableHttpClient { $httpClient = new TraceableHttpClient(new NativeHttpClient());