diff options
author | Anatol Belski <ab@php.net> | 2017-02-12 22:13:21 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2017-02-12 22:23:51 +0100 |
commit | 0d529d6eb323d425615050dae97584e5fad14b30 (patch) | |
tree | 7a9c3a850a4829f1df646b9f2cb65e470e566db5 | |
parent | e637cd82a01747dd47733e873c9423e9903ea170 (diff) | |
download | php-git-0d529d6eb323d425615050dae97584e5fad14b30.tar.gz |
The d_name member of struct dirent should be a pointer
Rework for 60950702, so then any encoding is supported. The path
segment length is measured in wchar_t size, whereby the number
of wchar_t is 255+\0. This means, in the actual encoding, the path
segment size can become (255*<bytes per glyph>)+\0 bytes in worst
case. It is still valid, as all the FS API uses wide chars
internally.
-rw-r--r-- | win32/readdir.c | 24 | ||||
-rw-r--r-- | win32/readdir.h | 2 |
2 files changed, 16 insertions, 10 deletions
diff --git a/win32/readdir.c b/win32/readdir.c index 42b528ad0a..1031fe2ac2 100644 --- a/win32/readdir.c +++ b/win32/readdir.c @@ -37,7 +37,7 @@ DIR *opendir(const char *dir) return NULL; } - dp = (DIR *) malloc(sizeof(DIR)); + dp = (DIR *) calloc(1, sizeof(DIR)); if (dp == NULL) { return NULL; } @@ -87,6 +87,7 @@ DIR *opendir(const char *dir) struct dirent *readdir(DIR *dp) { char *_tmp; + size_t reclen; if (!dp || dp->finished) return NULL; @@ -98,14 +99,15 @@ struct dirent *readdir(DIR *dp) } } - _tmp = php_win32_ioutil_w_to_any(dp->fileinfo.cFileName); + _tmp = php_win32_cp_conv_w_to_any(dp->fileinfo.cFileName, PHP_WIN32_CP_IGNORE_LEN, &reclen); if (!_tmp) { /* wide to utf8 failed, should never happen. */ return NULL; } - strlcpy(dp->dent.d_name, _tmp, _MAX_FNAME*4+1); - dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name); - free(_tmp); + if (dp->dent.d_name) + free(dp->dent.d_name); + dp->dent.d_name = _tmp; + dp->dent.d_reclen = (unsigned short)reclen; dp->offset++; @@ -118,6 +120,7 @@ struct dirent *readdir(DIR *dp) int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result) { char *_tmp; + size_t reclen; if (!dp || dp->finished) { *result = NULL; @@ -132,15 +135,16 @@ int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result) } } - _tmp = php_win32_ioutil_w_to_any(dp->fileinfo.cFileName); + _tmp = php_win32_cp_conv_w_to_any(dp->fileinfo.cFileName, PHP_WIN32_CP_IGNORE_LEN, &reclen); if (!_tmp) { /* wide to utf8 failed, should never happen. */ result = NULL; return 0; } - strlcpy(dp->dent.d_name, _tmp, _MAX_FNAME*4+1); - dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name); - free(_tmp); + if (dp->dent.d_name) + free(dp->dent.d_name); + dp->dent.d_name = _tmp; + dp->dent.d_reclen = (unsigned short)reclen; dp->offset++; @@ -165,6 +169,8 @@ int closedir(DIR *dp) } if (dp->dirw) free(dp->dirw); + if (dp->dent.d_name) + free(dp->dent.d_name); if (dp) free(dp); diff --git a/win32/readdir.h b/win32/readdir.h index 495c36a1a9..aa485fb7f3 100644 --- a/win32/readdir.h +++ b/win32/readdir.h @@ -22,7 +22,7 @@ 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*4+1]; /* filename with care about UTF-8 (null terminated) */ + char *d_name; /* null terminated filename in the current encoding, glyph number <= 255 wchar_t's + \0 byte */ }; /* typedef DIR - not the same as Unix */ |