1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
From: Aleksander Machniak <alec@alec.pl>
Date: Wed, 31 Jul 2024 18:11:31 +0200
Subject: Fix infinite loop when parsing malformed Sieve script
Origin: https://github.com/roundcube/roundcubemail/commit/3567090a997e95aac6bb052bfb48bb301d0c03c3
Bug: https://github.com/roundcube/roundcubemail/issues/9562
---
plugins/managesieve/lib/Roundcube/rcube_sieve_script.php | 7 ++++---
plugins/managesieve/tests/Script.php | 14 ++++++++++++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
index 05a53a2..3c9d7fc 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
@@ -1353,9 +1353,10 @@ class rcube_sieve_script
// bracket-comment
case '/':
- if ($str[$position + 1] == '*') {
- if ($end_pos = strpos($str, '*/', $position + 2)) {
- $position = $end_pos + 2;
+ $position++;
+ if ($str[$position] == '*') {
+ if ($end_pos = strpos($str, '*/', $position + 1)) {
+ $position = $end_pos + 1;
}
else {
// error
diff --git a/plugins/managesieve/tests/Script.php b/plugins/managesieve/tests/Script.php
index 41982d1..f9ea3f4 100644
--- a/plugins/managesieve/tests/Script.php
+++ b/plugins/managesieve/tests/Script.php
@@ -59,6 +59,20 @@ class Managesieve_Script extends PHPUnit\Framework\TestCase
return $result;
}
+ /**
+ * Sieve script parsing
+ */
+ public function test_parser_bug9562()
+ {
+ // This is an obviously invalid script
+ $input = "vacation :subject \"a\" :from \"b\"\n<a href=\"https://test.org/\">test</a>";
+ $script = new \rcube_sieve_script($input);
+ $result = $script->as_text();
+
+ // TODO: The output still is BS, but it at least does not cause an infinite loop
+ $this->assertSame("require [\"vacation\"];\r\nvacation :subject \"a\" :from \"b\" \"a\";\r\n", $result);
+ }
+
function data_tokenizer()
{
return [
|