Sieve Filter \s* Regular Expression Not Recommended

Document ID: 10277

Synopsis

Some regular expressions that contain the \s* sequence will choke on blank lines, hitting a squared relationship in the regex engine between the number of blank lines and time to execute.

More Information

Sieve Filter \s* Regular Expression Not Recommended Some regular expressions that contain the \s* sequence will choke on blank lines, hitting a squared relationship in the regex engine between the number of blank lines and time to execute. If your Sieve rules contain this express, you may see SMTPRA 100% CPU increase (loop being caused) or message files that are zero bytes in size in your message spools or message data directories.

Most filters that include a \s expression will be ok, but "some" filters that included a "\s*" expression won't be. "\s*" would be ok, "(\s*|b)" would be ok, but "(\s*a|b)" wouldn't.

Rockliffe recommends that you analyze your Sieve filters, paying particular attention to expressions that contain \s*, and work out if you do want to match newlines, or if linear whitespace (space or tab) will indeed meet your needs.

Example of Proper Sieve Rule
(^[ \t]|;)[ \t]*(name=|begin[ \t]+\d+[\t]+)(".+\.|.+\.)(bat|cmd|com|exe|hta|js|jse|lnk|pif|scr|sct|shb|shs |vb|vbe|vbs|wsc|wsf|wsh|dll|ocx|msi)("|$|\?="|[ \t]+)

The main difference includes changing all expression syntax \s to a [ \t] (NOTE: the space before the \t is very important). Here a \s expression matches space, tab or newline whitespace, and the [ \t] expression matches only a tab or space character (not new lines).

Why can we do this? Well if you are looking for part of a body part header, then it will either be on a line following a ";", or will be on a "wrapped" header which means that it will be after a new line followed by one or more linear whitespace characters. Two examples should help clarify this:

Content-Type: application/octet-stream; name=Readme.txt

Content-Type: application/octet-stream;
 name=Readme.txt

You are therefore only interested in either linear whitespace, or newlines followed by one or more linear whitespaces. So a regex that looked for \s* would be quite happy to match all the blank lines, but a regex of "(^[\t]|;)[ \t]*" would not.

Query if using SQL Database
End-user can create Sieve scripts at the mailbox level and if you are using an SQL database you can find them by using this query. It isn't a simple query because the SieveScript column is a BLOB and it is complicated to deal with BLOBs using T-SQL.

Below is a query that will likely return the results the customer wants although there is a slight chance it will give incorrect data if there is a tuple where the first non-whitespace character occurs after the first 2k of data. I also took aliases and synonym domains out of the result set.

select
  mn.mailname, dn.domainname
from
  mailboxproperties mp
inner join
  mailnames mn on mn.mailboxid = mp.mailboxid -- get the name of the
mailbox from the ID
inner join
  domainnames dn on dn.domainid = mn.domainid -- get the name of
the domain from the ID
where
  ltrim(convert(char(2048), sievescript)) != '' and -- first 2048
bytes of SieveScript must contain a non whitespace character
  dn.principalname = 1 and -- ignore synonym domains
  mn.principalname = 1 -- ignore mailbox aliases