Skip to content

Commit a7f7022

Browse files
committed
Avoid copying the stat buffer on a cache hit
Closes GH-11628.
1 parent e85fb09 commit a7f7022

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

ext/standard/filestat.c

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,8 @@ PHP_FUNCTION(clearstatcache)
706706
/* {{{ php_stat */
707707
PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
708708
{
709-
zend_stat_t *stat_sb = {0};
710709
php_stream_statbuf ssb = {0};
710+
zend_stat_t *stat_sb = &ssb.sb;
711711
int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
712712
const char *local = NULL;
713713
php_stream_wrapper *wrapper = NULL;
@@ -765,14 +765,14 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
765765
if (filename == BG(CurrentLStatFile)
766766
|| (BG(CurrentLStatFile)
767767
&& zend_string_equal_content(filename, BG(CurrentLStatFile)))) {
768-
memcpy(&ssb, &BG(lssb), sizeof(php_stream_statbuf));
768+
stat_sb = &BG(lssb).sb;
769769
break;
770770
}
771771
} else {
772772
if (filename == BG(CurrentStatFile)
773773
|| (BG(CurrentStatFile)
774774
&& zend_string_equal_content(filename, BG(CurrentStatFile)))) {
775-
memcpy(&ssb, &BG(ssb), sizeof(php_stream_statbuf));
775+
stat_sb = &BG(ssb).sb;
776776
break;
777777
}
778778
}
@@ -819,14 +819,12 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
819819
}
820820
} while (0);
821821

822-
stat_sb = &ssb.sb;
823-
824822
if (type >= FS_IS_W && type <= FS_IS_X) {
825-
if(ssb.sb.st_uid==getuid()) {
823+
if(stat_sb->st_uid==getuid()) {
826824
rmask=S_IRUSR;
827825
wmask=S_IWUSR;
828826
xmask=S_IXUSR;
829-
} else if(ssb.sb.st_gid==getgid()) {
827+
} else if(stat_sb->st_gid==getgid()) {
830828
rmask=S_IRGRP;
831829
wmask=S_IWGRP;
832830
xmask=S_IXGRP;
@@ -839,7 +837,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
839837
gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
840838
n=getgroups(groups, gids);
841839
for(i=0;i<n;i++){
842-
if(ssb.sb.st_gid==gids[i]) {
840+
if(stat_sb->st_gid==gids[i]) {
843841
rmask=S_IRGRP;
844842
wmask=S_IWGRP;
845843
xmask=S_IXGRP;
@@ -865,26 +863,26 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
865863
switch (type) {
866864
case FS_PERMS:
867865
case FS_LPERMS:
868-
RETURN_LONG((zend_long)ssb.sb.st_mode);
866+
RETURN_LONG((zend_long)stat_sb->st_mode);
869867
case FS_INODE:
870-
RETURN_LONG((zend_long)ssb.sb.st_ino);
868+
RETURN_LONG((zend_long)stat_sb->st_ino);
871869
case FS_SIZE:
872-
RETURN_LONG((zend_long)ssb.sb.st_size);
870+
RETURN_LONG((zend_long)stat_sb->st_size);
873871
case FS_OWNER:
874-
RETURN_LONG((zend_long)ssb.sb.st_uid);
872+
RETURN_LONG((zend_long)stat_sb->st_uid);
875873
case FS_GROUP:
876-
RETURN_LONG((zend_long)ssb.sb.st_gid);
874+
RETURN_LONG((zend_long)stat_sb->st_gid);
877875
case FS_ATIME:
878-
RETURN_LONG((zend_long)ssb.sb.st_atime);
876+
RETURN_LONG((zend_long)stat_sb->st_atime);
879877
case FS_MTIME:
880-
RETURN_LONG((zend_long)ssb.sb.st_mtime);
878+
RETURN_LONG((zend_long)stat_sb->st_mtime);
881879
case FS_CTIME:
882-
RETURN_LONG((zend_long)ssb.sb.st_ctime);
880+
RETURN_LONG((zend_long)stat_sb->st_ctime);
883881
case FS_TYPE:
884-
if (S_ISLNK(ssb.sb.st_mode)) {
882+
if (S_ISLNK(stat_sb->st_mode)) {
885883
RETURN_STRING("link");
886884
}
887-
switch(ssb.sb.st_mode & S_IFMT) {
885+
switch(stat_sb->st_mode & S_IFMT) {
888886
case S_IFIFO: RETURN_STRING("fifo");
889887
case S_IFCHR: RETURN_STRING("char");
890888
case S_IFDIR: RETURN_STRING("dir");
@@ -894,20 +892,20 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
894892
case S_IFSOCK: RETURN_STRING("socket");
895893
#endif
896894
}
897-
php_error_docref(NULL, E_NOTICE, "Unknown file type (%d)", ssb.sb.st_mode&S_IFMT);
895+
php_error_docref(NULL, E_NOTICE, "Unknown file type (%d)", stat_sb->st_mode&S_IFMT);
898896
RETURN_STRING("unknown");
899897
case FS_IS_W:
900-
RETURN_BOOL((ssb.sb.st_mode & wmask) != 0);
898+
RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
901899
case FS_IS_R:
902-
RETURN_BOOL((ssb.sb.st_mode&rmask)!=0);
900+
RETURN_BOOL((stat_sb->st_mode & rmask) != 0);
903901
case FS_IS_X:
904-
RETURN_BOOL((ssb.sb.st_mode&xmask)!=0);
902+
RETURN_BOOL((stat_sb->st_mode & xmask) != 0);
905903
case FS_IS_FILE:
906-
RETURN_BOOL(S_ISREG(ssb.sb.st_mode));
904+
RETURN_BOOL(S_ISREG(stat_sb->st_mode));
907905
case FS_IS_DIR:
908-
RETURN_BOOL(S_ISDIR(ssb.sb.st_mode));
906+
RETURN_BOOL(S_ISDIR(stat_sb->st_mode));
909907
case FS_IS_LINK:
910-
RETURN_BOOL(S_ISLNK(ssb.sb.st_mode));
908+
RETURN_BOOL(S_ISLNK(stat_sb->st_mode));
911909
case FS_EXISTS:
912910
RETURN_TRUE; /* the false case was done earlier */
913911
case FS_LSTAT:

0 commit comments

Comments
 (0)