From 196e61f74bbf3d3ccacac3fd5c7d3f19ae61d435 Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Thu, 12 Sep 2024 22:01:34 +0200 Subject: [PATCH] fixup! feat: mail filters Signed-off-by: Daniel Kesselberg --- lib/Service/MailFilter/FilterBuilder.php | 35 +++++++------------ lib/Service/OutOfOffice/OutOfOfficeParser.php | 10 ++---- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/lib/Service/MailFilter/FilterBuilder.php b/lib/Service/MailFilter/FilterBuilder.php index 0d9bfea21a..fa8471fe00 100644 --- a/lib/Service/MailFilter/FilterBuilder.php +++ b/lib/Service/MailFilter/FilterBuilder.php @@ -11,6 +11,7 @@ use OCA\Mail\Exception\ImapFlagEncodingException; use OCA\Mail\IMAP\ImapFlag; +use OCA\Mail\Sieve\SieveUtils; class FilterBuilder { private const SEPARATOR = '### Nextcloud Mail: Filters ### DON\'T EDIT ###'; @@ -38,21 +39,21 @@ public function buildSieveScript(array $filters, string $untouchedScript): strin $tests[] = sprintf( 'header :%s "Subject" %s', $test['operator'], - $this->stringList($test['values']) + SieveUtils::stringList($test['values']), ); } if ($test['field'] === 'to') { $tests[] = sprintf( 'address :%s :all "To" %s', $test['operator'], - $this->stringList($test['values']) + SieveUtils::stringList($test['values']), ); } if ($test['field'] === 'from') { $tests[] = sprintf( 'address :%s :all "From" %s', $test['operator'], - $this->stringList($test['values']) + SieveUtils::stringList($test['values']), ); } } @@ -61,11 +62,17 @@ public function buildSieveScript(array $filters, string $untouchedScript): strin foreach ($filter['actions'] as $action) { if ($action['type'] === 'fileinto') { $extensions[] = 'fileinto'; - $actions[] = sprintf('fileinto "%s";', $action['mailbox']); + $actions[] = sprintf( + 'fileinto "%s";', + SieveUtils::escapeString($action['mailbox']) + ); } if ($action['type'] === 'addflag') { $extensions[] = 'imap4flags'; - $actions[] = sprintf('addflag %s;', $this->stringList($this->sanitizeFlag($action['flag']))); + $actions[] = sprintf( + 'addflag "%s";', + SieveUtils::escapeString($this->sanitizeFlag($action['flag'])) + ); } if ($action['type'] === 'keep') { $actions[] = 'keep;'; @@ -95,7 +102,7 @@ public function buildSieveScript(array $filters, string $untouchedScript): strin if (count($extensions) > 0) { $requireSection[] = self::SEPARATOR; - $requireSection[] = 'require ' . $this->stringList($extensions) . ';'; + $requireSection[] = 'require ' . SieveUtils::stringList($extensions) . ';'; $requireSection[] = self::SEPARATOR; $requireSection[] = ''; } @@ -118,22 +125,6 @@ public function buildSieveScript(array $filters, string $untouchedScript): strin )); } - private function stringList(string|array $value): string { - if (is_string($value)) { - $items = explode(',', $value); - } else { - $items = $value; - } - - $items = array_map([$this, 'quoteString'], $items); - - return '[' . implode(', ', $items) . ']'; - } - - private function quoteString(string $value): string { - return '"' . $value . '"'; - } - private function sanitizeFlag(string $flag): string { try { return $this->imapFlag->create($flag); diff --git a/lib/Service/OutOfOffice/OutOfOfficeParser.php b/lib/Service/OutOfOffice/OutOfOfficeParser.php index 79a532514f..28bb2abfd7 100644 --- a/lib/Service/OutOfOffice/OutOfOfficeParser.php +++ b/lib/Service/OutOfOffice/OutOfOfficeParser.php @@ -13,6 +13,7 @@ use DateTimeZone; use JsonException; use OCA\Mail\Exception\OutOfOfficeParserException; +use OCA\Mail\Sieve\SieveUtils; /** * Parses and builds out-of-office states from/to sieve scripts. @@ -119,7 +120,7 @@ public function buildSieveScript( $condition = "currentdate :value \"ge\" \"iso8601\" \"$formattedStart\""; } - $escapedSubject = $this->escapeStringForSieve($state->getSubject()); + $escapedSubject = SieveUtils::escapeString($state->getSubject()); $vacation = [ 'vacation', ':days 4', @@ -134,7 +135,7 @@ public function buildSieveScript( $vacation[] = ":addresses [$joinedRecipients]"; } - $escapedMessage = $this->escapeStringForSieve($state->getMessage()); + $escapedMessage = SieveUtils::escapeString($state->getMessage()); $vacation[] = "\"$escapedMessage\""; $vacationCommand = implode(' ', $vacation); @@ -183,9 +184,4 @@ public function buildSieveScript( private function formatDateForSieve(DateTimeImmutable $date): string { return $date->setTimezone($this->utc)->format('Y-m-d\TH:i:s\Z'); } - - private function escapeStringForSieve(string $subject): string { - $subject = preg_replace('/\\\\/', '\\\\\\\\', $subject); - return preg_replace('/"/', '\\"', $subject); - } }