Skip to content

Commit

Permalink
replace null character when serializing
Browse files Browse the repository at this point in the history
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
  • Loading branch information
SebastianKrupinski committed Dec 6, 2024
1 parent dbb8421 commit 85edd83
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 2 deletions.
1 change: 1 addition & 0 deletions apps/dav/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<step>OCA\DAV\Migration\RemoveClassifiedEventActivity</step>
<step>OCA\DAV\Migration\RemoveDeletedUsersCalendarSubscriptions</step>
<step>OCA\DAV\Migration\RemoveObjectProperties</step>
<step>OCA\DAV\Migration\RemoveBrokenProperties</step>
</post-migration>
<live-migration>
<step>OCA\DAV\Migration\ChunkCleanup</step>
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir . '/../lib/Migration/RegenerateBirthdayCalendars.php',
'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\RemoveBrokenProperties' => $baseDir . '/../lib/Migration/RemoveBrokenProperties.php',
'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php',
'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => $baseDir . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php',
'OCA\\DAV\\Migration\\RemoveObjectProperties' => $baseDir . '/../lib/Migration/RemoveObjectProperties.php',
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/Migration/RegenerateBirthdayCalendars.php',
'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\RemoveBrokenProperties' => __DIR__ . '/..' . '/../lib/Migration/RemoveBrokenProperties.php',
'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php',
'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => __DIR__ . '/..' . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php',
'OCA\\DAV\\Migration\\RemoveObjectProperties' => __DIR__ . '/..' . '/../lib/Migration/RemoveObjectProperties.php',
Expand Down
6 changes: 4 additions & 2 deletions apps/dav/lib/DAV/CustomPropertiesBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
$valueType = self::PROPERTY_TYPE_OBJECT;
// serialize produces null character
// these can not be properly stored in some databases and need to be replaced
$value = str_replace(chr(0), ' ', serialize($value));
$value = str_replace(chr(0), '\x00', serialize($value));
}
return [$value, $valueType];
}
Expand All @@ -536,7 +536,9 @@ private function decodeValueFromDatabase(string $value, int $valueType) {
case self::PROPERTY_TYPE_HREF:
return new Href($value);
case self::PROPERTY_TYPE_OBJECT:
return unserialize($value);
// some databases can not handel null characters, these are custom encoded during serialization
// this custom encoding needs to be first reversed before unserializing
return unserialize(str_replace('\x00', chr(0), $value));
case self::PROPERTY_TYPE_STRING:
default:
return $value;
Expand Down
67 changes: 67 additions & 0 deletions apps/dav/lib/Migration/RemoveBrokenProperties.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Migration;

use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;

class RemoveBrokenProperties implements IRepairStep {
private const CALENDAR_TRANSP_PROPERTY = '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp';

/**
* RemoveBrokenProperties constructor.
*
* @param IDBConnection $db
*/
public function __construct(
private IDBConnection $db,
) {
}

/**
* @inheritdoc
*/
public function getName() {
return 'Remove broken object properties';
}

/**
* @inheritdoc
*/
public function run(IOutput $output) {
// select all calendar transparency properties
$cmd = $this->db->getQueryBuilder();
$cmd->select('id', 'propertyvalue')
->from('properties')
->where($cmd->expr()->eq('propertyname', $cmd->createNamedParameter(self::CALENDAR_TRANSP_PROPERTY, IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR));
$result = $cmd->executeQuery();
// find broken properties
$brokenIds = [];
while ($entry = $result->fetch()) {
if (!empty($entry['propertyvalue'])) {
$object = @unserialize(str_replace('\x00', chr(0), $entry['propertyvalue']));
if ($object === false) {
$brokenIds[] = $entry['id'];
}
} else {
$brokenIds[] = $entry['id'];
}
}
$result->closeCursor();
// delete broken calendar transparency properties
$cmd = $this->db->getQueryBuilder();
$cmd->delete('properties')
->where($cmd->expr()->in('id', $cmd->createParameter('ids'), IQueryBuilder::PARAM_STR_ARRAY));
foreach (array_chunk($brokenIds, 1000) as $chunkIds) {
$cmd->setParameter('ids', $chunkIds, IQueryBuilder::PARAM_STR_ARRAY);
$cmd->executeStatement();
}
$total = count($brokenIds);
$output->info("$total broken object properties removed");
}
}

0 comments on commit 85edd83

Please sign in to comment.