Skip to content

Commit b1b91d3

Browse files
DerDreschnerbackportbot[bot]
authored andcommitted
fix: Return empty DataSet object when no unique IP exists to prevent exception on merge
Signed-off-by: David Dreschner <[email protected]>
1 parent 27a174b commit b1b91d3

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

lib/Service/NegativeSampleGenerator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private function getUniqueIPsPerUser(Dataset $positives): array {
5959
private function generateFromRealData(array $uidVec, array $uniqueIps): array {
6060
return array_merge(
6161
$uidVec,
62-
empty($uniqueIps) ? [] : $uniqueIps[random_int(0, count($uniqueIps) - 1)]
62+
$uniqueIps[random_int(0, count($uniqueIps) - 1)]
6363
);
6464
}
6565

@@ -96,6 +96,10 @@ public function generateShuffledFromPositiveSamples(DataSet $positives, int $num
9696
$max = count($positives);
9797
$uniqueIps = $this->getUniqueIPsPerUser($positives);
9898

99+
if ($uniqueIps === []) {
100+
return new Labeled();
101+
}
102+
99103
return new Labeled(
100104
array_map(function (int $id) use ($uniqueIps, $positives, $max) {
101105
$sample = $positives->sample($id % $max);

lib/Service/Statistics/AppStatistics.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
45
* SPDX-License-Identifier: AGPL-3.0-or-later

tests/Unit/Service/NegativeSampleGeneratorTest.php

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,9 @@ public function testGenerateMultipleShuffledFromLimitedUnique(): void {
112112
self::assertTrue(
113113
$ipVec == self::decToBitArray(3, 32) ||
114114
$ipVec === self::decToBitArray(4, 32),
115-
'sample has a unique IP'
115+
'Sample must have an unique IP'
116116
);
117117
}
118-
119-
$positives = new Unlabeled([
120-
array_merge(self::decToBitArray(1, 16), self::decToBitArray(1, 32)),
121-
array_merge(self::decToBitArray(2, 16), self::decToBitArray(1, 32)),
122-
array_merge(self::decToBitArray(3, 16), self::decToBitArray(1, 32)),
123-
array_merge(self::decToBitArray(4, 16), self::decToBitArray(1, 32)),
124-
]);
125-
126-
$result = $this->generator->generateShuffledFromPositiveSamples($positives, 5);
127-
128-
self::assertCount(5, $result);
129118
}
130119

131120
/**
@@ -154,11 +143,30 @@ public function testGenerateMultipleShuffledFromUniquesOnly(): void {
154143
self::assertTrue(
155144
$ipVec === self::decToBitArray(1, 32) ||
156145
$ipVec === self::decToBitArray(2, 32),
157-
'Sample has an unique IP'
146+
'Sample must have an unique IP'
158147
);
159148
}
160149
}
161150

151+
/**
152+
* Generating shuffled samples isn't possible when no user has an unique IP.
153+
* In that case, we have to return an empty Labeled() object as merging will
154+
* fail otherwise. See GitHub issue #860 for more.
155+
* @return void
156+
*/
157+
public function testGenerateShuffledFromDuplicatesOnly(): void {
158+
$positives = new Unlabeled([
159+
array_merge(self::decToBitArray(1, 16), self::decToBitArray(1, 32)),
160+
array_merge(self::decToBitArray(2, 16), self::decToBitArray(1, 32)),
161+
array_merge(self::decToBitArray(3, 16), self::decToBitArray(1, 32)),
162+
array_merge(self::decToBitArray(4, 16), self::decToBitArray(1, 32)),
163+
]);
164+
165+
$result = $this->generator->generateShuffledFromPositiveSamples($positives, 4);
166+
167+
self::assertCount(0, $result, 'Returned sample must be empty');
168+
}
169+
162170
/**
163171
* @return int[]
164172
*/

0 commit comments

Comments
 (0)