@@ -427,22 +427,49 @@ fn is_session_overshared_for_user(
427427 let recipient_device_ids: BTreeSet < & DeviceId > =
428428 recipient_devices. iter ( ) . map ( |d| d. device_id ( ) ) . collect ( ) ;
429429
430+ let mut shared: Vec < & DeviceId > = Vec :: new ( ) ;
431+
432+ // This duplicates a conservative subset of the logic in OutbundGroupSession::is_shared_with,
433+ // because we don't have corresponding DeviceData at hand
434+ fn is_actually_shared ( info : & ShareInfo ) -> bool {
435+ match info {
436+ ShareInfo :: Shared ( _) => true ,
437+ ShareInfo :: Withheld ( _) => false ,
438+ }
439+ }
440+
441+ // Collect the devices that have definitely received the session already
430442 let guard = outbound_session. shared_with_set . read ( ) ;
443+ if let Some ( for_user) = guard. get ( user_id) {
444+ shared. extend ( for_user. iter ( ) . filter_map ( |( d, info) | if is_actually_shared ( info) {
445+ Some ( AsRef :: < DeviceId > :: as_ref ( d) )
446+ } else {
447+ None
448+ } ) ) ;
449+ }
431450
432- let Some ( shared) = guard. get ( user_id) else {
451+ // To be conservative, also collect the devices that would still receive the session
452+ // from a pending to-device request if we don't rotate beforehand
453+ let guard = outbound_session. to_share_with_set . read ( ) ;
454+ for ( _txid, share_infos) in guard. values ( ) {
455+ if let Some ( for_user) = share_infos. get ( user_id) {
456+ shared. extend ( for_user. iter ( ) . filter_map ( |( d, info) | if is_actually_shared ( info) {
457+ Some ( AsRef :: < DeviceId > :: as_ref ( d) )
458+ } else {
459+ None
460+ } ) ) ;
461+ }
462+ }
463+
464+ if shared. is_empty ( ) {
433465 return false ;
434- } ;
466+ }
435467
436- // Devices that received this session
437- let shared: BTreeSet < & DeviceId > = shared
438- . iter ( )
439- . filter ( |( _, info) | matches ! ( info, ShareInfo :: Shared ( _) ) )
440- . map ( |( d, _) | d. as_ref ( ) )
441- . collect ( ) ;
468+ let shared: BTreeSet < & DeviceId > = shared. into_iter ( ) . collect ( ) ;
442469
443470 // The set difference between
444471 //
445- // 1. Devices that had previously received the session, and
472+ // 1. Devices that had previously received (or are queued to receive) the session, and
446473 // 2. Devices that would now receive the session
447474 //
448475 // Represents newly deleted or blacklisted devices. If this
0 commit comments