diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
commit | 0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch) | |
tree | 3f3789daa2f6db22da6e55e92bee0062a7d613fe /pigeonhole/tests/execute | |
parent | Initial commit. (diff) | |
download | dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip |
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pigeonhole/tests/execute')
19 files changed, 1540 insertions, 0 deletions
diff --git a/pigeonhole/tests/execute/actions.svtest b/pigeonhole/tests/execute/actions.svtest new file mode 100644 index 0000000..3f517fa --- /dev/null +++ b/pigeonhole/tests/execute/actions.svtest @@ -0,0 +1,80 @@ +require "vnd.dovecot.testsuite"; +require "relational"; +require "comparator-i;ascii-numeric"; + +test_set "message" text: +To: nico@frop.example.org +From: stephan@example.org +Subject: Test + +Test. +. +; + +test_mailbox_create "INBOX.VB"; +test_mailbox_create "INBOX.backup"; + +test "Fileinto" { + if not test_script_compile "actions/fileinto.sieve" { + test_fail "script compile failed"; + } + + if not test_script_run { + test_fail "script run failed"; + } + + if not test_result_action :count "eq" :comparator "i;ascii-numeric" "3" { + test_fail "wrong number of actions in result"; + } + + if not test_result_action :index 1 "store" { + test_fail "first action is not 'store'"; + } + + if not test_result_action :index 2 "store" { + test_fail "second action is not 'store'"; + } + + if not test_result_action :index 3 "keep" { + test_fail "third action is not 'keep'"; + } + + if not test_result_execute { + test_fail "result execute failed"; + } +} + +test "Redirect" { + if not test_script_compile "actions/redirect.sieve" { + test_fail "compile failed"; + } + + if not test_script_run { + test_fail "execute failed"; + } + + if not test_result_action :count "eq" :comparator "i;ascii-numeric" "4" { + test_fail "wrong number of actions in result"; + } + + if not test_result_action :index 1 "redirect" { + test_fail "first action is not 'redirect'"; + } + + if not test_result_action :index 2 "keep" { + test_fail "second action is not 'keep'"; + } + + if not test_result_action :index 3 "redirect" { + test_fail "third action is not 'redirect'"; + } + + if not test_result_action :index 4 "redirect" { + test_fail "fourth action is not 'redirect'"; + } + + if not test_result_execute { + test_fail "result execute failed"; + } +} + diff --git a/pigeonhole/tests/execute/actions/fileinto.sieve b/pigeonhole/tests/execute/actions/fileinto.sieve new file mode 100644 index 0000000..e9c133b --- /dev/null +++ b/pigeonhole/tests/execute/actions/fileinto.sieve @@ -0,0 +1,17 @@ +require "fileinto"; + +/* Three store actions */ + +if address :contains "to" "frop.example" { + /* #1 */ + fileinto "INBOX.VB"; +} + +/* #2 */ +fileinto "INBOX.backup"; + +/* #3 */ +keep; + +/* Duplicate of keep */ +fileinto "INBOX"; diff --git a/pigeonhole/tests/execute/actions/redirect.sieve b/pigeonhole/tests/execute/actions/redirect.sieve new file mode 100644 index 0000000..7adc23e --- /dev/null +++ b/pigeonhole/tests/execute/actions/redirect.sieve @@ -0,0 +1,17 @@ +if address :contains "to" "frop.example" { + /* #1 */ + redirect "stephan@example.com"; + + /* #2 */ + keep; +} + +/* #3 */ +redirect "stephan@example.org"; + +/* #4 */ +redirect "nico@example.nl"; + +/* Duplicates */ +redirect "Stephan Bosch <stephan@example.com>"; +keep; diff --git a/pigeonhole/tests/execute/address-normalize.svtest b/pigeonhole/tests/execute/address-normalize.svtest new file mode 100644 index 0000000..e826bde --- /dev/null +++ b/pigeonhole/tests/execute/address-normalize.svtest @@ -0,0 +1,46 @@ +require "vnd.dovecot.testsuite"; +require "envelope"; + +test_set "message" text: +From: tss@example.net +To: stephan@example.org +Subject: Frop! + +Frop! +. +; + +test_set "envelope.from" "timo@example.net"; +test_set "envelope.to" "\"sirius\"@example.org"; + +/* + * Mail address normalization - redirect + */ + +test "Mail address normalization - redirect" { + redirect "\"S[r]us\"@example.net"; + redirect "\"Sirius\"@example.net"; + redirect "\"Stephan Bosch\" <\"S.Bosch\"@example.net>"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if not envelope :is "to" "\"S[r]us\"@example.net" { + test_fail "envelope recipient incorrect"; + } + + test_message :smtp 1; + + if not envelope :is "to" "Sirius@example.net" { + test_fail "envelope recipient incorrect"; + } + + test_message :smtp 2; + + if not envelope :is "to" "S.Bosch@example.net" { + test_fail "envelope recipient incorrect"; + } +} diff --git a/pigeonhole/tests/execute/errors-cpu-limit.svtest b/pigeonhole/tests/execute/errors-cpu-limit.svtest new file mode 100644 index 0000000..4a045bc --- /dev/null +++ b/pigeonhole/tests/execute/errors-cpu-limit.svtest @@ -0,0 +1,363 @@ +require "vnd.dovecot.testsuite"; + +test_config_set "sieve_max_cpu_time" "2"; +test_config_reload; + +test_set "message" text: +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary= + +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +. +; + +test "CPU limit" { + if not test_script_compile "errors/cpu-limit.sieve" { + test_fail "script compile failed"; + } + + if test_script_run { + test_fail "script execute should have failed"; + } +} + diff --git a/pigeonhole/tests/execute/errors.svtest b/pigeonhole/tests/execute/errors.svtest new file mode 100644 index 0000000..45bc39c --- /dev/null +++ b/pigeonhole/tests/execute/errors.svtest @@ -0,0 +1,152 @@ +require "vnd.dovecot.testsuite"; + +require "relational"; +require "comparator-i;ascii-numeric"; +require "fileinto"; + +test "Action conflicts: reject <-> fileinto" { + if not test_script_compile "errors/conflict-reject-fileinto.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } +} + +test "Action conflicts: reject <-> keep" { + if not test_script_compile "errors/conflict-reject-keep.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } +} + +test "Action conflicts: reject <-> redirect" { + if not test_script_compile "errors/conflict-reject-redirect.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } +} + +test "Action limit" { + if not test_script_compile "errors/actions-limit.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } + + if not test_error :index 1 :contains "total number of actions exceeds policy limit"{ + test_fail "unexpected error reported"; + } +} + +test "Redirect limit" { + if not test_script_compile "errors/redirect-limit.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } + + if not test_error :index 1 :contains "number of redirect actions exceeds policy limit"{ + test_fail "unexpected error reported"; + } +} + +test "Fileinto missing folder" { + if not test_script_compile "errors/fileinto.sieve" { + test_fail "compile failed"; + } + + test_mailbox_create "INBOX"; + + if not test_script_run { + test_fail "execution failed"; + } + + if test_result_execute { + test_fail "execution of result should have failed"; + } + + if test_error :count "gt" :comparator "i;ascii-numeric" "1" { + test_fail "too many runtime errors reported"; + } + + if not allof ( + test_error :index 1 :contains "failed to store into mailbox", + test_error :index 1 :contains "exist", + test_error :index 1 :contains "FROP") { + test_fail "unexpected error reported"; + } +} + +test "Fileinto invalid folder name" { + if not test_script_compile "errors/fileinto-invalid-name.sieve" { + test_fail "compile failed"; + } + + if not test_script_run { + test_fail "execution failed"; + } + + if test_result_execute { + test_fail "execution of result should have failed"; + } + + if not test_error :count "eq" :comparator "i;ascii-numeric" "1" { + test_fail "wrong number of runtime errors reported"; + } + + if not allof ( + test_error :index 1 :contains "failed to store into mailbox", + test_error :index 1 :contains "name") { + test_fail "unexpected error reported"; + } +} + +test "Fileinto bad UTF-8 in folder name" { + if not test_script_compile "errors/fileinto-bad-utf8.sieve" { + test_fail "compile failed"; + } + + if test_script_run { + test_fail "execution should have failed"; + } + + if not test_error :count "eq" :comparator "i;ascii-numeric" "1" { + test_fail "wrong number of runtime errors reported"; + } + + if not test_error :index 1 :contains "invalid folder name" { + test_fail "unexpected error reported"; + } +} diff --git a/pigeonhole/tests/execute/errors/action-duplicates.sieve b/pigeonhole/tests/execute/errors/action-duplicates.sieve new file mode 100644 index 0000000..6d5370d --- /dev/null +++ b/pigeonhole/tests/execute/errors/action-duplicates.sieve @@ -0,0 +1,4 @@ +require "reject"; + +reject "Message is not appreciated."; +reject "No, really, it is not appreciated."; diff --git a/pigeonhole/tests/execute/errors/actions-limit.sieve b/pigeonhole/tests/execute/errors/actions-limit.sieve new file mode 100644 index 0000000..3ae33a3 --- /dev/null +++ b/pigeonhole/tests/execute/errors/actions-limit.sieve @@ -0,0 +1,35 @@ +require "fileinto"; + +fileinto "box1"; +fileinto "box2"; +fileinto "box3"; +fileinto "box4"; +fileinto "box5"; +fileinto "box6"; +fileinto "box7"; +fileinto "box8"; +fileinto "box9"; +fileinto "box10"; +fileinto "box11"; +fileinto "box12"; +fileinto "box13"; +fileinto "box14"; +fileinto "box15"; +fileinto "box16"; +fileinto "box17"; +fileinto "box18"; +fileinto "box19"; +fileinto "box20"; +fileinto "box21"; +fileinto "box22"; +fileinto "box23"; +fileinto "box24"; +fileinto "box25"; +fileinto "box26"; +fileinto "box27"; +fileinto "box28"; +redirect "address1@example.com"; +redirect "address2@example.com"; +redirect "address3@example.com"; +redirect "address4@example.com"; +keep; diff --git a/pigeonhole/tests/execute/errors/conflict-reject-fileinto.sieve b/pigeonhole/tests/execute/errors/conflict-reject-fileinto.sieve new file mode 100644 index 0000000..85ef139 --- /dev/null +++ b/pigeonhole/tests/execute/errors/conflict-reject-fileinto.sieve @@ -0,0 +1,5 @@ +require "reject"; +require "fileinto"; + +reject "No nonsense in my mailbox."; +fileinto "Spam"; diff --git a/pigeonhole/tests/execute/errors/conflict-reject-keep.sieve b/pigeonhole/tests/execute/errors/conflict-reject-keep.sieve new file mode 100644 index 0000000..569a4ac --- /dev/null +++ b/pigeonhole/tests/execute/errors/conflict-reject-keep.sieve @@ -0,0 +1,4 @@ +require "reject"; + +reject "I am not interested in your nonsense."; +keep; diff --git a/pigeonhole/tests/execute/errors/conflict-reject-redirect.sieve b/pigeonhole/tests/execute/errors/conflict-reject-redirect.sieve new file mode 100644 index 0000000..d012269 --- /dev/null +++ b/pigeonhole/tests/execute/errors/conflict-reject-redirect.sieve @@ -0,0 +1,4 @@ +require "reject"; + +reject "I am not interested in your nonsense."; +redirect "frop@example.com"; diff --git a/pigeonhole/tests/execute/errors/cpu-limit.sieve b/pigeonhole/tests/execute/errors/cpu-limit.sieve new file mode 100644 index 0000000..8532a4b --- /dev/null +++ b/pigeonhole/tests/execute/errors/cpu-limit.sieve @@ -0,0 +1,145 @@ +require ["mime","foreverypart","fileinto", "variables", "regex"]; + +# Here we create an inefficient regex with long compilation time +set "my_exp" "^(((A)|(AB)|(ABC)|(ABCD)|(ABCDE)|(ABCDEF)|(ABCDEFG)|(ABCDEFGH)|(ABCDEFGHI)|(ABCDEFGHIJ)|(ABCDEFGHIJK)|(ABCDEFGHIJKL)|(ABCDEFGHIJKLM)|(ABCDEFGHIJKLMN)|(ABCDEFGHIJKLMNO)|(ABCDEFGHIJKLMNOP)|(ABCDEFGHIJKLMNOPQ)|(ABCDEFGHIJKLMNOPQR))?((B)|(BC)|(BCD)|(BCDE)|(BCDEF)|(BCDEFG)|(BCDEFGH)|(BCDEFGHI)|(BCDEFGHIJ)|(BCDEFGHIJK)|(BCDEFGHIJKL)|(BCDEFGHIJKLM)|(BCDEFGHIJKLMN)|(BCDEFGHIJKLMNO)|(BCDEFGHIJKLMNOP)|(BCDEFGHIJKLMNOPQ)|(BCDEFGHIJKLMNOPQR))?((C)|(CD)|(CDE)|(CDEF)|(CDEFG)|(CDEFGH)|(CDEFGHI)|(CDEFGHIJ)|(CDEFGHIJK)|(CDEFGHIJKL)|(CDEFGHIJKLM)|(CDEFGHIJKLMN)|(CDEFGHIJKLMNO)|(CDEFGHIJKLMNOP)|(CDEFGHIJKLMNOPQ)|(CDEFGHIJKLMNOPQR))?((D)|(DE)|(DEF)|(DEFG)|(DEFGH)|(DEFGHI)|(DEFGHIJ)|(DEFGHIJK)|(DEFGHIJKL)|(DEFGHIJKLM)|(DEFGHIJKLMN)|(DEFGHIJKLMNO)|(DEFGHIJKLMNOP)|(DEFGHIJKLMNOPQ)|(DEFGHIJKLMNOPQR))?((E)|(EF)|(EFG)|(EFGH)|(EFGHI)|(EFGHIJ)|(EFGHIJK)|(EFGHIJKL)|(EFGHIJKLM)|(EFGHIJKLMN)|(EFGHIJKLMNO)|(EFGHIJKLMNOP)|(EFGHIJKLMNOPQ)|(EFGHIJKLMNOPQR))?((F)|(FG)|(FGH)|(FGHI)|(FGHIJ)|(FGHIJK)|(FGHIJKL)|(FGHIJKLM)|(FGHIJKLMN)|(FGHIJKLMNO)|(FGHIJKLMNOP)|(FGHIJKLMNOPQ)|(FGHIJKLMNOPQR))?((G)|(GH)|(GHI)|(GHIJ)|(GHIJK)|(GHIJKL)|(GHIJKLM)|(GHIJKLMN)|(GHIJKLMNO)|(GHIJKLMNOP)|(GHIJKLMNOPQ)|(GHIJKLMNOPQR))?((H)|(HI)|(HIJ)|(HIJK)|(HIJKL)|(HIJKLM)|(HIJKLMN)|(HIJKLMNO)|(HIJKLMNOP)|(HIJKLMNOPQ)|(HIJKLMNOPQR))?((I)|(IJ)|(IJK)|(IJKL)|(IJKLM)|(IJKLMN)|(IJKLMNO)|(IJKLMNOP)|(IJKLMNOPQ)|(IJKLMNOPQR))?((J)|(JK)|(JKL)|(JKLM)|(JKLMN)|(JKLMNO)|(JKLMNOP)|(JKLMNOPQ)|(JKLMNOPQR))?((K)|(KL)|(KLM)|(KLMN)|(KLMNO)|(KLMNOP)|(KLMNOPQ)|(KLMNOPQR))?((L)|(LM)|(LMN)|(LMNO)|(LMNOP)|(LMNOPQ)|(LMNOPQR))?((M)|(MN)|(MNO)|(MNOP)|(MNOPQ)|(MNOPQR))?((N)|(NO)|(NOP)|(NOPQ)|(NOPQR))?((O)|(OP)|(OPQ)|(OPQR))?((P)|(PQ)|(PQR))?((Q)|(QR))?((R))?((R)|(RQ)|(RQP)|(RQPO)|(RQPON)|(RQPONM)|(RQPONML)|(RQPONMLK)|(RQPONMLKJ)|(RQPONMLKJI)|(RQPONMLKJIH)|(RQPONMLKJIHG)|(RQPONMLKJIHGF)|(RQPONMLKJIHGFE)|(RQPONMLKJIHGFED)|(RQPONMLKJIHGFEDC)|(RQPONMLKJIHGFEDCB)|(RQPONMLKJIHGFEDCBA))?((Q)|(QP)|(QPO)|(QPON)|(QPONM)|(QPONML)|(QPONMLK)|(QPONMLKJ)|(QPONMLKJI)|(QPONMLKJIH)|(QPONMLKJIHG)|(QPONMLKJIHGF)|(QPONMLKJIHGFE)|(QPONMLKJIHGFED)|(QPONMLKJIHGFEDC)|(QPONMLKJIHGFEDCB)|(QPONMLKJIHGFEDCBA))?((P)|(PO)|(PON)|(PONM)|(PONML)|(PONMLK)|(PONMLKJ)|(PONMLKJI)|(PONMLKJIH)|(PONMLKJIHG)|(PONMLKJIHGF)|(PONMLKJIHGFE)|(PONMLKJIHGFED)|(PONMLKJIHGFEDC)|(PONMLKJIHGFEDCB)|(PONMLKJIHGFEDCBA))?((O)|(ON)|(ONM)|(ONML)|(ONMLK)|(ONMLKJ)|(ONMLKJI)|(ONMLKJIH)|(ONMLKJIHG)|(ONMLKJIHGF)|(ONMLKJIHGFE)|(ONMLKJIHGFED)|(ONMLKJIHGFEDC)|(ONMLKJIHGFEDCB)|(ONMLKJIHGFEDCBA))?((N)|(NM)|(NML)|(NMLK)|(NMLKJ)|(NMLKJI)|(NMLKJIH)|(NMLKJIHG)|(NMLKJIHGF)|(NMLKJIHGFE)|(NMLKJIHGFED)|(NMLKJIHGFEDC)|(NMLKJIHGFEDCB)|(NMLKJIHGFEDCBA))?((M)|(ML)|(MLK)|(MLKJ)|(MLKJI)|(MLKJIH)|(MLKJIHG)|(MLKJIHGF)|(MLKJIHGFE)|(MLKJIHGFED)|(MLKJIHGFEDC)|(MLKJIHGFEDCB)|(MLKJIHGFEDCBA))?((L)|(LK)|(LKJ)|(LKJI)|(LKJIH)|(LKJIHG)|(LKJIHGF)|(LKJIHGFE)|(LKJIHGFED)|(LKJIHGFEDC)|(LKJIHGFEDCB)|(LKJIHGFEDCBA))?((K)|(KJ)|(KJI)|(KJIH)|(KJIHG)|(KJIHGF)|(KJIHGFE)|(KJIHGFED)|(KJIHGFEDC)|(KJIHGFEDCB)|(KJIHGFEDCBA))?((J)|(JI)|(JIH)|(JIHG)|(JIHGF)|(JIHGFE)|(JIHGFED)|(JIHGFEDC)|(JIHGFEDCB)|(JIHGFEDCBA))?((I)|(IH)|(IHG)|(IHGF)|(IHGFE)|(IHGFED)|(IHGFEDC)|(IHGFEDCB)|(IHGFEDCBA))?((H)|(HG)|(HGF)|(HGFE)|(HGFED)|(HGFEDC)|(HGFEDCB)|(HGFEDCBA))?((G)|(GF)|(GFE)|(GFED)|(GFEDC)|(GFEDCB)|(GFEDCBA))?((F)|(FE)|(FED)|(FEDC)|(FEDCB)|(FEDCBA))?((E)|(ED)|(EDC)|(EDCB)|(EDCBA))?((D)|(DC)|(DCB)|(DCBA))?((C)|(CB)|(CBA))?((B)|(BA))?((A))?)+$"; +set "a" "ABCDEFGHIJKLMNOPQR"; +set "b" "RQPONMLKJIHGFEDCBA"; +set "c" "${a}${b}${a}${b}${a}${b}${a}${b}"; +set "e" "${c}${c}${c}${c}${c}${c}${c}${c}"; +set "f" "${e}${e}${e}${e}${e}${e}${e}${e}"; + +# We create a string on which this regex will spend enough time (around 200 ms) +set "final" "${f}${f}${f}${f}${f}${f}${f}${f}${f}${f}${f}${f}${f}${f}@"; + +# We repeat the throttling process for every mime part +foreverypart { + # We use several if statements to multiply the cpu time consumed by one match + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } + if string :regex "${final}" "${my_exp}" { discard; } + if string :regex "${final}" "${my_exp}" { keep; } +} diff --git a/pigeonhole/tests/execute/errors/fileinto-bad-utf8.sieve b/pigeonhole/tests/execute/errors/fileinto-bad-utf8.sieve new file mode 100644 index 0000000..3e57c92 --- /dev/null +++ b/pigeonhole/tests/execute/errors/fileinto-bad-utf8.sieve @@ -0,0 +1,7 @@ +require "fileinto"; +require "variables"; +require "encoded-character"; + +set "mailbox" "${hex:ff}rop"; +fileinto "${mailbox}"; + diff --git a/pigeonhole/tests/execute/errors/fileinto-invalid-name.sieve b/pigeonhole/tests/execute/errors/fileinto-invalid-name.sieve new file mode 100644 index 0000000..871323e --- /dev/null +++ b/pigeonhole/tests/execute/errors/fileinto-invalid-name.sieve @@ -0,0 +1,5 @@ +require "fileinto"; +require "mailbox"; + +fileinto :create "foo//somedomain/org"; + diff --git a/pigeonhole/tests/execute/errors/fileinto.sieve b/pigeonhole/tests/execute/errors/fileinto.sieve new file mode 100644 index 0000000..185674c --- /dev/null +++ b/pigeonhole/tests/execute/errors/fileinto.sieve @@ -0,0 +1,3 @@ +require "fileinto"; + +fileinto "FROP"; diff --git a/pigeonhole/tests/execute/errors/redirect-limit.sieve b/pigeonhole/tests/execute/errors/redirect-limit.sieve new file mode 100644 index 0000000..86cfda0 --- /dev/null +++ b/pigeonhole/tests/execute/errors/redirect-limit.sieve @@ -0,0 +1,5 @@ +redirect "address1@example.com"; +redirect "address2@example.com"; +redirect "address3@example.com"; +redirect "address4@example.com"; +redirect "address5@example.com"; diff --git a/pigeonhole/tests/execute/examples.svtest b/pigeonhole/tests/execute/examples.svtest new file mode 100644 index 0000000..6143018 --- /dev/null +++ b/pigeonhole/tests/execute/examples.svtest @@ -0,0 +1,115 @@ +require "vnd.dovecot.testsuite"; + +/* Compile and execute all example scripts to trigger + * any Segfaults. No message is set and no results are checked. + */ + +test "Elvey example" { + if not test_script_compile "../../examples/elvey.sieve" { + test_fail "could not compile"; + } + + test_binary_save "elvey"; + test_binary_load "elvey"; + + if not test_script_run { } +} + +test "M. Johnson example" { + if not test_script_compile "../../examples/mjohnson.sieve" { + test_fail "could not compile"; + } + + test_binary_save "mjohnson"; + test_binary_load "mjohnson"; + + if not test_script_run { } +} + +test "RFC 3028 example" { + if not test_script_compile "../../examples/rfc3028.sieve" { + test_fail "could not compile"; + } + + test_binary_save "rfc3028"; + test_binary_load "rfc3028"; + + if not test_script_run { } +} + +test "Sieve examples" { + if not test_script_compile "../../examples/sieve_examples.sieve" { + test_fail "could not compile"; + } + + test_binary_save "sieve_examples"; + test_binary_load "sieve_examples"; + + if not test_script_run { } +} + +test "Vivil example" { + if not test_script_compile "../../examples/vivil.sieve" { + test_fail "could not compile"; + } + + test_binary_save "vivil"; + test_binary_load "vivil"; + + if not test_script_run { } +} + +test "Jerry example" { + if not test_script_compile "../../examples/jerry.sieve" { + test_fail "could not compile"; + } + + test_binary_save "jerry"; + test_binary_load "jerry"; + + if not test_script_run { } +} + +test "M. Klose example" { + if not test_script_compile "../../examples/mklose.sieve" { + test_fail "could not compile"; + } + + test_binary_save "mklose"; + test_binary_load "mklose"; + + if not test_script_run { } +} + +test "Sanjay example" { + if not test_script_compile "../../examples/sanjay.sieve" { + test_fail "could not compile"; + } + + test_binary_save "sanjay"; + test_binary_load "sanjay"; + + if not test_script_run { } +} + +test "Relational (RFC5231) example" { + if not test_script_compile "../../examples/relational.rfc5231.sieve" { + test_fail "could not compile"; + } + + test_binary_save "relational"; + test_binary_load "relational"; + + if not test_script_run { } +} + +test "Subaddress (RFC5233) example" { + if not test_script_compile "../../examples/subaddress.rfc5233.sieve" { + test_fail "could not compile"; + } + + test_binary_save "subaddress"; + test_binary_load "subaddress"; + + if not test_script_run { } +} diff --git a/pigeonhole/tests/execute/mailstore.svtest b/pigeonhole/tests/execute/mailstore.svtest new file mode 100644 index 0000000..d6cc220 --- /dev/null +++ b/pigeonhole/tests/execute/mailstore.svtest @@ -0,0 +1,84 @@ +require "vnd.dovecot.testsuite"; +require "fileinto"; +require "variables"; +require "mailbox"; + +set "message1" text: +From: stephan@example.org +To: nico@frop.example.org +Subject: First message + +Frop +. +; + +set "message2" text: +From: stephan@example.org +To: nico@frop.example.org +Subject: Second message + +Frop +. +; + +set "message3" text: +From: stephan@example.org +To: nico@frop.example.org +Subject: Third message + +Frop +. +; + +test "Duplicates" { + test_set "message" "${message1}"; + + fileinto :create "Folder"; + fileinto :create "Folder"; + + if not test_result_execute { + test_fail "failed to execute first result"; + } + + test_result_reset; + + test_set "message" "${message2}"; + + fileinto :create "Folder"; + fileinto :create "Folder"; + + if not test_result_execute { + test_fail "failed to execute second result"; + } + + test_result_reset; + + test_set "message" "${message3}"; + + fileinto :create "Folder"; + fileinto :create "Folder"; + + if not test_result_execute { + test_fail "failed to execute third result"; + } + + test_message :folder "Folder" 0; + + if not header :is "subject" "First message" { + test_fail "first message incorrect"; + } + + test_message :folder "Folder" 1; + + if not header :is "subject" "Second message" { + test_fail "first message incorrect"; + } + + test_message :folder "Folder" 2; + + if not header :is "subject" "Third message" { + test_fail "first message incorrect"; + } +} + + diff --git a/pigeonhole/tests/execute/smtp.svtest b/pigeonhole/tests/execute/smtp.svtest new file mode 100644 index 0000000..2c7d2e6 --- /dev/null +++ b/pigeonhole/tests/execute/smtp.svtest @@ -0,0 +1,449 @@ +require "vnd.dovecot.testsuite"; +require "envelope"; + +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; + +test "Redirect" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if not address :is "to" "tss@example.net" { + test_fail "to address incorrect (strange forward)"; + } + + if not address :is "from" "stephan@example.org" { + test_fail "from address incorrect (strange forward)"; + } + + if not envelope :is "to" "cras@example.net" { + test_fail "envelope recipient incorrect"; + } + + if not envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "<>"; +test_set "envelope.to" "timo@example.net"; + +test "Redirect from <>" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; + +test_config_set "sieve_redirect_envelope_from" " recipient "; +test_config_reload; + +test "Redirect from [recipient]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "timo@example.net" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "orig_recipient "; +test_config_reload; + +test "Redirect from [original recipient]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "tss@example.net" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "<backscatter@example.net> "; +test_config_reload; + +test "Redirect from [<explicit>]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "backscatter@example.net" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; + +test_config_set "sieve_redirect_envelope_from" "<>"; +test_config_reload; + +test "Redirect from [<>]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "<>"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "<backscatter@example.net>"; +test_config_reload; + +test "Redirect from <> with [<explicit>]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "backscatter@example.net" { + test_fail "envelope sender incorrect (erroneously changed)"; + } + + if not envelope :is "from" "" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "user_email"; +test_config_reload; + +test "Redirect from [user email - fallback default]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if not envelope :is "from" "timo@example.net" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "timo@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +test_result_reset; +test_set "message" text: +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "user_email"; +test_config_set "sieve_user_email" "t.sirainen@example.net"; +test_config_reload; + +test "Redirect from [user email]" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + test_message :smtp 0; + + if envelope :is "from" "sirius@example.org" { + test_fail "envelope sender incorrect (not changed)"; + } + + if not envelope :is "from" "t.sirainen@example.net" { + test_fail "envelope sender incorrect"; + } + + if not header :contains "x-sieve-redirected-from" + "t.sirainen@example.net" { + test_fail "x-sieve-redirected-from header is incorrect"; + } +} + +/* + * Redirect mail loop (sieve_user_email) + */ + +test_result_reset; +test_set "message" text: +X-Sieve-Redirected-From: t.sirainen@example.net +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "user_email"; +test_config_set "sieve_user_email" "t.sirainen@example.net"; +test_config_reload; + +test "Redirect mail loop (sieve_user_email)" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + if test_message :smtp 0 { + test_fail "failed to recognize mail loop"; + } +} + +/* + * Redirect mail loop (final recipient) + */ + +test_result_reset; +test_set "message" text: +X-Sieve-Redirected-From: timo@example.net +From: stephan@example.org +To: tss@example.net +Subject: Frop! + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_reload; + +test "Redirect mail loop (final recipient)" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + if test_message :smtp 0 { + test_fail "failed to recognize mail loop"; + } +} + +/* + * Redirect mail loop (multiple headers) + */ + +test_result_reset; +test_set "message" text: +X-Sieve-Redirected-From: stephan@example.net +From: stephan@example.org +To: tss@example.net +Subject: Frop! +X-Sieve-Redirected-From: t.sirainen@example.net +X-Sieve-Redirected-From: t.sirainen@example.com + +Frop! +. +; +test_set "envelope.from" "sirius@example.org"; +test_set "envelope.to" "timo@example.net"; +test_set "envelope.orig_to" "tss@example.net"; + +test_config_set "sieve_redirect_envelope_from" "user_email"; +test_config_set "sieve_user_email" "t.sirainen@example.net"; +test_config_reload; + +test "Redirect mail loop (sieve_user_email)" { + redirect "cras@example.net"; + + if not test_result_execute { + test_fail "failed to execute redirect"; + } + + if test_message :smtp 0 { + test_fail "failed to recognize mail loop"; + } +} |