From b4ec289c3036f3609ecc1b82b197bc3aebf17d27 Mon Sep 17 00:00:00 2001 From: Michael Stilkerich Date: Wed, 21 Dec 2022 13:49:52 +0100 Subject: [PATCH] Convert address fields to strings during search (Fixes: #410) This avoids passing an address as structured data to roundcube's compare_search_value() function, which requires either a string or a list of strings. --- CHANGELOG.md | 4 ++++ src/Addressbook.php | 11 +++++++++++ src/DataConversion.php | 4 ++-- tests/unit/AddressbookTest.php | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a69fde81..95e0b396 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for RCMCardDAV +## Version 4.4.5 (to 4.4.4) + +- Fix: Internal server error with PHP8 when searching address fields of contacts (Fixes: #410) + ## Version 4.4.4 (to 4.4.3) - Fix PHP 8.1 warning on loss of precision by using integer division diff --git a/src/Addressbook.php b/src/Addressbook.php index f45212ed..160e499d 100644 --- a/src/Addressbook.php +++ b/src/Addressbook.php @@ -40,6 +40,7 @@ /** * @psalm-import-type FullAbookRow from AbstractDatabase * @psalm-import-type SaveData from DataConversion + * @psalm-import-type SaveDataAddressField from DataConversion * * @psalm-type GroupSaveData = array{ * ID: string, @@ -1763,6 +1764,16 @@ private function checkPostSearchFilter( } } + // normalize address structured data to string + if (isset($save_data['address'])) { + $mergedAddrs = []; + /** @psalm-var list $save_data['address'] */ + foreach ($save_data['address'] as $addrStruct) { + $mergedAddrs[] = implode(' ', $addrStruct); + } + $save_data['address'] = $mergedAddrs; + } + $filterMatches = 0; foreach ($postSearchFilter as $psfilter) { [ $col, $val ] = $psfilter; diff --git a/src/DataConversion.php b/src/DataConversion.php index df03859c..ba9213c4 100644 --- a/src/DataConversion.php +++ b/src/DataConversion.php @@ -58,7 +58,7 @@ * maidenname?: string, * organization?: string, * department?: string - * } & array + * } & array> * * @psalm-type SaveDataFromDC = array{ * name: string, @@ -83,7 +83,7 @@ * department?: string, * vcard?: string, * _carddav_vcard?: VCard, - * } & array + * } & array> * * @psalm-type ColTypeDef = array{subtypes?: list, subtypealias?: array} * @psalm-type ColTypeDefs = array diff --git a/tests/unit/AddressbookTest.php b/tests/unit/AddressbookTest.php index c295277a..1c348ca1 100644 --- a/tests/unit/AddressbookTest.php +++ b/tests/unit/AddressbookTest.php @@ -314,6 +314,13 @@ public function searchDataProvider(): array [], [], 2, ["60", "50"] ], + 'Single Multivalue DB structured-content field search with contains search' => [ + ['address'], ["Kanto"], rcube_addressbook::SEARCH_ALL, true, false, + 'name', 'ASC', 1, 10, + 0, + [], [], + 1, ["60"] + ], 'Single Multivalue DB field search with strict search' => [ ['email'], ["north@7kingdoms.com"], rcube_addressbook::SEARCH_STRICT, true, false, 'name', 'ASC', 1, 10, @@ -372,6 +379,14 @@ public function searchDataProvider(): array [], [], 1, ["60"] ], + 'All fields search (no matches)' => [ + '*', 'Birkin22', + rcube_addressbook::SEARCH_ALL, true, false, + 'name', 'ASC', 1, 10, + 0, + [], [], + 0, [] + ], 'Two fields OR search' => [ ['organization', 'name'], 'the', rcube_addressbook::SEARCH_ALL, true, false,