From 5d8a665fb01c78d184a9d62ecea1aaa0bbaeed0d Mon Sep 17 00:00:00 2001 From: Andrew Pietila Date: Mon, 27 Jan 2025 21:57:43 -0600 Subject: [PATCH] Implement RFC 5322 3.2.4 --- mimetest.js | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/mimetest.js b/mimetest.js index 9421222..601d038 100644 --- a/mimetest.js +++ b/mimetest.js @@ -253,7 +253,7 @@ function parseAtom(chars, ptr) { var atext = parseAtext(chars, ptr); subTokens.push(atext); value += atext._value; - ptr = atext._value + 1; + ptr = atext._endChar + 1; } catch(e) { inAtom = false; } @@ -285,7 +285,7 @@ function parseDotAtomText(chars, ptr) { var atext = parseAtext(chars, ptr); subTokens.push(atext); value += atext._value; - ptr = atext._value + 1; + ptr = atext._endChar + 1; } catch(e) { // We fish later. } @@ -303,4 +303,140 @@ function parseDotAtomText(chars, ptr) { // TODO: Do we care with granularity about the dots and their positions? return new ABNFResult(value, subTokens, "dot-atom-text", startChar, ptr); +} + +function parseDotAtom(chars, ptr) { + // RFC 5322 3.2.3 + // dot-atom = [CFWS] dot-atom-text [CFWS] + var startChar = ptr; + var value = ""; + var subTokens = []; + try { + var cfws = parseCFWS(chars, ptr); + subTokens.push(cfws); + value += cfws._value; + ptr = cfws._endChar + 1; + } catch(e) { + + } + try { + var dat = parseDotAtomText(chars, ptr); + subTokens.push(dat); + value += dat._value; + ptr = dat._endChar + 1; + } catch(e) { + throw new ABNFNoMatchError(); + } + try { + const cfws = parseCFWS(chars, ptr); + subTokens.push(cfws); + value += cfws._value; + ptr = cfws._endChar + 1; + } catch(e) { + + } + return new ABNFResult(value, subTokens, "dot-atom", startChar, ptr); +} + +const qtextChars = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~".split(''); + +function parseQtext(chars, ptr) { + // RFC 5322 3.2.4 + // qtext = %d33 / ; Printable US-ASCII + // %d35-91 / ; characters not including + // %d93-126 / ; "\" or the quote character + // obs-qtext + + if ( qtextChars.includes(chars[ptr]) ) { + return new ABNFResult(chars[ptr], null, "qtext", ptr, ptr); + } else { + throw new ABNFNoMatchError(); + } +} + +function parseQcontent(chars, ptr) { + // RFC 5322 3.2.4 + try { + const qtext = parseQtext(chars, ptr); + return new ABNFResult(qtext._value, qtext, "qcontent", qtext._startChar, qtext._endChar); + } catch(e) { + try { + const quotedPair = parseQuotedPair(chars, ptr); + return new ABNFResult(quotedPair._value, quotedPair, "qcontent", quotedPair._startChar, quotedPair._endChar); + } catch(e) { + throw new ABNFNoMatchError(); + } + } +} + +function parseDQUOTE(chars, ptr) { + // RFC 5234 B.1 + // DQUOTE = %x22 + // ; " (Double Quote) + if ( chars[ptr] === String.fromCharCode(0x22) ) { + return new ABNFResult(chars[ptr], null, "DQUOTE", ptr, ptr); + } else { + throw new ABNFNoMatchError(); + } +} + +function parseQuotedString(chars, ptr) { + // RFC 5322 3.2.4 + // quoted-string = [CFWS] + // DQUOTE *([FWS] qcontent) [FWS] DQUOTE + // [CFWS] + var startChar = ptr; + var value = ""; + var subTokens = []; + try { + const cfws = parseCFWS(chars, ptr); + subTokens.push(cfws); + value += cfws._value; + ptr = cfws._endChar + 1; + } catch(e) { + + } + try { + const dquote = parseDQUOTE(chars, ptr); + subTokens.push(dquote); + value += dquote._value; + ptr = dquote._endChar + 1; + } catch(e) { + throw new ABNFNoMatchError(); + } + var inDquot = true; + while (inDquot) { + try { + const fws = parseFWS(chars, ptr); + subTokens.push(fws); + value += fws._value; + ptr = fws._endChar + 1; + } catch(e) { + try { + const qcontent = parseQcontent(chars, ptr); + subTokens.push(qcontent); + value += qcontent._value; + ptr = qcontent._endChar + 1; + } catch(e) { + inDquot = false; + } + } + } + try { + const dquote = parseDQUOTE(chars, ptr); + subTokens.push(dquote); + value += dquote._value; + ptr = dquote._endChar + 1; + } catch(e) { + throw new ABNFNoMatchError(); + } + try { + const cfws = parseCFWS(chars, ptr); + subTokens.push(cfws); + value += cfws._value; + ptr = cfws._endChar + 1; + } catch(e) { + + } + return new ABNFResult(value, subTokens, "quoted-string", startChar, ptr); } \ No newline at end of file