|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2018-03-17 06:45 UTC] VeryCrazyDog at gmail dot com
Description:
------------
When calling SplFileInfo::isFile() on a large file, false is returned instead of true.
When calling SplFileInfo::getMTime() and SplFileInfo::getSize() on a large file, RuntimeException is throw.
This problem does not happens on Windows 7 64bit running same PHP version. It seems that it is related the maximum value of int, because the file size which I used in the test is "2939977728" which cannot be fit in 32bit OS.
Although it may not be possible to report the file size, it is expected at least, isFile() and getMTime() should return the correct result.
Test script:
---------------
<?php
$info = new SplFileInfo('/path/to/large_file');
var_dump($info);
var_dump($info->isFile()); // This returns false
var_dump($info->isReadable());
var_dump($info->getMTime()); // This throws RuntimeException
var_dump($info->getSize()); // This throws RuntimeException
if ($info->isFile()) {
echo $info->getRealPath();
}
Expected result:
----------------
vcd@server ~$ php -f test.php
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(24) "/home/vcd/tmp/large_file"
["fileName":"SplFileInfo":private]=>
string(10) "large_file"
}
bool(true)
bool(true)
int(1515414305)
bool(false)
/home/vcd/tmp/large_file
Actual result:
--------------
vcd@server ~$ php -f test.php
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(24) "/home/vcd/tmp/large_file"
["fileName":"SplFileInfo":private]=>
string(10) "large_file"
}
bool(false)
bool(true)
PHP Fatal error: Uncaught RuntimeException: SplFileInfo::getMTime(): stat failed for /home/vcd/tmp/large_file in /home/vcd/test.php:6
Stack trace:
#0 /home/vcd/test.php(6): SplFileInfo->getMTime()
#1 {main}
thrown in /home/vcd/test.php on line 6
Patchesfronk-support (last revision 2024-06-09 09:35 UTC by hai9669082999 at gmail dot com)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 22:00:01 2025 UTC |
I tried to run the following C program, but no error occurred, maybe the error is throw somewhere else? --------------- #include <stdio.h> #include <stdint.h> typedef int32_t zend_long; int main (void) { zend_long l = 2147483647; // Print: long: 2147483647 printf("long: %d\n", l); l++; // Print: long: -2147483648 printf("long: %d\n", l); long long int ll = 2721514410; // Print: long long: 2721514410 printf("long long: %lld\n", ll); l = (zend_long)ll; // Print: long: -1573452886 printf("long: %d\n", l); return 0; } --------------- I am now running PHP 7.4.3 and the same result and same error occurred. Besides a more descriptive error message, is that possible to give correct output when isFile() and getMTime() are called?You can try something like the following (untested): #include <stdio.h> #include <sys/stat.h> int main() { struct stat ssb; int res = stat("/path/to/large/file", &ssb); printf("result: %d, errno: %d, EOVERFLOW: %d", res, errno, EOVERFLOW); return 0; } I assume that will show that errno is EOVERFLOW. Anyhow, I don't think we can really fix this, since the stat() call is important, and if it fails there's not much we can do, besides giving a better error message.I tested using your source code, indeed yes, EOVERFLOW returned without result. Agreed that nothing can be done here. Shall I close this bug or shall I leave it open for improving the error message? A side question, since "stat" Linux command works, there should have a way to get the file info (such as modified date), but I can imagine the change will be huge which may not be justify to do, right? Output: ------------ result: -1, errno: 75, EOVERFLOW: 75 File type: regular file I-node number: 1697634 Mode: 100644 (octal) Link count: 1 Ownership: UID=1000 GID=100 Preferred I/O block size: 0 bytes File size: -1573452886 bytes Blocks allocated: 0 Last status change: Thu Jan 1 08:00:00 1970 Last file access: Thu Jan 1 08:00:00 1970 Last file modification: Thu Jan 1 08:00:00 1970 ------------ Source code: ------------ #include <stdio.h> #include <sys/stat.h> #include <errno.h> #include <time.h> int main() { struct stat sb = {0}; int res = stat("/home/vcd/tmp/LARGE_FILE", &sb); printf("result: %d, errno: %d, EOVERFLOW: %d\n\n", res, errno, EOVERFLOW); printf("File type: "); switch (sb.st_mode & S_IFMT) { case S_IFBLK: printf("block device\n"); break; case S_IFCHR: printf("character device\n"); break; case S_IFDIR: printf("directory\n"); break; case S_IFIFO: printf("FIFO/pipe\n"); break; case S_IFLNK: printf("symlink\n"); break; case S_IFREG: printf("regular file\n"); break; case S_IFSOCK: printf("socket\n"); break; default: printf("unknown?\n"); break; } printf("I-node number: %ld\n", (long) sb.st_ino); printf("Mode: %lo (octal)\n", (unsigned long) sb.st_mode); printf("Link count: %ld\n", (long) sb.st_nlink); printf("Ownership: UID=%ld GID=%ld\n", (long) sb.st_uid, (long) sb.st_gid); printf("Preferred I/O block size: %ld bytes\n", (long) sb.st_blksize); printf("File size: %lld bytes\n", (long long) sb.st_size); printf("Blocks allocated: %lld\n", (long long) sb.st_blocks); printf("Last status change: %s", ctime(&sb.st_ctime)); printf("Last file access: %s", ctime(&sb.st_atime)); printf("Last file modification: %s", ctime(&sb.st_mtime)); return 0; } ------------