|
| 1 | +--TEST-- |
| 2 | +OPcache pinned atomic operations warn and wrap on integer overflow |
| 3 | +--EXTENSIONS-- |
| 4 | +opcache |
| 5 | +--INI-- |
| 6 | +opcache.enable=1 |
| 7 | +opcache.enable_cli=1 |
| 8 | +opcache.static_cache.pinned_size_mb=32 |
| 9 | +--FILE-- |
| 10 | +<?php |
| 11 | + |
| 12 | +function show_result(string $label, callable $callback, int $expected): void |
| 13 | +{ |
| 14 | + echo "-- {$label} --\n"; |
| 15 | + $result = $callback(); |
| 16 | + echo "result: "; |
| 17 | + var_dump($result === $expected); |
| 18 | +} |
| 19 | + |
| 20 | +OPcache\pinned_clear(); |
| 21 | + |
| 22 | +$maxKey = 'atomic_overflow_max_' . getmypid(); |
| 23 | +$minKey = 'atomic_overflow_min_' . getmypid(); |
| 24 | +$missingKey = 'atomic_overflow_missing_' . getmypid(); |
| 25 | +$handlerProbeKey = 'atomic_overflow_handler_probe_' . getmypid(); |
| 26 | + |
| 27 | +OPcache\pinned_store($handlerProbeKey, 'ok'); |
| 28 | + |
| 29 | +set_error_handler(static function (int $severity, string $message) use ($handlerProbeKey): bool { |
| 30 | + echo "warning severity: "; |
| 31 | + var_dump($severity === E_WARNING); |
| 32 | + echo "warning message: {$message}\n"; |
| 33 | + echo "handler fetch: "; |
| 34 | + var_dump(OPcache\pinned_fetch($handlerProbeKey) === 'ok'); |
| 35 | + |
| 36 | + return true; |
| 37 | +}); |
| 38 | + |
| 39 | +var_dump(OPcache\pinned_store($maxKey, PHP_INT_MAX)); |
| 40 | +show_result('increment max no throw', static fn () => OPcache\pinned_atomic_increment($maxKey), PHP_INT_MIN); |
| 41 | +echo "max wrapped no throw: "; |
| 42 | +var_dump(OPcache\pinned_fetch($maxKey) === PHP_INT_MIN); |
| 43 | + |
| 44 | +var_dump(OPcache\pinned_store($maxKey, PHP_INT_MAX)); |
| 45 | +show_result('increment max throw flag', static fn () => OPcache\pinned_atomic_increment($maxKey, 1, true), PHP_INT_MIN); |
| 46 | +echo "max wrapped throw flag: "; |
| 47 | +var_dump(OPcache\pinned_fetch($maxKey) === PHP_INT_MIN); |
| 48 | + |
| 49 | +var_dump(OPcache\pinned_store($minKey, PHP_INT_MIN)); |
| 50 | +show_result('decrement min no throw', static fn () => OPcache\pinned_atomic_decrement($minKey), PHP_INT_MAX); |
| 51 | +echo "min wrapped no throw: "; |
| 52 | +var_dump(OPcache\pinned_fetch($minKey) === PHP_INT_MAX); |
| 53 | + |
| 54 | +var_dump(OPcache\pinned_store($minKey, PHP_INT_MIN)); |
| 55 | +show_result('decrement min throw flag', static fn () => OPcache\pinned_atomic_decrement($minKey, 1, true), PHP_INT_MAX); |
| 56 | +echo "min wrapped throw flag: "; |
| 57 | +var_dump(OPcache\pinned_fetch($minKey) === PHP_INT_MAX); |
| 58 | + |
| 59 | +show_result('decrement missing min step', static fn () => OPcache\pinned_atomic_decrement($missingKey, PHP_INT_MIN), PHP_INT_MIN); |
| 60 | +echo "missing wrapped: "; |
| 61 | +var_dump(OPcache\pinned_fetch($missingKey) === PHP_INT_MIN); |
| 62 | + |
| 63 | +?> |
| 64 | +--EXPECT-- |
| 65 | +bool(true) |
| 66 | +-- increment max no throw -- |
| 67 | +warning severity: bool(true) |
| 68 | +warning message: OPcache\pinned_atomic_increment(): Integer overflow occurred; result wrapped around |
| 69 | +handler fetch: bool(true) |
| 70 | +result: bool(true) |
| 71 | +max wrapped no throw: bool(true) |
| 72 | +bool(true) |
| 73 | +-- increment max throw flag -- |
| 74 | +warning severity: bool(true) |
| 75 | +warning message: OPcache\pinned_atomic_increment(): Integer overflow occurred; result wrapped around |
| 76 | +handler fetch: bool(true) |
| 77 | +result: bool(true) |
| 78 | +max wrapped throw flag: bool(true) |
| 79 | +bool(true) |
| 80 | +-- decrement min no throw -- |
| 81 | +warning severity: bool(true) |
| 82 | +warning message: OPcache\pinned_atomic_decrement(): Integer overflow occurred; result wrapped around |
| 83 | +handler fetch: bool(true) |
| 84 | +result: bool(true) |
| 85 | +min wrapped no throw: bool(true) |
| 86 | +bool(true) |
| 87 | +-- decrement min throw flag -- |
| 88 | +warning severity: bool(true) |
| 89 | +warning message: OPcache\pinned_atomic_decrement(): Integer overflow occurred; result wrapped around |
| 90 | +handler fetch: bool(true) |
| 91 | +result: bool(true) |
| 92 | +min wrapped throw flag: bool(true) |
| 93 | +-- decrement missing min step -- |
| 94 | +warning severity: bool(true) |
| 95 | +warning message: OPcache\pinned_atomic_decrement(): Integer overflow occurred; result wrapped around |
| 96 | +handler fetch: bool(true) |
| 97 | +result: bool(true) |
| 98 | +missing wrapped: bool(true) |
0 commit comments