From 100258ffd6f9a9094878a5cdaff0aa8986d70eac Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 21 Dec 2023 20:12:02 +0000 Subject: [PATCH] Fix test for GH-10495: feof on OpenSSL stream hangs --- ext/openssl/tests/ServerClientTestCase.inc | 29 ++++++++++++++++++++++ ext/openssl/tests/gh10495.phpt | 23 +++++++++-------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/ext/openssl/tests/ServerClientTestCase.inc b/ext/openssl/tests/ServerClientTestCase.inc index 753366df6f4..a05a4815a01 100644 --- a/ext/openssl/tests/ServerClientTestCase.inc +++ b/ext/openssl/tests/ServerClientTestCase.inc @@ -26,6 +26,35 @@ function phpt_has_sslv3() { return $result; } +function phpt_extract_tls_records($rawData) { + $records = []; + $offset = 0; + $dataLength = strlen($rawData); + + while ($offset < $dataLength) { + // Ensure there's enough data left for the header. + if ($offset + 5 > $dataLength) { + break; + } + + // Extract the length of the current record. + $length = unpack("n", substr($rawData, $offset + 3, 2))[1]; + + // Check if the total length is within the bounds of the rawData. + if ($offset + 5 + $length > $dataLength) { + break; + } + + // Extract the record and add it to the records array. + $records[] = substr($rawData, $offset, 5 + $length); + + // Move the offset past the current record. + $offset += 5 + $length; + } + + return $records; +} + /** * This is a singleton to let the wait/notify functions work * I know it's horrible, but it's a means to an end diff --git a/ext/openssl/tests/gh10495.phpt b/ext/openssl/tests/gh10495.phpt index 3ed5a3d384b..7c743d8de50 100644 --- a/ext/openssl/tests/gh10495.phpt +++ b/ext/openssl/tests/gh10495.phpt @@ -63,25 +63,26 @@ $proxyCode = <<<'CODE' $read = [$upstream, $conn]; $applicationData = false; - $i = 1; while (stream_select($read, $write, $except, 1)) { foreach ($read as $fp) { $data = stream_get_contents($fp); if ($fp === $conn) { fwrite($upstream, $data); } else { - if ($data !== '' && $data[0] === chr(23)) { - if (!$applicationData) { - $applicationData = true; - fwrite($conn, $data[0]); - phpt_notify(); - sleep(1); - fwrite($conn, substr($data, 1)); + foreach (phpt_extract_tls_records($data) as $record) { + if ($record !== '' && $record[0] === chr(23)) { + if (!$applicationData) { + $applicationData = true; + fwrite($conn, $record[0]); + phpt_notify(); + sleep(1); + fwrite($conn, substr($record, 1)); + } else { + fwrite($conn, $record); + } } else { - fwrite($conn, $data); + fwrite($conn, $record); } - } else { - fwrite($conn, $data); } } }