mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
First fixes for a 64bit compatible ftp extension
This commit is contained in:
parent
8d86597d73
commit
a93a462dce
6 changed files with 107 additions and 57 deletions
|
@ -612,7 +612,7 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam
|
||||||
/* {{{ ftp_alloc
|
/* {{{ ftp_alloc
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ftp_alloc(ftpbuf_t *ftp, const int size, char **response)
|
ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
|
||||||
{
|
{
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
|
|
||||||
|
@ -620,7 +620,7 @@ ftp_alloc(ftpbuf_t *ftp, const int size, char **response)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer) - 1, "%d", size);
|
snprintf(buffer, sizeof(buffer) - 1, "%ld", size);
|
||||||
|
|
||||||
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
|
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -787,7 +787,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
|
||||||
/* {{{ ftp_get
|
/* {{{ ftp_get
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC)
|
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC)
|
||||||
{
|
{
|
||||||
databuf_t *data = NULL;
|
databuf_t *data = NULL;
|
||||||
int lastch;
|
int lastch;
|
||||||
|
@ -808,11 +808,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
|
||||||
ftp->data = data;
|
ftp->data = data;
|
||||||
|
|
||||||
if (resumepos > 0) {
|
if (resumepos > 0) {
|
||||||
if (resumepos > 2147483647) {
|
snprintf(arg, sizeof(arg), "%ld", resumepos);
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483647 bytes.");
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
snprintf(arg, sizeof(arg), "%u", resumepos);
|
|
||||||
if (!ftp_putcmd(ftp, "REST", arg)) {
|
if (!ftp_putcmd(ftp, "REST", arg)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -885,10 +881,10 @@ bail:
|
||||||
/* {{{ ftp_put
|
/* {{{ ftp_put
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC)
|
ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC)
|
||||||
{
|
{
|
||||||
databuf_t *data = NULL;
|
databuf_t *data = NULL;
|
||||||
int size;
|
long size;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int ch;
|
int ch;
|
||||||
char arg[11];
|
char arg[11];
|
||||||
|
@ -905,11 +901,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, i
|
||||||
ftp->data = data;
|
ftp->data = data;
|
||||||
|
|
||||||
if (startpos > 0) {
|
if (startpos > 0) {
|
||||||
if (startpos > 2147483647) {
|
snprintf(arg, sizeof(arg), "%ld", startpos);
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes.");
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
snprintf(arg, sizeof(arg), "%u", startpos);
|
|
||||||
if (!ftp_putcmd(ftp, "REST", arg)) {
|
if (!ftp_putcmd(ftp, "REST", arg)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +958,7 @@ bail:
|
||||||
|
|
||||||
/* {{{ ftp_size
|
/* {{{ ftp_size
|
||||||
*/
|
*/
|
||||||
int
|
long
|
||||||
ftp_size(ftpbuf_t *ftp, const char *path)
|
ftp_size(ftpbuf_t *ftp, const char *path)
|
||||||
{
|
{
|
||||||
if (ftp == NULL) {
|
if (ftp == NULL) {
|
||||||
|
@ -981,7 +973,7 @@ ftp_size(ftpbuf_t *ftp, const char *path)
|
||||||
if (!ftp_getresp(ftp) || ftp->resp != 213) {
|
if (!ftp_getresp(ftp) || ftp->resp != 213) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return atoi(ftp->inbuf);
|
return atol(ftp->inbuf);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -1143,7 +1135,7 @@ ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args)
|
||||||
int
|
int
|
||||||
ftp_readline(ftpbuf_t *ftp)
|
ftp_readline(ftpbuf_t *ftp)
|
||||||
{
|
{
|
||||||
int size, rcvd;
|
long size, rcvd;
|
||||||
char *data, *eol;
|
char *data, *eol;
|
||||||
|
|
||||||
/* shift the extra to the front */
|
/* shift the extra to the front */
|
||||||
|
@ -1236,7 +1228,8 @@ ftp_getresp(ftpbuf_t *ftp)
|
||||||
int
|
int
|
||||||
my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
|
my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
int n, size, sent;
|
long size, sent;
|
||||||
|
int n;
|
||||||
|
|
||||||
size = len;
|
size = len;
|
||||||
while (size) {
|
while (size) {
|
||||||
|
@ -1719,7 +1712,7 @@ bail:
|
||||||
/* {{{ ftp_nb_get
|
/* {{{ ftp_nb_get
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC)
|
ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC)
|
||||||
{
|
{
|
||||||
databuf_t *data = NULL;
|
databuf_t *data = NULL;
|
||||||
char arg[11];
|
char arg[11];
|
||||||
|
@ -1737,14 +1730,7 @@ ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t typ
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resumepos>0) {
|
if (resumepos>0) {
|
||||||
/* We are working on an architecture that supports 64-bit integers
|
snprintf(arg, sizeof(arg), "%ld", resumepos);
|
||||||
* since php is 32 bit by design, we bail out with warning
|
|
||||||
*/
|
|
||||||
if (resumepos > 2147483647) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483648 bytes.");
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
snprintf(arg, sizeof(arg), "%u", resumepos);
|
|
||||||
if (!ftp_putcmd(ftp, "REST", arg)) {
|
if (!ftp_putcmd(ftp, "REST", arg)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1843,7 +1829,7 @@ bail:
|
||||||
/* {{{ ftp_nb_put
|
/* {{{ ftp_nb_put
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC)
|
ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC)
|
||||||
{
|
{
|
||||||
databuf_t *data = NULL;
|
databuf_t *data = NULL;
|
||||||
char arg[11];
|
char arg[11];
|
||||||
|
@ -1858,11 +1844,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (startpos > 0) {
|
if (startpos > 0) {
|
||||||
if (startpos > 2147483647) {
|
snprintf(arg, sizeof(arg), "%ld", startpos);
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes.");
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
snprintf(arg, sizeof(arg), "%u", startpos);
|
|
||||||
if (!ftp_putcmd(ftp, "REST", arg)) {
|
if (!ftp_putcmd(ftp, "REST", arg)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1899,7 +1881,7 @@ bail:
|
||||||
int
|
int
|
||||||
ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC)
|
ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC)
|
||||||
{
|
{
|
||||||
int size;
|
long size;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ int ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int fi
|
||||||
* however some servers will not accept STOR or APPE until ALLO is confirmed.
|
* however some servers will not accept STOR or APPE until ALLO is confirmed.
|
||||||
* If response is passed, it is estrdup()ed from ftp->inbuf and must be freed
|
* If response is passed, it is estrdup()ed from ftp->inbuf and must be freed
|
||||||
* or assigned to a zval returned to the user */
|
* or assigned to a zval returned to the user */
|
||||||
int ftp_alloc(ftpbuf_t *ftp, const int size, char **response);
|
int ftp_alloc(ftpbuf_t *ftp, const long size, char **response);
|
||||||
|
|
||||||
/* returns a NULL-terminated array of filenames in the given path
|
/* returns a NULL-terminated array of filenames in the given path
|
||||||
* or NULL on error. the return array must be freed (but don't
|
* or NULL on error. the return array must be freed (but don't
|
||||||
|
@ -169,15 +169,15 @@ int ftp_pasv(ftpbuf_t *ftp, int pasv);
|
||||||
/* retrieves a file and saves its contents to outfp
|
/* retrieves a file and saves its contents to outfp
|
||||||
* returns true on success, false on error
|
* returns true on success, false on error
|
||||||
*/
|
*/
|
||||||
int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC);
|
int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC);
|
||||||
|
|
||||||
/* stores the data from a file, socket, or process as a file on the remote server
|
/* stores the data from a file, socket, or process as a file on the remote server
|
||||||
* returns true on success, false on error
|
* returns true on success, false on error
|
||||||
*/
|
*/
|
||||||
int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC);
|
int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC);
|
||||||
|
|
||||||
/* returns the size of the given file, or -1 on error */
|
/* returns the size of the given file, or -1 on error */
|
||||||
int ftp_size(ftpbuf_t *ftp, const char *path);
|
long ftp_size(ftpbuf_t *ftp, const char *path);
|
||||||
|
|
||||||
/* returns the last modified time of the given file, or -1 on error */
|
/* returns the last modified time of the given file, or -1 on error */
|
||||||
time_t ftp_mdtm(ftpbuf_t *ftp, const char *path);
|
time_t ftp_mdtm(ftpbuf_t *ftp, const char *path);
|
||||||
|
@ -194,12 +194,12 @@ int ftp_site(ftpbuf_t *ftp, const char *cmd);
|
||||||
/* retrieves part of a file and saves its contents to outfp
|
/* retrieves part of a file and saves its contents to outfp
|
||||||
* returns true on success, false on error
|
* returns true on success, false on error
|
||||||
*/
|
*/
|
||||||
int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC);
|
int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC);
|
||||||
|
|
||||||
/* stores the data from a file, socket, or process as a file on the remote server
|
/* stores the data from a file, socket, or process as a file on the remote server
|
||||||
* returns true on success, false on error
|
* returns true on success, false on error
|
||||||
*/
|
*/
|
||||||
int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC);
|
int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC);
|
||||||
|
|
||||||
/* continues a previous nb_(f)get command
|
/* continues a previous nb_(f)get command
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -784,8 +784,8 @@ PHP_FUNCTION(ftp_nb_fget)
|
||||||
ftptype_t xtype;
|
ftptype_t xtype;
|
||||||
php_stream *stream;
|
php_stream *stream;
|
||||||
char *file;
|
char *file;
|
||||||
int file_len, ret;
|
int file_len;
|
||||||
long mode, resumepos=0;
|
long mode, resumepos=0, ret;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
|
@ -968,9 +968,7 @@ PHP_FUNCTION(ftp_nb_get)
|
||||||
RETURN_LONG(PHP_FTP_FAILED);
|
RETURN_LONG(PHP_FTP_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == PHP_FTP_FINISHED) {
|
|
||||||
php_stream_close(outstream);
|
php_stream_close(outstream);
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_LONG(ret);
|
RETURN_LONG(ret);
|
||||||
}
|
}
|
||||||
|
@ -982,7 +980,7 @@ PHP_FUNCTION(ftp_nb_continue)
|
||||||
{
|
{
|
||||||
zval *z_ftp;
|
zval *z_ftp;
|
||||||
ftpbuf_t *ftp;
|
ftpbuf_t *ftp;
|
||||||
int ret;
|
long ret;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
|
@ -1120,7 +1118,7 @@ PHP_FUNCTION(ftp_put)
|
||||||
ftpbuf_t *ftp;
|
ftpbuf_t *ftp;
|
||||||
ftptype_t xtype;
|
ftptype_t xtype;
|
||||||
char *remote, *local;
|
char *remote, *local;
|
||||||
int remote_len, local_len;
|
long remote_len, local_len;
|
||||||
long mode, startpos=0;
|
long mode, startpos=0;
|
||||||
php_stream *instream;
|
php_stream *instream;
|
||||||
|
|
||||||
|
@ -1173,8 +1171,8 @@ PHP_FUNCTION(ftp_nb_put)
|
||||||
ftpbuf_t *ftp;
|
ftpbuf_t *ftp;
|
||||||
ftptype_t xtype;
|
ftptype_t xtype;
|
||||||
char *remote, *local;
|
char *remote, *local;
|
||||||
int remote_len, local_len, ret;
|
int remote_len, local_len;
|
||||||
long mode, startpos=0;
|
long mode, startpos=0, ret;
|
||||||
php_stream *instream;
|
php_stream *instream;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
|
||||||
|
|
23
ext/ftp/tests/filesize_large.phpt
Normal file
23
ext/ftp/tests/filesize_large.phpt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
--TEST--
|
||||||
|
Verify php can handle filesizes >32bit
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require 'skipif.inc';
|
||||||
|
if (2147483647 == PHP_INT_MAX) {
|
||||||
|
die('skip 64-bit only');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require 'server.inc';
|
||||||
|
|
||||||
|
$ftp = ftp_connect('127.0.0.1', $port);
|
||||||
|
if (!$ftp) die("Couldn't connect to the server");
|
||||||
|
|
||||||
|
ftp_login($ftp, 'user', 'pass');
|
||||||
|
var_dump(ftp_size($ftp, 'largefile'));
|
||||||
|
|
||||||
|
ftp_close($ftp);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(5368709120)
|
36
ext/ftp/tests/ftp_nb_get_large.phpt
Normal file
36
ext/ftp/tests/ftp_nb_get_large.phpt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
--TEST--
|
||||||
|
Testing ftp_nb_fget can handle large files incl. resume
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require 'skipif.inc';
|
||||||
|
if (2147483647 == PHP_INT_MAX) {
|
||||||
|
die('skip ot supported on this system');
|
||||||
|
}
|
||||||
|
if (disk_free_space(__DIR__) < 10*1024*1024*1024) {
|
||||||
|
die('not enough disk space');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require 'server.inc';
|
||||||
|
|
||||||
|
$ftp = ftp_connect('127.0.0.1', $port);
|
||||||
|
ftp_login($ftp, 'user', 'pass');
|
||||||
|
if (!$ftp) die("Couldn't connect to the server");
|
||||||
|
|
||||||
|
$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt";
|
||||||
|
touch($local_file);
|
||||||
|
ftp_nb_get($ftp, $local_file, 'fget_large.txt', FTP_BINARY, 5368709119);
|
||||||
|
$fp = fopen($local_file, 'r');
|
||||||
|
fseek($fp, 5368709119);
|
||||||
|
var_dump(fread($fp, 1));
|
||||||
|
var_dump(filesize($local_file));
|
||||||
|
fclose($fp);
|
||||||
|
?>
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
@unlink(dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt");
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
string(1) "X"
|
||||||
|
int(5368709120)
|
|
@ -358,6 +358,16 @@ if ($pid) {
|
||||||
fputs($fs, "Bar\r\n");
|
fputs($fs, "Bar\r\n");
|
||||||
fputs($s, "226 Closing data Connection.\r\n");
|
fputs($s, "226 Closing data Connection.\r\n");
|
||||||
break;
|
break;
|
||||||
|
case "fget_large":
|
||||||
|
fputs($s, "150 File status okay; about to open data connection.\r\n");
|
||||||
|
$transfer_type = $ascii? 'ASCII' : 'BINARY' ;
|
||||||
|
if ($GLOBALS['rest_pos'] == '5368709119') {
|
||||||
|
fputs($fs, "X");
|
||||||
|
} else {
|
||||||
|
fputs($fs, "Y");
|
||||||
|
}
|
||||||
|
fputs($s, "226 Closing data Connection.\r\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fputs($s, "550 {$matches[1]}: No such file or directory \r\n");
|
fputs($s, "550 {$matches[1]}: No such file or directory \r\n");
|
||||||
break;
|
break;
|
||||||
|
@ -393,11 +403,12 @@ if ($pid) {
|
||||||
}elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) {
|
}elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) {
|
||||||
fputs($s, "425 Error establishing connection\r\n");
|
fputs($s, "425 Error establishing connection\r\n");
|
||||||
|
|
||||||
}elseif (preg_match('/^REST \d+/', $buf, $matches)) {
|
}elseif (preg_match('/^REST (\d+)/', $buf, $matches)) {
|
||||||
|
$GLOBALS['rest_pos'] = $matches[1];
|
||||||
fputs($s, "350 OK\r\n");
|
fputs($s, "350 OK\r\n");
|
||||||
}
|
}elseif (preg_match('/^SIZE largefile/', $buf)) {
|
||||||
|
fputs($s, "213 5368709120\r\n");
|
||||||
else {
|
}else {
|
||||||
fputs($s, "500 Syntax error, command unrecognized.\r\n");
|
fputs($s, "500 Syntax error, command unrecognized.\r\n");
|
||||||
dump_and_exit($buf);
|
dump_and_exit($buf);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue