Skip to content

Commit 540daf5

Browse files
committed
Fix potential boundary error in Diff::getText()
Both $start and $end could be negative. Signed-off-by: Jack Cherng <[email protected]>
1 parent 2b723e7 commit 540daf5

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

src/Diff.php

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@ public function setOptions(array $options): self
137137

138138
/**
139139
* Get a range of lines from $start to $end from the first comparison string
140-
* and return them as an array. If no values are supplied, the entire string
141-
* is returned. It's also possible to specify just one line to return only
142-
* that line.
140+
* and return them as an array.
143141
*
144-
* @param int $start the starting number
145-
* @param null|int $end the ending number. If not supplied, only the item in $start will be returned.
142+
* If $end is null, it returns array sliced from the $start to the end.
143+
*
144+
* @param int $start the starting number. If null, the whole array will be returned.
145+
* @param null|int $end the ending number. If null, only the item in $start will be returned.
146146
*
147147
* @return string[] array of all of the lines between the specified range
148148
*/
@@ -153,12 +153,12 @@ public function getA(int $start = 0, ?int $end = null): array
153153

154154
/**
155155
* Get a range of lines from $start to $end from the second comparison string
156-
* and return them as an array. If no values are supplied, the entire string
157-
* is returned. It's also possible to specify just one line to return only
158-
* that line.
156+
* and return them as an array.
157+
*
158+
* If $end is null, it returns array sliced from the $start to the end.
159159
*
160160
* @param int $start the starting number
161-
* @param null|int $end the ending number. If not supplied, only the item in $start will be returned.
161+
* @param null|int $end the ending number
162162
*
163163
* @return string[] array of all of the lines between the specified range
164164
*/
@@ -224,14 +224,46 @@ public function render(AbstractRenderer $renderer): string
224224
/**
225225
* The work horse of getA() and getB().
226226
*
227+
* If $end is null, it returns array sliced from the $start to the end.
228+
*
227229
* @param string[] $lines the array of lines
228230
* @param int $start the starting number
229-
* @param null|int $end the ending number. If not supplied, only the item in $start will be sliced.
231+
* @param null|int $end the ending number
230232
*
231233
* @return string[] array of all of the lines between the specified range
232234
*/
233235
private function getText(array $lines, int $start = 0, ?int $end = null): array
234236
{
235-
return \array_slice($lines, $start, ($end ?? $start + 1) - $start);
237+
$arrayLength = \count($lines);
238+
239+
// make $end set
240+
$end = $end ?? $arrayLength;
241+
242+
// make $start non-negative
243+
if ($start < 0) {
244+
$start += $arrayLength;
245+
246+
if ($start < 0) {
247+
$start = 0;
248+
}
249+
}
250+
251+
// may prevent from calling array_slice()
252+
if ($start === 0 && $end >= $arrayLength) {
253+
return $lines;
254+
}
255+
256+
// make $end non-negative
257+
if ($end < 0) {
258+
$end += $arrayLength;
259+
260+
if ($end < 0) {
261+
$end = 0;
262+
}
263+
}
264+
265+
// now both $start and $end are non-negative
266+
// hence the length for array_slice() must be non-negative
267+
return \array_slice($lines, $start, \max(0, $end - $start));
236268
}
237269
}

0 commit comments

Comments
 (0)