From 55f99c4422a7843beafafd9b2232381bd12b7e85 Mon Sep 17 00:00:00 2001 From: o-hushcha Date: Wed, 27 May 2026 00:44:55 +0300 Subject: [PATCH] Fix TypeError in parseFetch for integer-shaped key tokens Some IMAP servers emit FETCH responses where an even-indexed atom (key position) is an integer-shaped token (e.g. "* 1 FETCH (12345 NIL)" or as observed in the wild on the @integromat/imap consumer side via extension/quirk responses). convStr returns a JS number for such atoms, and parseFetch then calls .toLowerCase() on it, throwing: TypeError: list[i].toLowerCase is not a function at Parser.parseFetch (lib/Parser.js:431) Coerce the key token to a string at the extraction site. Value-position numeric atoms (RFC822.SIZE, MODSEQ, UIDNEXT, etc.) are untouched, so existing consumers that read those as numbers see no behavior change. Bump to 0.8.22. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/Parser.js | 7 ++++++- package.json | 2 +- test/test-parser.js | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/Parser.js b/lib/Parser.js index 16297d366..44740ea76 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -428,7 +428,12 @@ function parseFetch(text, literals, seqno) { var list = parseExpr(text, literals)[0], attrs = {}, m, body; // list is [KEY1, VAL1, KEY2, VAL2, .... KEYn, VALn] for (var i = 0, len = list.length, key, val; i < len; i += 2) { - key = list[i].toLowerCase(); + // Coerce the key token to a string before lowercasing. Some servers send + // integer-shaped atoms at key positions in malformed FETCH responses; + // convStr returns a JS number for those, and Number has no .toLowerCase. + // Coercing here keeps value-position numeric atoms (RFC822.SIZE, MODSEQ, + // etc.) untouched. + key = String(list[i]).toLowerCase(); val = list[i + 1]; if (key === 'envelope') val = parseFetchEnvelope(val); diff --git a/package.json b/package.json index e2fb1f75c..98368648c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "@integromat/imap", - "version": "0.8.21", + "version": "0.8.22", "author": "Brian White ", "description": "An IMAP module for node.js that makes communicating with IMAP servers easy", "main": "./lib/Connection", diff --git a/test/test-parser.js b/test/test-parser.js index 39d1723d1..01236a749 100644 --- a/test/test-parser.js +++ b/test/test-parser.js @@ -310,6 +310,15 @@ var CR = '\r', LF = '\n', CRLF = CR + LF; ], what: 'Untagged FETCH with non-body literal' }, + { source: ['* 1 FETCH (12345 NIL)', CRLF], + expected: [ { type: 'fetch', + num: 1, + textCode: undefined, + text: { '12345': null } + } + ], + what: 'Untagged FETCH with integer-shaped key token (regression: no TypeError on .toLowerCase)' + }, { source: ['* 12 FETCH (INTERNALDATE {2', '6}' + CRLF + '17-Jul-1996 02:44:25 -0700)' + CRLF], expected: [ { type: 'fetch',