Skip to content

Commit 7d3fa7d

Browse files
committed
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4: First fixes for a 64bit compatible ftp extension
2 parents e4f9619 + a93a462 commit 7d3fa7d

File tree

6 files changed

+107
-57
lines changed

6 files changed

+107
-57
lines changed

ext/ftp/ftp.c

+18-36
Original file line numberDiff line numberDiff line change
@@ -612,16 +612,16 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam
612612
/* {{{ ftp_alloc
613613
*/
614614
int
615-
ftp_alloc(ftpbuf_t *ftp, const int size, char **response)
615+
ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
616616
{
617617
char buffer[64];
618618

619619
if (ftp == NULL || size <= 0) {
620620
return 0;
621621
}
622622

623-
snprintf(buffer, sizeof(buffer) - 1, "%d", size);
624-
623+
snprintf(buffer, sizeof(buffer) - 1, "%ld", size);
624+
625625
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
626626
return 0;
627627
}
@@ -787,7 +787,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
787787
/* {{{ ftp_get
788788
*/
789789
int
790-
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC)
790+
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC)
791791
{
792792
databuf_t *data = NULL;
793793
int lastch;
@@ -808,11 +808,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
808808
ftp->data = data;
809809

810810
if (resumepos > 0) {
811-
if (resumepos > 2147483647) {
812-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483647 bytes.");
813-
goto bail;
814-
}
815-
snprintf(arg, sizeof(arg), "%u", resumepos);
811+
snprintf(arg, sizeof(arg), "%ld", resumepos);
816812
if (!ftp_putcmd(ftp, "REST", arg)) {
817813
goto bail;
818814
}
@@ -885,10 +881,10 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
885881
/* {{{ ftp_put
886882
*/
887883
int
888-
ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC)
884+
ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC)
889885
{
890886
databuf_t *data = NULL;
891-
int size;
887+
long size;
892888
char *ptr;
893889
int ch;
894890
char arg[11];
@@ -905,11 +901,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, i
905901
ftp->data = data;
906902

907903
if (startpos > 0) {
908-
if (startpos > 2147483647) {
909-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes.");
910-
goto bail;
911-
}
912-
snprintf(arg, sizeof(arg), "%u", startpos);
904+
snprintf(arg, sizeof(arg), "%ld", startpos);
913905
if (!ftp_putcmd(ftp, "REST", arg)) {
914906
goto bail;
915907
}
@@ -966,7 +958,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, i
966958

967959
/* {{{ ftp_size
968960
*/
969-
int
961+
long
970962
ftp_size(ftpbuf_t *ftp, const char *path)
971963
{
972964
if (ftp == NULL) {
@@ -981,7 +973,7 @@ ftp_size(ftpbuf_t *ftp, const char *path)
981973
if (!ftp_getresp(ftp) || ftp->resp != 213) {
982974
return -1;
983975
}
984-
return atoi(ftp->inbuf);
976+
return atol(ftp->inbuf);
985977
}
986978
/* }}} */
987979

@@ -1143,7 +1135,7 @@ ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args)
11431135
int
11441136
ftp_readline(ftpbuf_t *ftp)
11451137
{
1146-
int size, rcvd;
1138+
long size, rcvd;
11471139
char *data, *eol;
11481140

11491141
/* shift the extra to the front */
@@ -1236,7 +1228,8 @@ ftp_getresp(ftpbuf_t *ftp)
12361228
int
12371229
my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
12381230
{
1239-
int n, size, sent;
1231+
long size, sent;
1232+
int n;
12401233

12411234
size = len;
12421235
while (size) {
@@ -1719,7 +1712,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
17191712
/* {{{ ftp_nb_get
17201713
*/
17211714
int
1722-
ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC)
1715+
ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC)
17231716
{
17241717
databuf_t *data = NULL;
17251718
char arg[11];
@@ -1737,14 +1730,7 @@ ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t typ
17371730
}
17381731

17391732
if (resumepos>0) {
1740-
/* We are working on an architecture that supports 64-bit integers
1741-
* since php is 32 bit by design, we bail out with warning
1742-
*/
1743-
if (resumepos > 2147483647) {
1744-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater than 2147483648 bytes.");
1745-
goto bail;
1746-
}
1747-
snprintf(arg, sizeof(arg), "%u", resumepos);
1733+
snprintf(arg, sizeof(arg), "%ld", resumepos);
17481734
if (!ftp_putcmd(ftp, "REST", arg)) {
17491735
goto bail;
17501736
}
@@ -1843,7 +1829,7 @@ ftp_nb_continue_read(ftpbuf_t *ftp TSRMLS_DC)
18431829
/* {{{ ftp_nb_put
18441830
*/
18451831
int
1846-
ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC)
1832+
ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC)
18471833
{
18481834
databuf_t *data = NULL;
18491835
char arg[11];
@@ -1858,11 +1844,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type
18581844
goto bail;
18591845
}
18601846
if (startpos > 0) {
1861-
if (startpos > 2147483647) {
1862-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater than 2147483647 bytes.");
1863-
goto bail;
1864-
}
1865-
snprintf(arg, sizeof(arg), "%u", startpos);
1847+
snprintf(arg, sizeof(arg), "%ld", startpos);
18661848
if (!ftp_putcmd(ftp, "REST", arg)) {
18671849
goto bail;
18681850
}
@@ -1899,7 +1881,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type
18991881
int
19001882
ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC)
19011883
{
1902-
int size;
1884+
long size;
19031885
char *ptr;
19041886
int ch;
19051887

ext/ftp/ftp.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ int ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int fi
146146
* however some servers will not accept STOR or APPE until ALLO is confirmed.
147147
* If response is passed, it is estrdup()ed from ftp->inbuf and must be freed
148148
* or assigned to a zval returned to the user */
149-
int ftp_alloc(ftpbuf_t *ftp, const int size, char **response);
149+
int ftp_alloc(ftpbuf_t *ftp, const long size, char **response);
150150

151151
/* returns a NULL-terminated array of filenames in the given path
152152
* 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);
169169
/* retrieves a file and saves its contents to outfp
170170
* returns true on success, false on error
171171
*/
172-
int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC);
172+
int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC);
173173

174174
/* stores the data from a file, socket, or process as a file on the remote server
175175
* returns true on success, false on error
176176
*/
177-
int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC);
177+
int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC);
178178

179179
/* returns the size of the given file, or -1 on error */
180-
int ftp_size(ftpbuf_t *ftp, const char *path);
180+
long ftp_size(ftpbuf_t *ftp, const char *path);
181181

182182
/* returns the last modified time of the given file, or -1 on error */
183183
time_t ftp_mdtm(ftpbuf_t *ftp, const char *path);
@@ -194,12 +194,12 @@ int ftp_site(ftpbuf_t *ftp, const char *cmd);
194194
/* retrieves part of a file and saves its contents to outfp
195195
* returns true on success, false on error
196196
*/
197-
int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC);
197+
int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC);
198198

199199
/* stores the data from a file, socket, or process as a file on the remote server
200200
* returns true on success, false on error
201201
*/
202-
int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC);
202+
int ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, long startpos TSRMLS_DC);
203203

204204
/* continues a previous nb_(f)get command
205205
*/

ext/ftp/php_ftp.c

+7-9
Original file line numberDiff line numberDiff line change
@@ -784,8 +784,8 @@ PHP_FUNCTION(ftp_nb_fget)
784784
ftptype_t xtype;
785785
php_stream *stream;
786786
char *file;
787-
int file_len, ret;
788-
long mode, resumepos=0;
787+
int file_len;
788+
long mode, resumepos=0, ret;
789789

790790
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrsl|l", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
791791
return;
@@ -968,9 +968,7 @@ PHP_FUNCTION(ftp_nb_get)
968968
RETURN_LONG(PHP_FTP_FAILED);
969969
}
970970

971-
if (ret == PHP_FTP_FINISHED) {
972-
php_stream_close(outstream);
973-
}
971+
php_stream_close(outstream);
974972

975973
RETURN_LONG(ret);
976974
}
@@ -982,7 +980,7 @@ PHP_FUNCTION(ftp_nb_continue)
982980
{
983981
zval *z_ftp;
984982
ftpbuf_t *ftp;
985-
int ret;
983+
long ret;
986984

987985
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ftp) == FAILURE) {
988986
return;
@@ -1120,7 +1118,7 @@ PHP_FUNCTION(ftp_put)
11201118
ftpbuf_t *ftp;
11211119
ftptype_t xtype;
11221120
char *remote, *local;
1123-
int remote_len, local_len;
1121+
long remote_len, local_len;
11241122
long mode, startpos=0;
11251123
php_stream *instream;
11261124

@@ -1173,8 +1171,8 @@ PHP_FUNCTION(ftp_nb_put)
11731171
ftpbuf_t *ftp;
11741172
ftptype_t xtype;
11751173
char *remote, *local;
1176-
int remote_len, local_len, ret;
1177-
long mode, startpos=0;
1174+
int remote_len, local_len;
1175+
long mode, startpos=0, ret;
11781176
php_stream *instream;
11791177

11801178
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rppl|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {

ext/ftp/tests/filesize_large.phpt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Verify php can handle filesizes >32bit
3+
--SKIPIF--
4+
<?php
5+
require 'skipif.inc';
6+
if (2147483647 == PHP_INT_MAX) {
7+
die('skip 64-bit only');
8+
}
9+
?>
10+
--FILE--
11+
<?php
12+
require 'server.inc';
13+
14+
$ftp = ftp_connect('127.0.0.1', $port);
15+
if (!$ftp) die("Couldn't connect to the server");
16+
17+
ftp_login($ftp, 'user', 'pass');
18+
var_dump(ftp_size($ftp, 'largefile'));
19+
20+
ftp_close($ftp);
21+
?>
22+
--EXPECT--
23+
int(5368709120)

ext/ftp/tests/ftp_nb_get_large.phpt

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Testing ftp_nb_fget can handle large files incl. resume
3+
--SKIPIF--
4+
<?php
5+
require 'skipif.inc';
6+
if (2147483647 == PHP_INT_MAX) {
7+
die('skip ot supported on this system');
8+
}
9+
if (disk_free_space(__DIR__) < 10*1024*1024*1024) {
10+
die('not enough disk space');
11+
}
12+
?>
13+
--FILE--
14+
<?php
15+
require 'server.inc';
16+
17+
$ftp = ftp_connect('127.0.0.1', $port);
18+
ftp_login($ftp, 'user', 'pass');
19+
if (!$ftp) die("Couldn't connect to the server");
20+
21+
$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt";
22+
touch($local_file);
23+
ftp_nb_get($ftp, $local_file, 'fget_large.txt', FTP_BINARY, 5368709119);
24+
$fp = fopen($local_file, 'r');
25+
fseek($fp, 5368709119);
26+
var_dump(fread($fp, 1));
27+
var_dump(filesize($local_file));
28+
fclose($fp);
29+
?>
30+
--CLEAN--
31+
<?php
32+
@unlink(dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt");
33+
?>
34+
--EXPECT--
35+
string(1) "X"
36+
int(5368709120)

ext/ftp/tests/server.inc

+17-6
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,17 @@ if ($pid) {
357357
$transfer_type = $ascii? 'ASCII' : 'BINARY' ;
358358
fputs($fs, "Bar\r\n");
359359
fputs($s, "226 Closing data Connection.\r\n");
360-
break;
360+
break;
361+
case "fget_large":
362+
fputs($s, "150 File status okay; about to open data connection.\r\n");
363+
$transfer_type = $ascii? 'ASCII' : 'BINARY' ;
364+
if ($GLOBALS['rest_pos'] == '5368709119') {
365+
fputs($fs, "X");
366+
} else {
367+
fputs($fs, "Y");
368+
}
369+
fputs($s, "226 Closing data Connection.\r\n");
370+
break;
361371
default:
362372
fputs($s, "550 {$matches[1]}: No such file or directory \r\n");
363373
break;
@@ -393,11 +403,12 @@ if ($pid) {
393403
}elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) {
394404
fputs($s, "425 Error establishing connection\r\n");
395405

396-
}elseif (preg_match('/^REST \d+/', $buf, $matches)) {
406+
}elseif (preg_match('/^REST (\d+)/', $buf, $matches)) {
407+
$GLOBALS['rest_pos'] = $matches[1];
397408
fputs($s, "350 OK\r\n");
398-
}
399-
400-
else {
409+
}elseif (preg_match('/^SIZE largefile/', $buf)) {
410+
fputs($s, "213 5368709120\r\n");
411+
}else {
401412
fputs($s, "500 Syntax error, command unrecognized.\r\n");
402413
dump_and_exit($buf);
403414
}
@@ -407,4 +418,4 @@ if ($pid) {
407418
}
408419

409420
fclose($socket);
410-
?>
421+
?>

0 commit comments

Comments
 (0)