Skip to content

Fix handling of large compressed packets #6144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

nikic
Copy link
Member

@nikic nikic commented Sep 16, 2020

Fix for https://bugs.php.net/bug.php?id=80107. There's two layers of packet splitting going on. First, packets need to be split into having a payload of exactly 2^24-1 bytes or being the last packet. If the split packet has size between 2^24-5 and 2^24-1 bytes, the compressed packets also needs to be split, though the choice of split doesn't matter here. I'm splitting off the first 8192 bytes, as that's what I observe libmysqlclient to be doing.

If I may say so, the protocol is pretty ridiculous.

@cmb69
Copy link
Member

cmb69 commented Sep 16, 2020

The test fails on default configurations of MySQL 5.6 and 8.0 on Windows, because max_allowed_packet is only 4MB there. I suggest something like:

 ext/mysqli/tests/mysqli_real_connect_compression_error.phpt | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt b/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt
index 4ce0804bc8..fb876bf449 100644
--- a/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt
+++ b/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt
@@ -4,7 +4,15 @@ Bug #80107 mysqli_query() fails for ~16 MB long query when compression is enable
 <?php
 require_once('skipif.inc');
 require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
+require_once("connect.inc");
+$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
+if (!$link) {
+    die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
+}
+$result = $link->query("SHOW VARIABLES LIKE 'max_allowed_packet'");
+if ($result->fetch_assoc()['Value'] < 0xffffff) {
+    die('skip max_allowed_packet is less than 0xffffff');
+}
 ?>
 --INI--
 mysqli.allow_local_infile=1

@nikic
Copy link
Member Author

nikic commented Sep 16, 2020

@cmb69 I see a couple tests doing SET @@global.max_allowed_packet = or SET GLOBAL max_allowed_packet =. Would that work as well?

@cmb69
Copy link
Member

cmb69 commented Sep 16, 2020

That needs SUPER privilege, and fails otherwise. We could check for that, but given that the test apparently works in CI, I think just skipping is okay.

@nikic
Copy link
Member Author

nikic commented Sep 18, 2020

Merged into 7.3 up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants