This bug has been open for a while:
http://bugs.php.net/bug.php?id=27792
Having run into this issue recently, here's a patch (hopefully
attached, mail.app and list filters willing) against PHP 5.3 to
address it.
This patch will promote to double the file sizes that overflow
LONG_MAX, which works transparently for my script.
Note that this only touches the obvious functions in the core; there
may be other extensions that need to behave similarly.
The defines that I jam into CFLAGS are known to work in our other
projects on Linux, Solaris, FreeBSD and OSX. The other (weirder)
platforms might need some other adjustments to work correctly.
--Wez.
Index: configure.in
===================================================================
RCS file: /repository/php-src/configure.in,v
retrieving revision 1.579.2.52.2.77.2.5
diff -u -p -r1.579.2.52.2.77.2.5 configure.in
--- configure.in 5 Oct 2007 15:00:05 -0000 1.579.2.52.2.77.2.5
+++ configure.in 14 Oct 2007 21:54:34 -0000
@@ -154,6 +154,8 @@ PHP_PROG_LEX
dnl Platform-specific compile settings.
dnl -------------------------------------------------------------------------
+CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-D_LARGEFILE64_SOURCE"
+
dnl See bug #28605
case $host_cpu in
alpha*)
Index: ext/standard/file.c
===================================================================
RCS file: /repository/php-src/ext/standard/file.c,v
retrieving revision 1.409.2.6.2.28.2.1
diff -u -p -r1.409.2.6.2.28.2.1 file.c
--- ext/standard/file.c 3 Oct 2007 10:44:32 -0000 1.409.2.6.2.28.2.1
+++ ext/standard/file.c 14 Oct 2007 21:54:36 -0000
@@ -1348,7 +1348,7 @@ PHPAPI PHP_FUNCTION(rewind)
PHPAPI PHP_FUNCTION(ftell)
{
zval **arg1;
- long ret;
+ off_t ret;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) ==
FAILURE) {
@@ -1361,7 +1361,11 @@ PHPAPI PHP_FUNCTION(ftell)
if (ret == -1) {
RETURN_FALSE;
}
- RETURN_LONG(ret);
+ if (ret > LONG_MAX) {
+ RETURN_DOUBLE((double)ret);
+ } else {
+ RETURN_LONG((long)ret);
+ }
}
/* }}} */
@@ -1460,7 +1464,7 @@ PHP_FUNCTION(rmdir)
PHP_FUNCTION(readfile)
{
char *filename;
- int size = 0;
+ size_t size = 0;
int filename_len;
zend_bool use_include_path = 0;
zval *zcontext = NULL;
@@ -1477,7 +1481,11 @@ PHP_FUNCTION(readfile)
if (stream) {
size = php_stream_passthru(stream);
php_stream_close(stream);
- RETURN_LONG(size);
+ if (size > LONG_MAX) {
+ RETURN_DOUBLE((double)size);
+ } else {
+ RETURN_LONG((long)size);
+ }
}
RETURN_FALSE;
}
@@ -1517,7 +1525,7 @@ PHP_FUNCTION(umask)
PHPAPI PHP_FUNCTION(fpassthru)
{
zval **arg1;
- int size;
+ size_t size;
php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) ==
FAILURE) {
@@ -1527,7 +1535,11 @@ PHPAPI PHP_FUNCTION(fpassthru)
PHP_STREAM_TO_ZVAL(stream, arg1);
size = php_stream_passthru(stream);
- RETURN_LONG(size);
+ if (size > LONG_MAX) {
+ RETURN_DOUBLE((double)size);
+ } else {
+ RETURN_LONG((long)size);
+ }
}
/* }}} */
@@ -1659,7 +1671,11 @@ PHP_NAMED_FUNCTION(php_if_fstat)
#else
MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
#endif
- MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size);
+ if (stat_ssb.sb.st_size > LONG_MAX) {
+ MAKE_DOUBLE_ZVAL_INCREF(stat_size, (double)stat_ssb.sb.st_size);
+ } else {
+ MAKE_LONG_ZVAL_INCREF(stat_size, (long)stat_ssb.sb.st_size);
+ }
#ifdef NETWARE
MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime.tv_sec);
MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime.tv_sec);
Index: ext/standard/filestat.c
===================================================================
RCS file: /repository/php-src/ext/standard/filestat.c,v
retrieving revision 1.136.2.8.2.14
diff -u -p -r1.136.2.8.2.14 filestat.c
--- ext/standard/filestat.c 21 Sep 2007 14:05:18 -0000 1.136.2.8.2.14
+++ ext/standard/filestat.c 14 Oct 2007 21:54:36 -0000
@@ -858,7 +858,11 @@ PHPAPI void php_stat(const char *filenam
case FS_INODE:
RETURN_LONG((long)ssb.sb.st_ino);
case FS_SIZE:
- RETURN_LONG((long)ssb.sb.st_size);
+ if (ssb.sb.st_size > LONG_MAX) {
+ RETURN_DOUBLE((double)ssb.sb.st_size);
+ } else {
+ RETURN_LONG((long)ssb.sb.st_size);
+ }
case FS_OWNER:
RETURN_LONG((long)ssb.sb.st_uid);
case FS_GROUP:
@@ -927,7 +931,11 @@ PHPAPI void php_stat(const char *filenam
#else
MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
#endif
- MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
+ if (stat_sb->st_size > LONG_MAX) {
+ MAKE_DOUBLE_ZVAL_INCREF(stat_size,
(double)stat_sb->st_size);
+ } else {
+ MAKE_LONG_ZVAL_INCREF(stat_size,
(long)stat_sb->st_size);
+ }
#ifdef NETWARE
MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec);
MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec);
Index: ext/standard/php_filestat.h
===================================================================
RCS file: /repository/php-src/ext/standard/php_filestat.h,v
retrieving revision 1.24.2.4.2.1.2.1
diff -u -p -r1.24.2.4.2.1.2.1 php_filestat.h
--- ext/standard/php_filestat.h 7 Oct 2007 05:22:07 -0000 1.24.2.4.2.1.2.1
+++ ext/standard/php_filestat.h 14 Oct 2007 21:54:36 -0000
@@ -64,6 +64,12 @@ PHP_FUNCTION(clearstatcache);
ZVAL_LONG(name, val); \
Z_ADDREF_P(name);
+#define MAKE_DOUBLE_ZVAL_INCREF(name, val)\
+ MAKE_STD_ZVAL(name); \
+ ZVAL_DOUBLE(name, val); \
+ Z_ADDREF_P(name);
+
+
#ifdef PHP_WIN32
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
Index: ext/standard/streamsfuncs.c
===================================================================
RCS file: /repository/php-src/ext/standard/streamsfuncs.c,v
retrieving revision 1.58.2.6.2.15.2.4
diff -u -p -r1.58.2.6.2.15.2.4 streamsfuncs.c
--- ext/standard/streamsfuncs.c 10 Oct 2007 12:58:41 -0000
1.58.2.6.2.15.2.4
+++ ext/standard/streamsfuncs.c 14 Oct 2007 21:54:38 -0000
@@ -389,7 +389,7 @@ PHP_FUNCTION(stream_socket_recvfrom)
}
/* }}} */
-/* {{{ proto long stream_get_contents(resource source [, long maxlen [, long
offset]])
+/* {{{ proto string stream_get_contents(resource source [, long maxlen [, long
offset]])
Reads all remaining bytes (or up to maxlen bytes) from a stream and returns
them as a string. */
PHP_FUNCTION(stream_get_contents)
{
@@ -433,6 +433,7 @@ PHP_FUNCTION(stream_copy_to_stream)
php_stream *src, *dest;
zval *zsrc, *zdest;
long maxlen = PHP_STREAM_COPY_ALL, pos = 0;
+ size_t copied;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|ll", &zsrc,
&zdest, &maxlen, &pos) == FAILURE) {
RETURN_FALSE;
@@ -446,7 +447,12 @@ PHP_FUNCTION(stream_copy_to_stream)
RETURN_FALSE;
}
- RETURN_LONG(php_stream_copy_to_stream(src, dest, maxlen));
+ copied = php_stream_copy_to_stream(src, dest, maxlen);
+ if (copied > LONG_MAX) {
+ RETURN_DOUBLE((double)copied);
+ } else {
+ RETURN_LONG(copied);
+ }
}
/* }}} */
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php