@@ -32,21 +32,26 @@ static_assert(DT_UNKNOWN == __WASI_FILETYPE_UNKNOWN, "Value mismatch");
3232#endif
3333
3434// Grows a buffer to be large enough to hold a certain amount of data.
35- #define GROW (buffer , buffer_size , target_size ) \
36- do { \
37- if ((buffer_size) < (target_size)) { \
38- size_t new_size = (buffer_size); \
39- while (new_size < (target_size)) \
40- new_size *= 2; \
41- void *new_buffer = realloc(buffer, new_size); \
42- if (new_buffer == NULL) { \
43- errno = ENOMEM; \
44- return NULL; \
45- } \
46- (buffer) = new_buffer; \
47- (buffer_size) = new_size; \
48- } \
49- } while (0)
35+ #ifdef __wasip1__
36+ typedef void * buffer_t ;
37+ #else
38+ typedef struct dirent * buffer_t ;
39+ #endif
40+ static buffer_t grow (buffer_t * buffer , size_t * buffer_size , size_t target_size ) {
41+ if (* buffer_size < target_size ) {
42+ size_t new_size = * buffer_size ;
43+ while (new_size < target_size )
44+ new_size *= 2 ;
45+ void * new_buffer = realloc (* buffer , new_size );
46+ if (new_buffer == NULL ) {
47+ errno = ENOMEM ;
48+ return NULL ;
49+ }
50+ * buffer = new_buffer ;
51+ * buffer_size = new_size ;
52+ }
53+ return * buffer ;
54+ }
5055
5156#if defined(__wasip1__ )
5257struct dirent * readdir (DIR * dirp ) {
@@ -73,7 +78,8 @@ struct dirent *readdir(DIR *dirp) {
7378 // the entry another time. Ensure that the read buffer is large
7479 // enough to fit at least this single entry.
7580 if (buffer_left < entry_size ) {
76- GROW (dirp -> buffer , dirp -> buffer_size , entry_size );
81+ if (grow (& dirp -> buffer , & dirp -> buffer_size , entry_size ) == NULL )
82+ return NULL ;
7783 goto read_entries ;
7884 }
7985
@@ -86,8 +92,9 @@ struct dirent *readdir(DIR *dirp) {
8692
8793 // Return the next directory entry. Ensure that the dirent is large
8894 // enough to fit the filename.
89- GROW (dirp -> dirent , dirp -> dirent_size ,
90- offsetof(struct dirent , d_name ) + entry .d_namlen + 1 );
95+ if (grow (& dirp -> dirent , & dirp -> dirent_size ,
96+ offsetof(struct dirent , d_name ) + entry .d_namlen + 1 ))
97+ return NULL ;
9198 struct dirent * dirent = dirp -> dirent ;
9299 dirent -> d_type = entry .d_type ;
93100 memcpy (dirent -> d_name , name , entry .d_namlen );
@@ -172,7 +179,8 @@ static struct dirent *readdir_next(DIR *dirp) {
172179 // hash of the directory itself.
173180 if (dirp -> offset == 0 ) {
174181 dirp -> offset += 1 ;
175- GROW (dirp -> dirent , dirp -> dirent_size , offsetof(struct dirent , d_name ) + 2 );
182+ if (grow (& dirp -> dirent , & dirp -> dirent_size , offsetof(struct dirent , d_name ) + 2 ) == NULL )
183+ return NULL ;
176184 bool ok = filesystem_method_descriptor_metadata_hash (dir_handle ,
177185 & metadata ,
178186 & error_code );
@@ -191,7 +199,8 @@ static struct dirent *readdir_next(DIR *dirp) {
191199 // avoid opening the parent directory here.
192200 if (dirp -> offset == 1 ) {
193201 dirp -> offset += 1 ;
194- GROW (dirp -> dirent , dirp -> dirent_size , offsetof(struct dirent , d_name ) + 3 );
202+ if (grow (& dirp -> dirent , & dirp -> dirent_size , offsetof(struct dirent , d_name ) + 3 ) == NULL )
203+ return NULL ;
195204 dirp -> dirent -> d_ino = 0 ;
196205 dirp -> dirent -> d_type = DT_DIR ;
197206 dirp -> dirent -> d_name [0 ] = '.' ;
@@ -218,7 +227,10 @@ static struct dirent *readdir_next(DIR *dirp) {
218227
219228 // Ensure that the dirent is large enough to fit the filename
220229 size_t the_size = offsetof(struct dirent , d_name );
221- GROW (dirp -> dirent , dirp -> dirent_size , the_size + dir_entry .name .len + 1 );
230+ if (grow (& dirp -> dirent , & dirp -> dirent_size , the_size + dir_entry .name .len + 1 ) == NULL ) {
231+ wasip2_string_free (& dir_entry .name );
232+ return NULL ;
233+ }
222234
223235 // Fill out `d_type` and `d_name`
224236 dirp -> dirent -> d_type = dir_entry_type_to_d_type (dir_entry .type );
0 commit comments