Skip to content

Commit

Permalink
Convert address fields to strings during search (Fixes: #410)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mstilkerich committed Dec 21, 2022
1 parent 28745e0 commit b4ec289
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
11 changes: 11 additions & 0 deletions src/Addressbook.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1763,6 +1764,16 @@ private function checkPostSearchFilter(
}
}

// normalize address structured data to string
if (isset($save_data['address'])) {
$mergedAddrs = [];
/** @psalm-var list<SaveDataAddressField> $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;
Expand Down
4 changes: 2 additions & 2 deletions src/DataConversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
* maidenname?: string,
* organization?: string,
* department?: string
* } & array<string, SaveDataMultiField|SaveDataAddressField>
* } & array<string, SaveDataMultiField|list<SaveDataAddressField>>
*
* @psalm-type SaveDataFromDC = array{
* name: string,
Expand All @@ -83,7 +83,7 @@
* department?: string,
* vcard?: string,
* _carddav_vcard?: VCard,
* } & array<string, SaveDataMultiField|SaveDataAddressField>
* } & array<string, SaveDataMultiField|list<SaveDataAddressField>>
*
* @psalm-type ColTypeDef = array{subtypes?: list<string>, subtypealias?: array<string,string>}
* @psalm-type ColTypeDefs = array<string,ColTypeDef>
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/AddressbookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'], ["[email protected]"], rcube_addressbook::SEARCH_STRICT, true, false,
'name', 'ASC', 1, 10,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit b4ec289

Please sign in to comment.