Skip to content

Commit 5f5c0d9

Browse files
Fix GH-14402: Rearrange tests
1 parent 2236ca2 commit 5f5c0d9

14 files changed

+584
-431
lines changed

ext/spl/spl_heap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,10 +1091,6 @@ static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_objec
10911091
array_init(return_value);
10921092
add_assoc_long(return_value, "flags", intern->flags);
10931093

1094-
if (heap_count == 0) {
1095-
return;
1096-
}
1097-
10981094
array_init_size(&heap_elements, heap_count);
10991095

11001096
for (int heap_idx = 0; heap_idx < heap_count; ++heap_idx) {
@@ -1191,6 +1187,10 @@ PHP_METHOD(SplPriorityQueue, __serialize)
11911187

11921188
ZEND_PARSE_PARAMETERS_NONE();
11931189

1190+
if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) {
1191+
RETURN_THROWS();
1192+
}
1193+
11941194
array_init(return_value);
11951195

11961196
spl_heap_serialize_properties(&props, intern);
@@ -1244,6 +1244,10 @@ PHP_METHOD(SplHeap, __serialize)
12441244

12451245
ZEND_PARSE_PARAMETERS_NONE();
12461246

1247+
if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) {
1248+
RETURN_THROWS();
1249+
}
1250+
12471251
array_init(return_value);
12481252

12491253
spl_heap_serialize_properties(&props, intern);

ext/spl/tests/SplHeap_serialization_format_security.phpt

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
--TEST--
2+
SplHeap and SplPriorityQueue serialization fails when corrupted
3+
--FILE--
4+
<?php
5+
6+
class ThrowingHeap extends SplMaxHeap {
7+
public function compare($a, $b): int {
8+
if ($a === 'throw' || $b === 'throw') {
9+
throw new Exception('Comparison failed');
10+
}
11+
return parent::compare($a, $b);
12+
}
13+
}
14+
15+
$heap = new ThrowingHeap();
16+
$heap->insert(1);
17+
$heap->insert(2);
18+
19+
try {
20+
$heap->insert('throw');
21+
} catch (Exception $e) {
22+
// no-op, heap should now be corrupted
23+
}
24+
25+
echo "Heap is corrupted: " . ($heap->isCorrupted() ? 'YES' : 'NO') . "\n";
26+
27+
try {
28+
serialize($heap);
29+
echo "FAIL: Serialization should have thrown\n";
30+
} catch (Exception $e) {
31+
echo "Serialization failed: " . $e->getMessage() . "\n";
32+
}
33+
34+
class ThrowingPQ extends SplPriorityQueue {
35+
public function compare($priority1, $priority2): int {
36+
if ($priority1 === 'throw' || $priority2 === 'throw') {
37+
throw new Exception('Priority comparison failed');
38+
}
39+
return parent::compare($priority1, $priority2);
40+
}
41+
}
42+
43+
$pq = new ThrowingPQ();
44+
$pq->insert('data1', 1);
45+
$pq->insert('data2', 2);
46+
47+
try {
48+
$pq->insert('data3', 'throw');
49+
} catch (Exception $e) {
50+
// no-op, queue is corrupted
51+
}
52+
53+
echo "PriorityQueue is corrupted: " . ($pq->isCorrupted() ? 'YES' : 'NO') . "\n";
54+
55+
try {
56+
serialize($pq);
57+
echo "FAIL: PQ Serialization should have thrown\n";
58+
} catch (Exception $e) {
59+
echo "PQ Serialization failed: " . $e->getMessage() . "\n";
60+
}
61+
62+
?>
63+
--EXPECT--
64+
Heap is corrupted: YES
65+
Serialization failed: Heap is corrupted, heap properties are no longer ensured.
66+
PriorityQueue is corrupted: YES
67+
PQ Serialization failed: Heap is corrupted, heap properties are no longer ensured.
Lines changed: 72 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,84 @@
11
--TEST--
2-
SplHeap and SplPriorityQueue serialization error handling
2+
SplHeap and SplPriorityQueue unserialization error handling
33
--FILE--
44
<?php
55

6-
try {
7-
$heap = new SplMaxHeap();
8-
$heap->__unserialize([]);
9-
echo "FAIL: Should have thrown exception\n";
10-
} catch (Exception $e) {
11-
echo "Wrong element count - " . $e->getMessage() . "\n";
12-
}
13-
14-
try {
15-
$heap = new SplMinHeap();
16-
$heap->__unserialize(['not_array', []]);
17-
echo "FAIL: Should have thrown exception\n";
18-
} catch (Exception $e) {
19-
echo "Invalid properties type - " . $e->getMessage() . "\n";
20-
}
21-
22-
try {
23-
$heap = new SplMaxHeap();
24-
$heap->__unserialize([[], 'not_array']);
25-
echo "FAIL: Should have thrown exception\n";
26-
} catch (Exception $e) {
27-
echo "Invalid state type - " . $e->getMessage() . "\n";
28-
}
29-
30-
try {
31-
$heap = new SplMaxHeap();
32-
$heap->__unserialize([[], []]);
33-
echo "FAIL: Should have thrown exception\n";
34-
} catch (Exception $e) {
35-
echo "Missing flags - " . $e->getMessage() . "\n";
36-
}
37-
38-
try {
39-
$heap = new SplMaxHeap();
40-
$heap->__unserialize([[], ['flags' => 0, 'heap_elements' => 'not_array']]);
41-
echo "FAIL: Should have thrown exception\n";
42-
} catch (Exception $e) {
43-
echo "Invalid heap elements - " . $e->getMessage() . "\n";
44-
}
45-
46-
try {
47-
$pq = new SplPriorityQueue();
48-
$pq->__unserialize([[], [], []]);
49-
echo "FAIL: Should have thrown exception\n";
50-
} catch (Exception $e) {
51-
echo "PQ wrong element count - " . $e->getMessage() . "\n";
52-
}
53-
54-
try {
55-
$pq = new SplPriorityQueue();
56-
$pq->__unserialize([123, []]);
57-
echo "FAIL: Should have thrown exception\n";
58-
} catch (Exception $e) {
59-
echo "PQ invalid properties - " . $e->getMessage() . "\n";
60-
}
61-
62-
try {
63-
$pq = new SplPriorityQueue();
64-
$pq->__unserialize([[], []]);
65-
echo "FAIL: Should have thrown exception\n";
66-
} catch (Exception $e) {
67-
echo "PQ missing flags - " . $e->getMessage() . "\n";
68-
}
6+
// Test malformed data cases
7+
$invalid_cases = [
8+
// Wrong array count
9+
[],
10+
[[], [], []],
11+
12+
// Invalid properties type
13+
['not_array', []],
14+
[123, []],
15+
16+
// Invalid state type
17+
[[], 'not_array'],
18+
[[], 123],
19+
20+
// Missing flags
21+
[[], []],
22+
23+
// Invalid flags type
24+
[[], ['flags' => 'not_int']],
25+
26+
// Missing heap_elements
27+
[[], ['flags' => 0]],
28+
29+
// Invalid heap_elements type
30+
[[], ['flags' => 0, 'heap_elements' => 'not_array']],
31+
[[], ['flags' => 0, 'heap_elements' => 123]],
32+
];
6933

70-
try {
71-
$pq = new SplPriorityQueue();
72-
$pq->__unserialize([[], ['flags' => 1, 'heap_elements' => ['not_array']]]);
73-
echo "FAIL: Should have thrown exception\n";
74-
} catch (Exception $e) {
75-
echo "PQ invalid element structure - " . $e->getMessage() . "\n";
34+
foreach ($invalid_cases as $i => $case) {
35+
try {
36+
$heap = new SplMaxHeap();
37+
$heap->__unserialize($case);
38+
echo "Case $i: UNEXPECTED SUCCESS\n";
39+
} catch (Exception $e) {
40+
echo "Case $i: " . $e->getMessage() . "\n";
41+
}
7642
}
7743

78-
try {
79-
$pq = new SplPriorityQueue();
80-
$pq->__unserialize([[], ['flags' => 1, 'heap_elements' => [['data' => 'test']]]]);
81-
echo "FAIL: Should have thrown exception\n";
82-
} catch (Exception $e) {
83-
echo "PQ missing priority - " . $e->getMessage() . "\n";
84-
}
44+
$pq_invalid_cases = [
45+
// Invalid flags for PQ
46+
[[], ['flags' => 0]],
47+
48+
// Invalid element structure
49+
[[], ['flags' => 1, 'heap_elements' => ['not_array']]],
50+
51+
// Missing data/priority keys
52+
[[], ['flags' => 1, 'heap_elements' => [['data' => 'test']]]],
53+
[[], ['flags' => 1, 'heap_elements' => [['priority' => 1]]]],
54+
[[], ['flags' => 1, 'heap_elements' => [[]]]],
55+
];
8556

86-
try {
87-
$pq = new SplPriorityQueue();
88-
$pq->__unserialize([[], ['flags' => 1, 'heap_elements' => [['priority' => 1]]]]);
89-
echo "FAIL: Should have thrown exception\n";
90-
} catch (Exception $e) {
91-
echo "PQ missing data - " . $e->getMessage() . "\n";
57+
foreach ($pq_invalid_cases as $i => $case) {
58+
try {
59+
$pq = new SplPriorityQueue();
60+
$pq->__unserialize($case);
61+
echo "PQ Case $i: UNEXPECTED SUCCESS\n";
62+
} catch (Exception $e) {
63+
echo "PQ Case $i: " . $e->getMessage() . "\n";
64+
}
9265
}
9366

9467
?>
9568
--EXPECT--
96-
Wrong element count - Invalid serialization data for SplMaxHeap object
97-
Invalid properties type - Invalid serialization data for SplMinHeap object
98-
Invalid state type - Invalid serialization data for SplMaxHeap object
99-
Missing flags - Invalid serialization data for SplMaxHeap object
100-
Invalid heap elements - Invalid serialization data for SplMaxHeap object
101-
PQ wrong element count - Invalid serialization data for SplPriorityQueue object
102-
PQ invalid properties - Invalid serialization data for SplPriorityQueue object
103-
PQ missing flags - Invalid serialization data for SplPriorityQueue object
104-
PQ invalid element structure - Invalid serialization data for SplPriorityQueue object
105-
PQ missing priority - Invalid serialization data for SplPriorityQueue object
106-
PQ missing data - Invalid serialization data for SplPriorityQueue object
69+
Case 0: Invalid serialization data for SplMaxHeap object
70+
Case 1: Invalid serialization data for SplMaxHeap object
71+
Case 2: Invalid serialization data for SplMaxHeap object
72+
Case 3: Invalid serialization data for SplMaxHeap object
73+
Case 4: Invalid serialization data for SplMaxHeap object
74+
Case 5: Invalid serialization data for SplMaxHeap object
75+
Case 6: Invalid serialization data for SplMaxHeap object
76+
Case 7: Invalid serialization data for SplMaxHeap object
77+
Case 8: Invalid serialization data for SplMaxHeap object
78+
Case 9: Invalid serialization data for SplMaxHeap object
79+
Case 10: Invalid serialization data for SplMaxHeap object
80+
PQ Case 0: Invalid serialization data for SplPriorityQueue object
81+
PQ Case 1: Invalid serialization data for SplPriorityQueue object
82+
PQ Case 2: Invalid serialization data for SplPriorityQueue object
83+
PQ Case 3: Invalid serialization data for SplPriorityQueue object
84+
PQ Case 4: Invalid serialization data for SplPriorityQueue object

0 commit comments

Comments
 (0)