Skip to content

Commit da2ea50

Browse files
authored
fix(imap-search): ZMSA-77: revert ZMSA-67, add UID SEARCH protocol tests (#977)
* ZMSA-77: in case of UID SEARCH 1:N where N is the amount of messages in mailbox, treat the search as sequence search instead of UID search * ZMSA-77: revert ZMSA-67 changes, add more UID SEARCH protocol tests * remove unneded variable * rename some search protocol tests * add more search protocol tests
1 parent f7fe4d7 commit da2ea50

File tree

3 files changed

+146
-8
lines changed

3 files changed

+146
-8
lines changed

imap-core/lib/commands/search.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ module.exports = {
3333
let parsed;
3434

3535
try {
36-
parsed = parseQueryTerms(terms, this.selected.uidList, isUid);
36+
parsed = parseQueryTerms(terms, this.selected.uidList);
3737
} catch (E) {
3838
return callback(E);
3939
}
@@ -151,9 +151,8 @@ function isFixedRange(value) {
151151
return value.indexOf(':') >= 0 && value.indexOf(',') < 0;
152152
}
153153

154-
function parseQueryTerms(terms, uidList, isUidSearch) {
154+
function parseQueryTerms(terms, uidList) {
155155
terms = [].concat(terms || []);
156-
isUidSearch = !!isUidSearch;
157156

158157
let pos = 0;
159158
let term;
@@ -184,12 +183,8 @@ function parseQueryTerms(terms, uidList, isUidSearch) {
184183
if (!termType) {
185184
// try if it is a sequence set
186185
if (imapTools.validateSequence(term)) {
187-
let messageRange = imapTools.getMessageRange(uidList, term, isUidSearch);
188-
if (isUidSearch && isFixedRange(term)) {
189-
messageRange.isContiguous = true;
190-
}
191186
// resolve sequence list to an array of UID values
192-
curTerm = ['uid', messageRange];
187+
curTerm = ['uid', imapTools.getMessageRange(uidList, term, false)];
193188
} else {
194189
// no idea what the term is for
195190
throw new Error('Unknown search term ' + term.toUpperCase());

imap-core/test/protocol-test.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,5 +1867,138 @@ describe('IMAP Protocol integration tests', function () {
18671867
}
18681868
);
18691869
});
1870+
1871+
it('should search with UID SEARCH 1:N correctly if N equals to EXISTS response', function (done) {
1872+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH 1:6 NOT DELETED', 'T4 LOGOUT'];
1873+
1874+
testClient(
1875+
{
1876+
commands: cmds,
1877+
secure: true,
1878+
port
1879+
},
1880+
function (resp) {
1881+
resp = resp.toString();
1882+
expect(resp.match(/^\* SEARCH /gm).length).to.equal(1);
1883+
expect(/^\* SEARCH 101 102 103 104 105 106$/m.test(resp)).to.be.true;
1884+
expect(/^T3 OK/m.test(resp)).to.be.true;
1885+
done();
1886+
}
1887+
);
1888+
});
1889+
1890+
it('should search with UID SEARCH 1:N correctly if N does not equal to EXISTS response', function (done) {
1891+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH 1:3', 'T4 LOGOUT'];
1892+
1893+
testClient(
1894+
{
1895+
commands: cmds,
1896+
secure: true,
1897+
port
1898+
},
1899+
function (resp) {
1900+
resp = resp.toString();
1901+
expect(resp.match(/^\* SEARCH /gm).length).to.equal(1);
1902+
expect(/^\* SEARCH 101 102 103$/m.test(resp)).to.be.true;
1903+
expect(/^T3 OK/m.test(resp)).to.be.true;
1904+
done();
1905+
}
1906+
);
1907+
});
1908+
1909+
it('should intersect sequence set with UID search key in UID SEARCH', function (done) {
1910+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH 2:5 UID 103:104', 'T4 LOGOUT'];
1911+
1912+
testClient(
1913+
{
1914+
commands: cmds,
1915+
secure: true,
1916+
port
1917+
},
1918+
function (resp) {
1919+
resp = resp.toString();
1920+
expect(resp.match(/^\* SEARCH /gm).length).to.equal(1);
1921+
expect(/^\* SEARCH 103 104$/m.test(resp)).to.be.true;
1922+
expect(/^T3 OK/m.test(resp)).to.be.true;
1923+
done();
1924+
}
1925+
);
1926+
});
1927+
1928+
it('should treat 1:10 as sequence and 20:30 as UID set (empty intersection)', function (done) {
1929+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH 1:10 UID 20:30', 'T4 LOGOUT'];
1930+
1931+
testClient(
1932+
{
1933+
commands: cmds,
1934+
secure: true,
1935+
port
1936+
},
1937+
function (resp) {
1938+
resp = resp.toString();
1939+
expect(/^\* SEARCH$/m.test(resp)).to.be.true;
1940+
expect(/^\* SEARCH \d/m.test(resp)).to.be.false;
1941+
expect(/^T3 OK/m.test(resp)).to.be.true;
1942+
done();
1943+
}
1944+
);
1945+
});
1946+
1947+
it('should treat UID 1:10 as UID set and 20:30 as sequence (empty intersection)', function (done) {
1948+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH UID 1:10 20:30', 'T4 LOGOUT'];
1949+
1950+
testClient(
1951+
{
1952+
commands: cmds,
1953+
secure: true,
1954+
port
1955+
},
1956+
function (resp) {
1957+
resp = resp.toString();
1958+
expect(/^\* SEARCH$/m.test(resp)).to.be.true;
1959+
expect(/^\* SEARCH \d/m.test(resp)).to.be.false;
1960+
expect(/^T3 OK/m.test(resp)).to.be.true;
1961+
done();
1962+
}
1963+
);
1964+
});
1965+
1966+
it('should intersect sequence set with UID set when both match', function (done) {
1967+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH 1:4 UID 102:104', 'T4 LOGOUT'];
1968+
1969+
testClient(
1970+
{
1971+
commands: cmds,
1972+
secure: true,
1973+
port
1974+
},
1975+
function (resp) {
1976+
resp = resp.toString();
1977+
expect(resp.match(/^\* SEARCH /gm).length).to.equal(1);
1978+
expect(/^\* SEARCH 102 103 104$/m.test(resp)).to.be.true;
1979+
expect(/^T3 OK/m.test(resp)).to.be.true;
1980+
done();
1981+
}
1982+
);
1983+
});
1984+
1985+
it('should intersect UID set first and sequence set second', function (done) {
1986+
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID SEARCH UID 101:104 2:3', 'T4 LOGOUT'];
1987+
1988+
testClient(
1989+
{
1990+
commands: cmds,
1991+
secure: true,
1992+
port
1993+
},
1994+
function (resp) {
1995+
resp = resp.toString();
1996+
expect(resp.match(/^\* SEARCH /gm).length).to.equal(1);
1997+
expect(/^\* SEARCH 102 103$/m.test(resp)).to.be.true;
1998+
expect(/^T3 OK/m.test(resp)).to.be.true;
1999+
done();
2000+
}
2001+
);
2002+
});
18702003
});
18712004
});

imap-core/test/search-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,16 @@ describe('#parseQueryTerms', function () {
547547

548548
describe('UID sequence edge cases', function () {
549549
this.timeout(1000);
550+
it('should treat bare sequence set as sequence numbers in UID SEARCH', function () {
551+
const testUidList = [39, 40, 44, 52, 53, 54, 59, 72];
552+
553+
const parsed = parseQueryTerms(['1:3'], testUidList, true);
554+
555+
expect(parsed.query).to.have.length(1);
556+
expect(parsed.query[0].key).to.equal('uid');
557+
expect(parsed.query[0].value).to.deep.equal([39, 40, 44]);
558+
});
559+
550560
it('should handle overlaps, duplicates, reversed ranges, and *', function () {
551561
const testUidList = [2, 4, 6, 8, 10, 12];
552562
const seq = buildWeirdSequenceSet();

0 commit comments

Comments
 (0)