@@ -232,10 +232,22 @@ pub fn fd_set_num_elements(set_count: usize, nfds: RawFd) -> usize {
232
232
#[ cfg( any( windows, target_os = "wasi" ) ) ]
233
233
#[ inline]
234
234
pub ( crate ) fn fd_set_num_elements_for_fd_array ( set_count : usize ) -> usize {
235
+ // Ensure that we always have a big enough set to derefence an `FD_SET`.
236
+ core:: cmp:: max (
237
+ fd_set_num_elements_for_fd_array_raw ( set_count) ,
238
+ div_ceil ( size_of :: < FD_SET > ( ) , size_of :: < FdSetElement > ( ) ) ,
239
+ )
240
+ }
241
+
242
+ /// Compute the raw `fd_set_num_elements` value, before ensuring the value is
243
+ /// big enough to dereference an `FD_SET`.
244
+ #[ cfg( any( windows, target_os = "wasi" ) ) ]
245
+ #[ inline]
246
+ fn fd_set_num_elements_for_fd_array_raw ( set_count : usize ) -> usize {
235
247
// Allocate space for an `fd_count` field, plus `set_count` elements
236
248
// for the `fd_array` field.
237
249
div_ceil (
238
- align_of :: < FD_SET > ( ) + set_count * size_of :: < RawFd > ( ) ,
250
+ core :: cmp :: max ( align_of :: < FD_SET > ( ) , align_of :: < RawFd > ( ) ) + set_count * size_of :: < RawFd > ( ) ,
239
251
size_of :: < FdSetElement > ( ) ,
240
252
)
241
253
}
@@ -346,12 +358,24 @@ mod test {
346
358
347
359
// The layout of `FD_SET` should match our layout of a set of the same
348
360
// size.
361
+ assert_eq ! (
362
+ fd_set_num_elements_for_fd_array_raw(
363
+ memoffset:: span_of!( FD_SET , fd_array) . len( ) / size_of:: <RawFd >( )
364
+ ) * size_of:: <FdSetElement >( ) ,
365
+ size_of:: <FD_SET >( )
366
+ ) ;
349
367
assert_eq ! (
350
368
fd_set_num_elements_for_fd_array(
351
369
memoffset:: span_of!( FD_SET , fd_array) . len( ) / size_of:: <RawFd >( )
352
370
) * size_of:: <FdSetElement >( ) ,
353
371
size_of:: <FD_SET >( )
354
372
) ;
373
+
374
+ // Don't create fd sets smaller than `FD_SET`.
375
+ assert_eq ! (
376
+ fd_set_num_elements_for_fd_array( 0 ) * size_of:: <FdSetElement >( ) ,
377
+ size_of:: <FD_SET >( )
378
+ ) ;
355
379
}
356
380
357
381
#[ test]
0 commit comments