Skip to content

Commit 020fdfd

Browse files
committed
Fixed bug #75525 Access Violation in vcruntime140.dll
It was a mistake to make d_name a pointer. d_name has to be allocated in the body of struct dirent as per POSIX.1-2008. The binary compatibility is kept through the extra padding, which will be removed in 7.3.
1 parent 235d33a commit 020fdfd

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

win32/readdir.c

+5-9
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ DIR *opendir(const char *dir)
3737
return NULL;
3838
}
3939

40-
dp = (DIR *) calloc(1, sizeof(DIR));
40+
dp = (DIR *) calloc(1, sizeof(DIR) + MAXPATHLEN*sizeof(char));
4141
if (dp == NULL) {
4242
return NULL;
4343
}
@@ -104,9 +104,8 @@ struct dirent *readdir(DIR *dp)
104104
/* wide to utf8 failed, should never happen. */
105105
return NULL;
106106
}
107-
if (dp->dent.d_name)
108-
free(dp->dent.d_name);
109-
dp->dent.d_name = _tmp;
107+
memmove(dp->dent.d_name, _tmp, reclen + 1);
108+
free(_tmp);
110109
dp->dent.d_reclen = (unsigned short)reclen;
111110

112111
dp->offset++;
@@ -141,9 +140,8 @@ int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
141140
result = NULL;
142141
return 0;
143142
}
144-
if (dp->dent.d_name)
145-
free(dp->dent.d_name);
146-
dp->dent.d_name = _tmp;
143+
memmove(dp->dent.d_name, _tmp, reclen + 1);
144+
free(_tmp);
147145
dp->dent.d_reclen = (unsigned short)reclen;
148146

149147
dp->offset++;
@@ -169,8 +167,6 @@ int closedir(DIR *dp)
169167
}
170168
if (dp->dirw)
171169
free(dp->dirw);
172-
if (dp->dent.d_name)
173-
free(dp->dent.d_name);
174170
if (dp)
175171
free(dp);
176172

win32/readdir.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ struct dirent {
2222
long d_ino; /* inode (always 1 in WIN32) */
2323
off_t d_off; /* offset to this dirent */
2424
unsigned short d_reclen; /* length of d_name */
25-
char *d_name; /* null terminated filename in the current encoding, glyph number <= 255 wchar_t's + \0 byte */
25+
unsigned short pad0;
26+
#if defined(_WIN64)
27+
uint32_t pad1;
28+
#endif
29+
char d_name[1]; /* null terminated filename in the current encoding, glyph number <= 255 wchar_t's + \0 byte */
2630
};
2731

2832
/* typedef DIR - not the same as Unix */

0 commit comments

Comments
 (0)