Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable29] fix(files): handle multidimensional arrays in scanner #45279

Merged
merged 1 commit into from
May 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions lib/private/Files/Cache/Scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,9 @@ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData =
}

// Only update metadata that has changed
$newData = array_diff_assoc($data, $cacheData->getData());

// i.e. get all the values in $data that are not present in the cache already
$newData = $this->array_diff_assoc_multi($data, $cacheData->getData());

// make it known to the caller that etag has been changed and needs propagation
if (isset($newData['etag'])) {
$data['etag_changed'] = true;
Expand Down Expand Up @@ -369,6 +370,50 @@ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $loc
return $data;
}

/**
* Compares $array1 against $array2 and returns all the values in $array1 that are not in $array2
* Note this is a one-way check - i.e. we don't care about things that are in $array2 that aren't in $array1
*
* Supports multi-dimensional arrays
* Also checks keys/indexes
* Comparisons are strict just like array_diff_assoc
* Order of keys/values does not matter
*
* @param array $array1
* @param array $array2
* @return array with the differences between $array1 and $array1
* @throws \InvalidArgumentException if $array1 isn't an actual array
*
*/
protected function array_diff_assoc_multi(array $array1, array $array2) {

$result = [];

foreach ($array1 as $key => $value) {

// if $array2 doesn't have the same key, that's a result
if (!array_key_exists($key, $array2)) {
$result[$key] = $value;
continue;
}

// if $array2's value for the same key is different, that's a result
if ($array2[$key] !== $value && !is_array($value)) {
$result[$key] = $value;
continue;
}

if (is_array($value)) {
$nestedDiff = $this->array_diff_assoc_multi($value, $array2[$key]);
if (!empty($nestedDiff)) {
$result[$key] = $nestedDiff;
continue;
}
}
}
return $result;
}

/**
* Get the children currently in the cache
*
Expand Down
Loading