From 4e0496e2d6d0bcf654235854d88f71b031e63cb0 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 22 Jun 2015 12:34:38 +0300 Subject: Work-around for https://bugs.php.net/bug.php?id=39598 Fixes #3922 --- system/libraries/Email.php | 22 +++++++++++++++++++++- system/libraries/Xmlrpc.php | 22 +++++++++++++++++++++- user_guide_src/source/changelog.rst | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 66b5803dd..57693e1c7 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -2126,12 +2126,32 @@ class CI_Email { protected function _send_data($data) { $data .= $this->newline; - for ($written = 0, $length = strlen($data); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = strlen($data); $written < $length; $written += $result) { if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) { break; } + // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951 + elseif ($result === 0) + { + if ($timestamp === 0) + { + $timestamp = time(); + } + elseif ($timestamp < (time() - $this->smtp_timeout)) + { + $result = FALSE; + break; + } + + usleep(250000); + continue; + } + else + { + $timestamp = 0; + } } if ($result === FALSE) diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index 8fbc18f04..55555f56f 100644 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -735,12 +735,32 @@ class XML_RPC_Client extends CI_Xmlrpc .'Content-Length: '.strlen($msg->payload).$r.$r .$msg->payload; - for ($written = 0, $length = strlen($op); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result) { if (($result = fwrite($fp, substr($op, $written))) === FALSE) { break; } + // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951 + elseif ($result === 0) + { + if ($timestamp === 0) + { + $timestamp = time(); + } + elseif ($timestamp < (time() - $this->timeout)) + { + $result = FALSE; + break; + } + + usleep(250000); + continue; + } + else + { + $timestamp = 0; + } } if ($result === FALSE) diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 034fa9ac3..46d19bf2b 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -42,6 +42,7 @@ Bug fixes for 3.0.1 - Fixed a bug (#3890) - :doc:`Input Library ` method ``get_request_header()`` treated header names as case-sensitive. - Fixed a bug (#3903) - :doc:`Form Validation Library ` ignored "unnamed" closure validation rules. - Fixed a bug (#3904) - :doc:`Form Validation Library ` ignored "named" callback rules when the field is empty and there's no 'required' rule. +- Fixed a bug (#3922) - :doc:`Email ` and :doc:`XML-RPC ` libraries could enter an infinite loop due to `PHP bug #39598 `_. Version 3.0.0 ============= -- cgit v1.2.3-24-g4f1b