Simplify Sieve Parser and added RFC5235

This commit is contained in:
djmaze 2021-01-14 23:42:46 +01:00
parent 22964f1fde
commit d9865e3a46
11 changed files with 308 additions and 92 deletions

View file

@ -1,17 +0,0 @@
/**
* https://tools.ietf.org/html/rfc5232
*/
(Sieve => {
Sieve.Extensions.Imap4flags = class
{
/**
* setflag [<variablename: string>] <list-of-flags: string-list>
* addflag [<variablename: string>] <list-of-flags: string-list>
* removeflag [<variablename: string>] <list-of-flags: string-list>
* hasflag [MATCH-TYPE] [COMPARATOR] [<variable-list: string-list>] <list-of-flags: string-list>
*/
};
})(this.Sieve);

View file

@ -15,6 +15,7 @@ class Body extends Grammar.Test
this.match_type = ':is',
this.body_transform = ''; // :raw, :content <string-list>, :text
this.key_list = new Grammar.StringList;
// this.require = 'body';
}
toString()
@ -26,7 +27,6 @@ class Body extends Grammar.Test
+ ' ' + this.key_list;
}
pushArguments(args)
{
args.forEach((arg, i) => {
@ -43,7 +43,7 @@ class Body extends Grammar.Test
}
}
Sieve.Extensions.Body = Body;
Sieve.Commands.body = Body;
})(this.Sieve);

View file

@ -4,20 +4,23 @@
(Sieve => {
class Vacation extends Sieve.Grammar.Command
const Grammar = Sieve.Grammar;
class Vacation extends Grammar.Command
{
constructor()
{
super('vacation');
this.arguments = {
':days' : new Sieve.Grammar.Number,
':subject' : new Sieve.Grammar.QuotedString,
':from' : new Sieve.Grammar.QuotedString,
':addresses': new Sieve.Grammar.StringList,
':days' : new Grammar.Number,
':subject' : new Grammar.QuotedString,
':from' : new Grammar.QuotedString,
':addresses': new Grammar.StringList,
':mime' : false,
':handle' : new Sieve.Grammar.QuotedString
':handle' : new Grammar.QuotedString
};
this.reason = ''; // QuotedString / MultiLine
// this.require = 'vacation';
}
toString()
@ -82,6 +85,6 @@ class Vacation extends Sieve.Grammar.Command
*/
}
Sieve.Extensions.Vacation = Vacation;
Sieve.Commands.vacation = Vacation;
})(this.Sieve);

View file

@ -0,0 +1,114 @@
/**
* https://tools.ietf.org/html/rfc5232
*/
(Sieve => {
const Grammar = Sieve.Grammar;
class Flag extends Grammar.Command
{
constructor(identifier)
{
super(identifier);
this._variablename = new Grammar.QuotedString;
this.list_of_flags = new Grammar.StringList;
// this.require = 'imap4flags';
}
toString()
{
return this.identifier + ' ' + this._variablename + ' ' + this.list_of_flags + ';';
}
get variablename()
{
return this._variablename.value;
}
set variablename(value)
{
this._variablename.value = value;
}
pushArguments(args)
{
if (args[1]) {
if (args[0] instanceof Grammar.QuotedString) {
this._variablename = args[0];
}
if (args[1] instanceof Grammar.StringType) {
this.list_of_flags = args[1];
}
} else if (args[0] instanceof Grammar.StringType) {
this.list_of_flags = args[0];
}
}
}
class SetFlag extends Flag
{
constructor()
{
super('setflag');
}
}
class AddFlag extends Flag
{
constructor()
{
super('addflag');
}
}
class RemoveFlag extends Flag
{
constructor()
{
super('removeflag');
}
}
class HasFlag extends Grammar.Test
{
constructor()
{
super('hasflag');
this.comparator = 'i;ascii-casemap',
this.match_type = ':is',
this.variable_list = new Grammar.StringList;
this.list_of_flags = new Grammar.StringList;
// this.require = 'imap4flags';
}
toString()
{
return 'hasflag'
+ ' ' + this.match_type
// + ' ' + this.comparator
+ ' ' + this.variable_list
+ ' ' + this.list_of_flags;
}
pushArguments(args)
{
args.forEach((arg, i) => {
if (':is' === arg || ':contains' === arg || ':matches' === arg) {
this.match_type = arg;
} else if (arg instanceof Grammar.StringList || arg instanceof Grammar.StringType) {
this[args[i+1] ? 'variable_list' : 'list_of_flags'] = arg;
}
});
}
}
Object.assign(Sieve.Commands, {
setflag: SetFlag,
addflag: AddFlag,
removeflag: RemoveFlag,
hasflag: HasFlag
// mark and unmark never made it into the RFC
});
})(this.Sieve);

View file

@ -0,0 +1,95 @@
/**
* https://tools.ietf.org/html/rfc5235
*/
(Sieve => {
const Grammar = Sieve.Grammar;
class SpamTest extends Grammar.Test
{
constructor()
{
super('spamtest');
this.percent = false, // 0 - 100 else 0 - 10
this.comparator = 'i;ascii-casemap',
this.match_type = ':is',
this.value = new Grammar.QuotedString;
// this.require = this.percent ? 'spamtestplus' : 'spamtest';
}
toString()
{
return 'spamtest'
+ (this.percent ? ' :percent' : '')
// + ' ' + this.comparator
+ ' ' + this.match_type
+ ' ' + this.value;
}
pushArguments(args)
{
args.forEach((arg, i) => {
if (':is' === arg || ':contains' === arg || ':matches' === arg) {
this.match_type = arg;
} else if (':percent' === arg) {
this.percent = true;
} else if (arg instanceof Grammar.StringType) {
if (':comparator' === args[i-1]) {
this.comparator = arg;
} else if (':value' === args[i-1] || ':count' === args[i-1]) {
// Sieve relational [RFC5231] match types
this.match_type = args[i-1] + ' ' + arg;
} else {
this.value = arg;
}
}
});
}
}
class VirusTest extends Grammar.Test
{
constructor()
{
super('virustest');
this.comparator = 'i;ascii-casemap',
this.match_type = ':is',
this.value = new Grammar.QuotedString; // 1 - 5
// this.require = 'virustest';
}
toString()
{
return 'virustest'
// + ' ' + this.comparator
+ ' ' + this.match_type
+ ' ' + this.value;
}
pushArguments(args)
{
args.forEach((arg, i) => {
if (':is' === arg || ':contains' === arg || ':matches' === arg) {
this.match_type = arg;
} else if (arg instanceof Grammar.StringType) {
if (':comparator' === args[i-1]) {
this.comparator = arg;
} else if (':value' === args[i-1] || ':count' === args[i-1]) {
// Sieve relational [RFC5231] match types
this.match_type = args[i-1] + ' ' + arg;
} else {
this.value = arg;
}
}
});
}
}
Object.assign(Sieve.Commands, {
spamtest: SpamTest,
virustest: VirusTest
});
})(this.Sieve);

View file

@ -15,6 +15,7 @@ class Ereject extends Grammar.Command
{
super('ereject');
this._reason = new Grammar.QuotedString;
// this.require = 'ereject';
}
toString()
@ -49,6 +50,7 @@ class Reject extends Grammar.Command
{
super('reject');
this._reason = new Grammar.QuotedString;
// this.require = 'reject';
}
toString()
@ -74,7 +76,7 @@ class Reject extends Grammar.Command
}
}
Sieve.Extensions.Ereject = Ereject;
Sieve.Extensions.Reject = Reject;
Sieve.Commands.ereject = Ereject;
Sieve.Commands.reject = Reject;
})(this.Sieve);