]> granicus.if.org Git - php/commitdiff
Path handling related refactorings
authorAnatol Belski <ab@php.net>
Thu, 22 Dec 2016 13:56:47 +0000 (14:56 +0100)
committerAnatol Belski <ab@php.net>
Thu, 22 Dec 2016 13:56:47 +0000 (14:56 +0100)
Primarily related to the path handling datatypes, to avoid unnecessary
casts, where possible. Also some rework to avoid code dup. Probably
more places are to go, even not path related, primarily to have less
casts and unsigned integers where possible. That way, we've not only
less warnings and casts, but are also safer with regard to the
integer overflows. OFC it's not a panacea, but still significantly
reduces the vulnerability potential.

13 files changed:
TSRM/readdir.h
TSRM/tsrm_win32.c
UPGRADING.INTERNALS
Zend/zend_virtual_cwd.c
Zend/zend_virtual_cwd.h
ext/phar/func_interceptors.c
ext/phar/phar_object.c
ext/standard/dir.c
ext/standard/filestat.c
ext/standard/php_filestat.h
sapi/cli/php_cli.c
win32/readdir.c
win32/readdir.h

index 0665810c854359ce5d476bdbc6076e6eba014839..11c0f31ea123a468560f67593d9ae68cff1360ca 100644 (file)
@@ -1,45 +1,3 @@
-#ifndef READDIR_H
-#define READDIR_H
-
-
-/*
- * Structures and types used to implement opendir/readdir/closedir
- * on Windows 95/NT.
- */
-
-#include <windows.h>
-
-#include <io.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <direct.h>
-
-/* struct dirent - same as Unix */
-
-struct dirent {
-       long d_ino;                                     /* inode (always 1 in WIN32) */
-       off_t d_off;                            /* offset to this dirent */
-       unsigned short d_reclen;        /* length of d_name */
-       char d_name[_MAX_FNAME + 1];    /* filename (null terminated) */
-};
-
-
-/* typedef DIR - not the same as Unix */
-typedef struct {
-       HANDLE handle;                          /* _findfirst/_findnext handle */
-       short offset;                           /* offset into directory */
-       short finished;                         /* 1 if there are not more files */
-       WIN32_FIND_DATA fileinfo;       /* from _findfirst/_findnext */
-       char *dir;                                      /* the dir we are reading */
-       struct dirent dent;                     /* the dirent to return */
-} DIR;
-
-/* Function prototypes */
-DIR *opendir(const char *);
-struct dirent *readdir(DIR *);
-int readdir_r(DIR *, struct dirent *, struct dirent **);
-int closedir(DIR *);
-int rewinddir(DIR *);
-
-#endif /* READDIR_H */
+/* Keep this header for compatibility with external code, it's currently not
+       used anywhere in the core and there are no implementations in TSRM. */
+#include "win32/readdir.h"
index 7fa38198de92e469fa83a32ddeede7315d1dc699..ac9d66778895f965f849dbc45fd67b33abbe89b3 100644 (file)
@@ -296,14 +296,14 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
 
                if (CWDG(realpath_cache_size_limit)) {
                        t = time(0);
-                       bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
+                       bucket = realpath_cache_lookup(pathname, strlen(pathname), t);
                        if(bucket == NULL && real_path == NULL) {
                                /* We used the pathname directly. Call tsrm_realpath */
                                /* so that entry is created in realpath cache */
                                real_path = (char *)malloc(MAXPATHLEN);
                                if(tsrm_realpath(pathname, real_path) != NULL) {
                                        pathname = real_path;
-                                       bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
+                                       bucket = realpath_cache_lookup(pathname, strlen(pathname), t);
                                        PHP_WIN32_IOUTIL_REINIT_W(pathname);
                                }
                        }
index 95e9318b256b76bfd3eb21eaf454a4fe60e5e7ea..a9f1547245d9735aee39bb45c2eef1a684985007 100644 (file)
@@ -13,7 +13,12 @@ PHP 7.1 INTERNALS UPGRADE NOTES
 1. Internal API changes
 ========================
 
-  a.
+  a. Path related functions
+    - CWD_API void realpath_cache_del(const char *path, size_t path_len);
+    - CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, size_t path_len, time_t t);
+    - PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, size_t filename_len);
+    - PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zval *return_value);
+
 
 ========================
 2. Build system changes
index 420bc54a7b366a39d947b36b20159178f9e96cab..02f38342737538271211f723153543a10125ccf5 100644 (file)
@@ -537,7 +537,7 @@ CWD_API char *virtual_getcwd(char *buf, size_t size) /* {{{ */
 /* }}} */
 
 #ifdef ZEND_WIN32
-static inline zend_ulong realpath_cache_key(const char *path, int path_len) /* {{{ */
+static inline zend_ulong realpath_cache_key(const char *path, size_t path_len) /* {{{ */
 {
        register zend_ulong h;
        char *bucket_key_start = tsrm_win32_get_path_sid_key(path);
@@ -558,7 +558,7 @@ static inline zend_ulong realpath_cache_key(const char *path, int path_len) /* {
 }
 /* }}} */
 #else
-static inline zend_ulong realpath_cache_key(const char *path, int path_len) /* {{{ */
+static inline zend_ulong realpath_cache_key(const char *path, size_t path_len) /* {{{ */
 {
        register zend_ulong h;
        const char *e = path + path_len;
@@ -590,7 +590,7 @@ CWD_API void realpath_cache_clean(void) /* {{{ */
 }
 /* }}} */
 
-CWD_API void realpath_cache_del(const char *path, int path_len) /* {{{ */
+CWD_API void realpath_cache_del(const char *path, size_t path_len) /* {{{ */
 {
        zend_ulong key = realpath_cache_key(path, path_len);
        zend_ulong n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
@@ -618,7 +618,7 @@ CWD_API void realpath_cache_del(const char *path, int path_len) /* {{{ */
 }
 /* }}} */
 
-static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, int realpath_len, int is_dir, time_t t) /* {{{ */
+static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, size_t realpath_len, int is_dir, time_t t) /* {{{ */
 {
        zend_long size = sizeof(realpath_cache_bucket) + path_len + 1;
        int same = 1;
@@ -664,7 +664,7 @@ static inline void realpath_cache_add(const char *path, int path_len, const char
 }
 /* }}} */
 
-static inline realpath_cache_bucket* realpath_cache_find(const char *path, int path_len, time_t t) /* {{{ */
+static inline realpath_cache_bucket* realpath_cache_find(const char *path, size_t path_len, time_t t) /* {{{ */
 {
        zend_ulong key = realpath_cache_key(path, path_len);
        zend_ulong n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
@@ -693,7 +693,7 @@ static inline realpath_cache_bucket* realpath_cache_find(const char *path, int p
 }
 /* }}} */
 
-CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_len, time_t t) /* {{{ */
+CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, size_t path_len, time_t t) /* {{{ */
 {
        return realpath_cache_find(path, path_len, t);
 }
index 970e65e0b79f7464a83032fdd3c86a7b1d1efe2f..74e9f569fd6f15cfce353b0458c8a0b009b49cd2 100644 (file)
@@ -232,8 +232,8 @@ extern virtual_cwd_globals cwd_globals;
 #endif
 
 CWD_API void realpath_cache_clean(void);
-CWD_API void realpath_cache_del(const char *path, int path_len);
-CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_len, time_t t);
+CWD_API void realpath_cache_del(const char *path, size_t path_len);
+CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, size_t path_len, time_t t);
 CWD_API zend_long realpath_cache_size(void);
 CWD_API zend_long realpath_cache_max_buckets(void);
 CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void);
index 05bcbf9c3672137f810998c5b406d480686649c5..3e78fa1f869649e6ecac6ce9088f78d9418b5cae 100644 (file)
@@ -585,7 +585,7 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value)
 }
 /* }}} */
 
-static void phar_file_stat(const char *filename, php_stat_len filename_length, int type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
+static void phar_file_stat(const char *filename, size_t filename_length, int type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
 {
        if (!filename_length) {
                RETURN_FALSE;
@@ -770,7 +770,7 @@ void fname(INTERNAL_FUNCTION_PARAMETERS) { \
                        return; \
                } \
                \
-               phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \
+               phar_file_stat(filename, filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \
        } \
 }
 /* }}} */
index 457d6e593d49d233d3c8ecaab1ab0c4167ecc931..8af3869d9af8eac0657e9fa3344f900b66b43fca 100644 (file)
@@ -1423,7 +1423,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
        uint32_t str_key_len, base_len = p_obj->l;
        phar_entry_data *data;
        php_stream *fp;
-       php_stat_len fname_len;
+       size_t fname_len;
        size_t contents_len;
        char *fname, *error = NULL, *base = p_obj->b, *save = NULL, *temp = NULL;
        zend_string *opened;
@@ -1501,7 +1501,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
                                switch (intern->type) {
                                        case SPL_FS_DIR:
                                                test = spl_filesystem_object_get_path(intern, NULL);
-                                               fname_len = (php_stat_len)spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name);
+                                               fname_len = spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name);
                                                php_stat(fname, fname_len, FS_IS_DIR, &dummy);
 
                                                if (Z_TYPE(dummy) == IS_TRUE) {
@@ -1515,7 +1515,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
 
                                                if (test) {
                                                        fname = test;
-                                                       fname_len = (php_stat_len)strlen(fname);
+                                                       fname_len = strlen(fname);
                                                } else {
                                                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Could not resolve file path");
                                                        return ZEND_HASH_APPLY_STOP;
@@ -1531,7 +1531,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
                                                        return ZEND_HASH_APPLY_STOP;
                                                }
 
-                                               fname_len = (php_stat_len)strlen(fname);
+                                               fname_len = strlen(fname);
                                                save = fname;
                                                goto phar_spl_fileinfo;
                                }
@@ -1543,7 +1543,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
        }
 
        fname = Z_STRVAL_P(value);
-       fname_len = (php_stat_len)Z_STRLEN_P(value);
+       fname_len = Z_STRLEN_P(value);
 
 phar_spl_fileinfo:
        if (base_len) {
index de7e01ffea84aac1ce781355e9be766f3f4913df..9e7adfccfb1dacd9423d9c48a39f888435fac589 100644 (file)
@@ -420,7 +420,7 @@ PHP_NAMED_FUNCTION(php_if_readdir)
    Find pathnames matching a pattern */
 PHP_FUNCTION(glob)
 {
-       int cwd_skip = 0;
+       size_t cwd_skip = 0;
 #ifdef ZTS
        char cwd[MAXPATHLEN];
        char work_pattern[MAXPATHLEN];
@@ -459,7 +459,7 @@ PHP_FUNCTION(glob)
                        cwd[2] = '\0';
                }
 #endif
-               cwd_skip = (int)strlen(cwd)+1;
+               cwd_skip = strlen(cwd)+1;
 
                snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
                pattern = work_pattern;
index 370805a27e7eb80a4b916f2a00e6bebe5362e47f..47e7d63738e53d417287ebeaf401c0fea91fd1a5 100644 (file)
@@ -705,7 +705,7 @@ PHP_FUNCTION(touch)
 
 /* {{{ php_clear_stat_cache()
 */
-PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len)
+PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, size_t filename_len)
 {
        /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
         * as it may contain outdated data (e.g. "nlink" for a directory when deleting a file
@@ -740,7 +740,7 @@ PHP_FUNCTION(clearstatcache)
                return;
        }
 
-       php_clear_stat_cache(clear_realpath_cache, filename, (int)filename_len);
+       php_clear_stat_cache(clear_realpath_cache, filename, filename_len);
 }
 /* }}} */
 
@@ -751,7 +751,7 @@ PHP_FUNCTION(clearstatcache)
 
 /* {{{ php_stat
  */
-PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value)
+PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zval *return_value)
 {
        zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev,
                 stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks;
@@ -996,7 +996,7 @@ void name(INTERNAL_FUNCTION_PARAMETERS) { \
                Z_PARAM_PATH(filename, filename_len) \
        ZEND_PARSE_PARAMETERS_END(); \
        \
-       php_stat(filename, (php_stat_len) filename_len, funcnum, return_value); \
+       php_stat(filename, filename_len, funcnum, return_value); \
 }
 /* }}} */
 
index 2e87d96f058a6a4f4668c532c1879419f14319cb..5e141ca3e4fff71f6cd646ca8ac185974ada9750 100644 (file)
@@ -78,14 +78,11 @@ PHP_FUNCTION(clearstatcache);
 #define getuid() 1
 #endif
 
-#ifdef PHP_WIN32
-typedef unsigned int php_stat_len;
-#else
-typedef int php_stat_len;
-#endif
+/* Compatibility. */
+typedef size_t php_stat_len;
 
-PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len);
-PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value);
+PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, size_t filename_len);
+PHPAPI void php_stat(const char *filename, size_t filename_length, int type, zval *return_value);
 
 /* Switches for various filestat functions: */
 #define FS_PERMS    0
index 65a0a6350567d3651d2c2952c9d911856db987e8..b5fa6ea989fd7fb088ff29f7278b2eb9bac9aa25 100644 (file)
@@ -1126,7 +1126,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                }
                        case PHP_MODE_REFLECTION_EXT_INFO:
                                {
-                                       int len = (int)strlen(reflection_what);
+                                       size_t len = strlen(reflection_what);
                                        char *lcname = zend_str_tolower_dup(reflection_what, len);
                                        zend_module_entry *module;
 
@@ -1202,7 +1202,7 @@ int main(int argc, char *argv[])
        int php_optind = 1, use_extended_info = 0;
        char *ini_path_override = NULL;
        char *ini_entries = NULL;
-       int ini_entries_len = 0;
+       size_t ini_entries_len = 0;
        int ini_ignore = 0;
        sapi_module_struct *sapi_module = &cli_sapi_module;
 
@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[])
                                break;
                        case 'd': {
                                /* define ini entries on command line */
-                               int len = (int)strlen(php_optarg);
+                               size_t len = strlen(php_optarg);
                                char *val;
 
                                if ((val = strchr(php_optarg, '='))) {
@@ -1284,11 +1284,11 @@ int main(int argc, char *argv[])
                                        if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
                                                ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
                                                memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
-                                               ini_entries_len += (int)(val - php_optarg);
+                                               ini_entries_len += (val - php_optarg);
                                                memcpy(ini_entries + ini_entries_len, "\"", 1);
                                                ini_entries_len++;
                                                memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg));
-                                               ini_entries_len += len - (int)(val - php_optarg);
+                                               ini_entries_len += len - (val - php_optarg);
                                                memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
                                                ini_entries_len += sizeof("\n\0\"") - 2;
                                        } else {
index 4a6d65932f6765173501b51e799896639a9e1c4f..43d5deecfd7fa088533a3663529a59102ec667d5 100644 (file)
 extern "C" {
 #endif
 
-/* typedef DIR - not the same as Unix */
-struct DIR_W32 {
-       HANDLE handle;                          /* _findfirst/_findnext handle */
-       int offset;                                     /* offset into directory */
-       short finished;                         /* 1 if there are not more files */
-       WIN32_FIND_DATAW fileinfo;  /* from _findfirst/_findnext */
-       wchar_t *dirw;          /* the dir we are reading */
-       struct dirent dent;                     /* the dirent to return */
-};
-
 DIR *opendir(const char *dir)
 {
        DIR *dp;
index 4158ffc84a680946137094b674f6253dafbc9dcc..73058f88042d0cad0d2d104246164d834cfa5a50 100644 (file)
@@ -8,25 +8,32 @@ extern "C" {
 
 /*
  * Structures and types used to implement opendir/readdir/closedir
- * on Windows 95/NT.
+ * on Windows.
  */
 
 #include <config.w32.h>
 
-#include <stdlib.h>
-#include <sys/types.h>
+#include "ioutil.h"
 
 #define php_readdir_r readdir_r
 
 /* struct dirent - same as Unix */
 struct dirent {
        long d_ino;                                     /* inode (always 1 in WIN32) */
-       off_t d_off;                            /* offset to this dirent */
-       unsigned short d_reclen;        /* length of d_name */
-       char d_name[_MAX_FNAME + 1];    /* filename (null terminated) */
+       off_t d_off;                                    /* offset to this dirent */
+       unsigned short d_reclen;                        /* length of d_name */
+       char d_name[PHP_WIN32_IOUTIL_MAXPATHLEN + 1];   /* filename (null terminated) */
 };
 
 /* typedef DIR - not the same as Unix */
+struct DIR_W32 {
+       HANDLE handle;                  /* _findfirst/_findnext handle */
+       uint16_t offset;                /* offset into directory */
+       uint8_t finished;               /* 1 if there are not more files */
+       WIN32_FIND_DATAW fileinfo;      /* from _findfirst/_findnext */
+       wchar_t *dirw;                  /* the dir we are reading */
+       struct dirent dent;             /* the dirent to return */
+};
 typedef struct DIR_W32 DIR;
 
 /* Function prototypes */