Skip to content

Commit

Permalink
♻️ Parse uid-set as sequence-set without *
Browse files Browse the repository at this point in the history
In addition to letting us delete some code, this is also a step towards
replacing `UIDPlusData` with new (incompatible) data structures that
store UID sets directly, rather than converted into arrays of integers.
  • Loading branch information
nevans committed Jan 31, 2025
1 parent 7bfffe8 commit d51d12e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
20 changes: 10 additions & 10 deletions lib/net/imap/response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,7 @@ def charset__list
def resp_code_apnd__data
validity = number; SP!
dst_uids = uid_set # uniqueid ⊂ uid-set
UIDPlusData.new(validity, nil, dst_uids)
UIDPlus(validity, nil, dst_uids)
end

# already matched: "COPYUID"
Expand All @@ -2015,6 +2015,12 @@ def resp_code_copy__data
validity = number; SP!
src_uids = uid_set; SP!
dst_uids = uid_set
UIDPlus(validity, src_uids, dst_uids)
end

def UIDPlus(validity, src_uids, dst_uids)
src_uids &&= src_uids.each_ordered_number.to_a
dst_uids = dst_uids.each_ordered_number.to_a
UIDPlusData.new(validity, src_uids, dst_uids)
end

Expand Down Expand Up @@ -2141,15 +2147,9 @@ def nparens__objectid; NIL? ? nil : parens__objectid end
# uniqueid = nz-number
# ; Strictly ascending
def uid_set
token = match(T_NUMBER, T_ATOM)
case token.symbol
when T_NUMBER then [Integer(token.value)]
when T_ATOM
token.value.split(",").flat_map {|range|
range = range.split(":").map {|uniqueid| Integer(uniqueid) }
range.size == 1 ? range : Range.new(range.min, range.max).to_a
}
end
set = sequence_set
parse_error("uid-set cannot contain '*'") if set.include_star?
set
end

def nil_atom
Expand Down
18 changes: 18 additions & 0 deletions test/net/imap/test_imap_response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ def test_fetch_binary_and_binary_size
Net::IMAP.debug = debug
end

test "APPENDUID with '*'" do
parser = Net::IMAP::ResponseParser.new
assert_raise_with_message Net::IMAP::ResponseParseError, /uid-set cannot contain '\*'/ do
parser.parse(
"A004 OK [appendUID 1 1:*] Done\r\n"
)
end
end

test "COPYUID with backwards ranges" do
parser = Net::IMAP::ResponseParser.new
response = parser.parse(
Expand All @@ -223,4 +232,13 @@ def test_fetch_binary_and_binary_size
)
end

test "COPYUID with '*'" do
parser = Net::IMAP::ResponseParser.new
assert_raise_with_message Net::IMAP::ResponseParseError, /uid-set cannot contain '\*'/ do
parser.parse(
"A004 OK [copyUID 1 1:* 1:*] Done\r\n"
)
end
end

end

0 comments on commit d51d12e

Please sign in to comment.