From b546855a2081e4e459e2b3c6e79b742fd6fbb134 Mon Sep 17 00:00:00 2001 From: nick evans Date: Mon, 28 Sep 2026 09:46:26 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20`SequenceSet#slice(pos..to?= =?UTF-8?q?o=5Flow=5Fneg)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When slicing with a positive...negative range, where the range ends prior to the beginning of the set, this incorrectly set `max` to the _last_ value in the set, without regarding the sign of the range end. This converts both `set[start..end]` and `set[start..-end]` into `set[start..]` when the range end is out of range, which is correct for positive range end, but clearly incorrect for negative range end. --- lib/net/imap/sequence_set.rb | 2 +- test/net/imap/test_sequence_set.rb | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 29c59e800..ecd113e9a 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -2435,7 +2435,7 @@ def slice_range(range) if (first * last).positive? && last < first remain_frozen_empty elsif (min = sorted_set_num_at(first)) - max = sorted_set_num_at(last) || STAR_INT + max = sorted_set_num_at(last) || (last.negative? ? 0 : STAR_INT) if min <= max then intersection export_minmax_entry [min, max] else remain_frozen_empty end diff --git a/test/net/imap/test_sequence_set.rb b/test/net/imap/test_sequence_set.rb index bd3801076..b1b9acb35 100644 --- a/test/net/imap/test_sequence_set.rb +++ b/test/net/imap/test_sequence_set.rb @@ -489,13 +489,6 @@ def obj.to_sequence_set; 192_168.001_255 end def pend_slice_bug(what, &) = pend("#slice bug: #{what}", &) - def pend_slice_lomax(set, start, actual) - pend_slice_bug "return empty when max < -cardinality" do - assert_same empty, actual - end - assert_equal set[start..], actual - end - def pend_slice_nil(actual) pend_slice_bug "return nil for invalid slice start index" do assert_nil actual @@ -613,11 +606,11 @@ def pend_slice_zero_len(&) test "#[range] -> empty, for empty positive..negative range with valid start" do set = SequenceSet[1..200] - pend_slice_lomax set, 0, set[ 0.. -201] # i.e: 0.. before start - pend_slice_lomax set, 0, set[ 0...-200] # i.e: 0... 0 + assert_same SequenceSet.empty, set[ 0.. -201] # i.e: 0.. before start + assert_same SequenceSet.empty, set[ 0...-200] # i.e: 0... 0 assert_same SequenceSet.empty, set[ 1.. -200] # i.e: 1.. 0 - pend_slice_lomax set, 100, set[100.. -201] # i.e: 100.. before first - pend_slice_lomax set, 100, set[100...-200] # i.e: 100... 0 + assert_same SequenceSet.empty, set[100.. -201] # i.e: 100.. before first + assert_same SequenceSet.empty, set[100...-200] # i.e: 100... 0 assert_same SequenceSet.empty, set[100...-100] # i.e: 100...100 assert_same SequenceSet.empty, set[100.. -101] # i.e: 100.. 99 assert_same SequenceSet.empty, set[199... -1] # i.e: 199...199