summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2017-02-12 22:13:21 +0100
committerAnatol Belski <ab@php.net>2017-02-12 22:23:51 +0100
commit0d529d6eb323d425615050dae97584e5fad14b30 (patch)
tree7a9c3a850a4829f1df646b9f2cb65e470e566db5
parente637cd82a01747dd47733e873c9423e9903ea170 (diff)
downloadphp-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.c24
-rw-r--r--win32/readdir.h2
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 */