|
24 | 24 | use function in_array; |
25 | 25 | use function is_bool; |
26 | 26 | use function mb_substr; |
| 27 | +use function strlen; |
27 | 28 | use function substr; |
28 | 29 |
|
29 | 30 | #[AutowiredService] |
@@ -76,19 +77,29 @@ public function getTypeFromFunctionCall( |
76 | 77 | if ($length !== null) { |
77 | 78 | if ($functionReflection->getName() === 'mb_substr') { |
78 | 79 | $substr = mb_substr($constantString->getValue(), $offset->getValue(), $length->getValue()); |
| 80 | + } elseif ($this->phpVersion->substrReturnFalseInsteadOfEmptyString()) { |
| 81 | + $substr = $this->substrOrFalse($constantString->getValue(), $offset->getValue(), $length->getValue()); |
79 | 82 | } else { |
80 | 83 | $substr = substr($constantString->getValue(), $offset->getValue(), $length->getValue()); |
81 | 84 | } |
82 | 85 | } else { |
83 | 86 | if ($functionReflection->getName() === 'mb_substr') { |
84 | 87 | $substr = mb_substr($constantString->getValue(), $offset->getValue()); |
| 88 | + } elseif ($this->phpVersion->substrReturnFalseInsteadOfEmptyString()) { |
| 89 | + // Simulate substr call on an older PHP version if the runtime one is too new. |
| 90 | + $substr = $this->substrOrFalse($constantString->getValue(), $offset->getValue()); |
85 | 91 | } else { |
86 | 92 | $substr = substr($constantString->getValue(), $offset->getValue()); |
87 | 93 | } |
88 | 94 | } |
89 | 95 |
|
90 | 96 | if (is_bool($substr)) { |
91 | | - $results[] = new ConstantBooleanType($substr); |
| 97 | + if ($this->phpVersion->substrReturnFalseInsteadOfEmptyString()) { |
| 98 | + $results[] = new ConstantBooleanType($substr); |
| 99 | + } else { |
| 100 | + // Simulate substr call on a recent PHP version if the runtime one is too old. |
| 101 | + $results[] = new ConstantStringType(''); |
| 102 | + } |
92 | 103 | } else { |
93 | 104 | $results[] = new ConstantStringType($substr); |
94 | 105 | } |
@@ -129,4 +140,28 @@ public function getTypeFromFunctionCall( |
129 | 140 | return null; |
130 | 141 | } |
131 | 142 |
|
| 143 | + private function substrOrFalse(string $string, int $offset, ?int $length = null): false|string |
| 144 | + { |
| 145 | + $strlen = strlen($string); |
| 146 | + |
| 147 | + if ($offset > $strlen) { |
| 148 | + return false; |
| 149 | + } |
| 150 | + |
| 151 | + if ($length !== null && $length < 0) { |
| 152 | + if ($offset < 0 && -$length > $strlen) { |
| 153 | + return false; |
| 154 | + } |
| 155 | + if ($offset >= 0 && -$length > $strlen - $offset) { |
| 156 | + return false; |
| 157 | + } |
| 158 | + } |
| 159 | + |
| 160 | + if ($length === null) { |
| 161 | + return substr($string, $offset); |
| 162 | + } |
| 163 | + |
| 164 | + return substr($string, $offset, $length); |
| 165 | + } |
| 166 | + |
132 | 167 | } |
0 commit comments