diff --git a/dev/Sieve/Commands.js b/dev/Sieve/Commands.js index 79bf31849..4214849ba 100644 --- a/dev/Sieve/Commands.js +++ b/dev/Sieve/Commands.js @@ -73,7 +73,7 @@ export class RequireCommand extends GrammarCommand toString() { - return 'require ' + this.capabilities.toString() + ';'; + return 'require ' + this.capabilities + ';'; } pushArguments(args) @@ -109,12 +109,12 @@ export class FileIntoCommand extends GrammarCommand toString() { - return 'fileinto ' + return 'fileinto' // https://datatracker.ietf.org/doc/html/rfc3894 - + ((this.copy && capa.includes('copy')) ? ':copy ' : '') + + ((this.copy && capa.includes('copy')) ? ' :copy' : '') // https://datatracker.ietf.org/doc/html/rfc5490#section-3.2 - + ((this.create && capa.includes('mailbox')) ? ':create ' : '') - + this._mailbox + + ((this.create && capa.includes('mailbox')) ? ' :create' : '') + + ' ' + this._mailbox + ';'; } @@ -150,10 +150,13 @@ export class RedirectCommand extends GrammarCommand toString() { - return 'redirect ' + + return 'redirect' + // https://datatracker.ietf.org/doc/html/rfc6134#section-2.3 +// + ((this.list && capa.includes('extlists')) ? ' :list ' + this.list : '') // https://datatracker.ietf.org/doc/html/rfc3894 - + ((this.copy && capa.includes('copy')) ? ':copy ' : '') - + this._address + + ((this.copy && capa.includes('copy')) ? ' :copy' : '') + + ' ' + this._address + ';'; } diff --git a/dev/Sieve/Extensions/rfc5173.js b/dev/Sieve/Extensions/rfc5173.js index 31b299053..5d85fdab6 100644 --- a/dev/Sieve/Extensions/rfc5173.js +++ b/dev/Sieve/Extensions/rfc5173.js @@ -25,7 +25,7 @@ export class BodyTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.match_type + ' ' + this.body_transform - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc5183.js b/dev/Sieve/Extensions/rfc5183.js index 1279f1f48..66d8cbe44 100644 --- a/dev/Sieve/Extensions/rfc5183.js +++ b/dev/Sieve/Extensions/rfc5183.js @@ -25,7 +25,7 @@ export class EnvironmentTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.match_type + ' ' + this.name - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc5229.js b/dev/Sieve/Extensions/rfc5229.js index 08b4aea8e..86e1b7df6 100644 --- a/dev/Sieve/Extensions/rfc5229.js +++ b/dev/Sieve/Extensions/rfc5229.js @@ -59,8 +59,8 @@ export class StringTest extends GrammarTest return 'string' + ' ' + this.match_type + (this.comparator ? ' :comparator ' + this.comparator : '') - + ' ' + this.source.toString() - + ' ' + this.key_list.toString(); + + ' ' + this.source + + ' ' + this.key_list; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc5230.js b/dev/Sieve/Extensions/rfc5230.js index 1b077eb5c..a02670453 100644 --- a/dev/Sieve/Extensions/rfc5230.js +++ b/dev/Sieve/Extensions/rfc5230.js @@ -46,7 +46,7 @@ export class VacationCommand extends GrammarCommand // result += ' :from ' + this.arguments[':from']; } if (this.addresses.length) { - result += ' :addresses ' + this.addresses.toString(); + result += ' :addresses ' + this.addresses; } if (this.mime) { result += ' :mime'; diff --git a/dev/Sieve/Extensions/rfc5232.js b/dev/Sieve/Extensions/rfc5232.js index 3e5f378e3..918c944df 100644 --- a/dev/Sieve/Extensions/rfc5232.js +++ b/dev/Sieve/Extensions/rfc5232.js @@ -23,7 +23,7 @@ class FlagCommand extends GrammarCommand toString() { - return this.identifier + ' ' + this._variablename + ' ' + this.list_of_flags.toString() + ';'; + return this.identifier + ' ' + this._variablename + ' ' + this.list_of_flags + ';'; } get variablename() @@ -79,8 +79,8 @@ export class HasFlagTest extends GrammarTest return 'hasflag' + ' ' + this.match_type + (this.comparator ? ' :comparator ' + this.comparator : '') - + ' ' + this.variable_list.toString() - + ' ' + this.list_of_flags.toString(); + + ' ' + this.variable_list + + ' ' + this.list_of_flags; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc5260.js b/dev/Sieve/Extensions/rfc5260.js index 5c7868adc..57980f56f 100644 --- a/dev/Sieve/Extensions/rfc5260.js +++ b/dev/Sieve/Extensions/rfc5260.js @@ -36,7 +36,7 @@ export class DateTest extends GrammarTest + ' ' + this.match_type + ' ' + this.header_name + ' ' + this.date_part - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) @@ -77,7 +77,7 @@ export class CurrentDateTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.match_type + ' ' + this.date_part - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc5490.js b/dev/Sieve/Extensions/rfc5490.js index aa836c813..ca02aeb47 100644 --- a/dev/Sieve/Extensions/rfc5490.js +++ b/dev/Sieve/Extensions/rfc5490.js @@ -56,7 +56,7 @@ export class MetadataTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.mailbox + ' ' + this.annotation_name - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) @@ -115,7 +115,7 @@ export class ServerMetadataTest extends GrammarTest + ' ' + this.match_type + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.annotation_name - + ' ' + this.key_list.toString(); + + ' ' + this.key_list; } pushArguments(args) diff --git a/dev/Sieve/Extensions/rfc6134.js b/dev/Sieve/Extensions/rfc6134.js new file mode 100644 index 000000000..f3558ad17 --- /dev/null +++ b/dev/Sieve/Extensions/rfc6134.js @@ -0,0 +1,32 @@ +/** + * https://tools.ietf.org/html/rfc6134 + */ + +import { + GrammarStringList, + GrammarTest +} from 'Sieve/Grammar'; + +/** + * https://datatracker.ietf.org/doc/html/rfc6134#section-2.7 + */ +export class ValidExtListTest extends GrammarTest +{ + constructor() + { + super(); + this.ext_list_names = new GrammarStringList; + } + + get require() { return 'foreverypart'; } + + toString() + { + return 'valid_ext_list ' + this.ext_list_names; + } + + pushArguments(args) + { + this.ext_list_names = args.pop(); + } +} diff --git a/dev/Sieve/Grammar.js b/dev/Sieve/Grammar.js index b656b3ca8..102fb6cfa 100644 --- a/dev/Sieve/Grammar.js +++ b/dev/Sieve/Grammar.js @@ -70,7 +70,7 @@ export class GrammarCommand result += ' ' + arrayToString(this.arguments, ' '); } return result + ( - this.commands.length ? ' ' + this.commands.toString() : ';' + this.commands.length ? ' ' + this.commands : ';' ); } @@ -240,6 +240,12 @@ export class GrammarTest toString() { +/* + // https://datatracker.ietf.org/doc/html/rfc6134#section-2.3 + if (':list' == this.match_type && !capa.includes('extlists')) { + throw 'Unsupported match-type ' + this.match_type; + } +*/ return (this.identifier + (this.comparator ? ' :comparator ' + this.comparator : '') + (this.match_type ? ' ' + this.match_type : '') diff --git a/dev/Sieve/Parser.js b/dev/Sieve/Parser.js index f64f037ae..0516fffa3 100644 --- a/dev/Sieve/Parser.js +++ b/dev/Sieve/Parser.js @@ -213,6 +213,10 @@ export const parseScript = (script, name = 'script.sieve') => { pushArg = arg => { command || error('Argument not part of command'); let prev_arg = args[args.length-1]; +/* + // https://datatracker.ietf.org/doc/html/rfc6134#section-2.3 + if (':is' === arg || ':contains' === arg || ':matches' === arg || (capa.includes('extlists') && ':list')) { +*/ if (':is' === arg || ':contains' === arg || ':matches' === arg) { command.match_type = arg; } else if (':value' === prev_arg || ':count' === prev_arg) { diff --git a/dev/Sieve/README.md b/dev/Sieve/README.md index e1988527f..4b4849acb 100644 --- a/dev/Sieve/README.md +++ b/dev/Sieve/README.md @@ -19,7 +19,7 @@ https://www.iana.org/assignments/sieve-extensions/sieve-extensions.xhtml - [x] RFC5435 enotify - [x] RFC5463 ihave - [x] RFC5490 mailbox / mboxmetadata / servermetadata -- [ ] RFC5703 enclose / extracttext / foreverypart / mime / replace +- [x] RFC5703 enclose / extracttext / foreverypart / mime / replace - [x] RFC6131 vacation-seconds - [ ] RFC6134 extlists - [ ] RFC6558 convert diff --git a/dev/Sieve/Tests.js b/dev/Sieve/Tests.js index dbd35837f..0397b5478 100644 --- a/dev/Sieve/Tests.js +++ b/dev/Sieve/Tests.js @@ -71,8 +71,8 @@ export class AddressTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.address_part + ' ' + this.match_type - + ' ' + this.header_list.toString() - + ' ' + this.key_list.toString(); + + ' ' + this.header_list + + ' ' + this.key_list; } pushArguments(args) @@ -108,7 +108,7 @@ export class AllOfTest extends GrammarTest toString() { - return 'allof ' + this.tests.toString(); + return 'allof ' + this.tests; } } @@ -125,7 +125,7 @@ export class AnyOfTest extends GrammarTest toString() { - return 'anyof ' + this.tests.toString(); + return 'anyof ' + this.tests; } } @@ -150,8 +150,8 @@ export class EnvelopeTest extends GrammarTest + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.address_part + ' ' + this.match_type - + ' ' + this.envelope_part.toString() - + ' ' + this.key_list.toString(); + + ' ' + this.envelope_part + + ' ' + this.key_list; } pushArguments(args) @@ -195,7 +195,7 @@ export class ExistsTest extends GrammarTest result += ' :anychild'; } } - return result + ' ' + this.header_names.toString(); + return result + ' ' + this.header_names; } pushArguments(args) @@ -281,8 +281,8 @@ export class HeaderTest extends GrammarTest // + (this.last ? ' :last' : (this.index.value ? ' :index ' + this.index : '')) + (this.comparator ? ' :comparator ' + this.comparator : '') + ' ' + this.match_type - + ' ' + this.header_names.toString() - + ' ' + this.key_list.toString(); + + ' ' + this.header_names + + ' ' + this.key_list; } pushArguments(args)