php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68743 Infinite loop when CURLOPT_INFILESIZE doesn't match sended data
Submitted: 2015-01-04 14:25 UTC Modified: 2015-01-09 07:29 UTC
From: sjaillet at gmail dot com Assigned:
Status: Not a bug Package: cURL related
PHP Version: 5.6.4 OS: Ubuntu 14.04.1
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sjaillet at gmail dot com
New email:
PHP Version: OS:

 

 [2015-01-04 14:25 UTC] sjaillet at gmail dot com
Description:
------------
cURL multi enter into an infinite loop when CURLOPT_INFILESIZE doesn't match the size of sended data.

In the test script below I intentionally set the CURLOPT_INFILESIZE to the size of the sended data plus 1 byte.

In the documentation we can see that CURLOPT_READFUNCTION should return an empty string to signal an EOF.

So it's what I done in the following script.

So since CURLOPT_READFUNCTION returned the EOF signal which indicates that there's nothing to wait for, I expected cURL to bail out and throwing an error (or at least timeout), but the test script run into an infinite loop instead.


Test script:
---------------
$options = [
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
    CURLOPT_RETURNTRANSFER => false,
    CURLOPT_HEADER         => false,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_UPLOAD         => true,
    CURLOPT_URL            => 'http://httpbin.org/put',
    CURLOPT_CONNECTTIMEOUT => 1,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: text/plain; charset=UTF-8',
    ],
    CURLOPT_READFUNCTION   => function($handle, $fp, $length) {
        static $data = 'HelloWorld';
        $readed = $data;
        $data = '';
        echo "Length asked: '{$length}'\n";
        echo "Readed: '{$readed}'\n";
        return $readed;
    },
    CURLOPT_INFILESIZE     => strlen('HelloWorld') + 1 // The extra byte
];

$handle = curl_init();
curl_setopt_array($handle, $options);

$mh = curl_multi_init();
curl_multi_add_handle($mh, $handle);

$running = 0;
do {
    if (curl_multi_select($mh) === -1) {
        usleep(1000);
    }
    curl_multi_exec($mh, $running);
    echo "Number of running request(s): '{$running}'\n";
} while ($running > 0);


Expected result:
----------------
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
Length asked: '16384'
Readed: 'HelloWorld'
# of running request(s): '1'
Length asked: '16384'
Readed: ''
# of running request(s): '1'
# of running request(s): '0'

And a call to curl_strerror() should be able to display the error.

Actual result:
--------------
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
Length asked: '16384'
Readed: 'HelloWorld'
# of running request(s): '1'
Length asked: '16384'
Readed: ''
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
... etc.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-04 18:43 UTC] sjaillet at gmail dot com
Just for information, using `curl_exec($handle)` directly instead of the multi loop has the same behavior and the call hangs out indefinitely.
 [2015-01-09 07:29 UTC] krakjoe@php.net
-Status: Open +Status: Not a bug
 [2015-01-09 07:29 UTC] krakjoe@php.net
This is programmer error, you are forcing curl or your loop to execute indefinitely by providing the wrong length. 

cURL, and PHP, cannot possibly detect that you have programmed it wrong.
 [2015-01-11 01:08 UTC] nacridan at gmail dot com
The documentation of CURLOPT_READFUNCTION is pretty explicit: "It should return an empty string to signal EOF." which is the case here.
So if the data returned by READFUNCTION has the wrong length, it should generate an error, not an infinite loop so please reconsider the status of this ticket.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 16:01:28 2024 UTC