Implement RFC 5322 3.2.4

This commit is contained in:
Andrew Pietila 2025-01-27 21:57:43 -06:00
parent c774cb1db5
commit 5d8a665fb0

View file

@ -253,7 +253,7 @@ function parseAtom(chars, ptr) {
var atext = parseAtext(chars, ptr); var atext = parseAtext(chars, ptr);
subTokens.push(atext); subTokens.push(atext);
value += atext._value; value += atext._value;
ptr = atext._value + 1; ptr = atext._endChar + 1;
} catch(e) { } catch(e) {
inAtom = false; inAtom = false;
} }
@ -285,7 +285,7 @@ function parseDotAtomText(chars, ptr) {
var atext = parseAtext(chars, ptr); var atext = parseAtext(chars, ptr);
subTokens.push(atext); subTokens.push(atext);
value += atext._value; value += atext._value;
ptr = atext._value + 1; ptr = atext._endChar + 1;
} catch(e) { } catch(e) {
// We fish later. // We fish later.
} }
@ -303,4 +303,140 @@ function parseDotAtomText(chars, ptr) {
// TODO: Do we care with granularity about the dots and their positions? // TODO: Do we care with granularity about the dots and their positions?
return new ABNFResult(value, subTokens, "dot-atom-text", startChar, ptr); 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);
} }