Why is this an issue?

The upper range of for loops is inclusive in Delphi, meaning that a typical zero-based collection iteration should start at 0 and end at one before the array length:

for I := 0 to Length(Array) - 1 do
  WriteLn(Array[I]);

Forgetting to subtract one from the length of the collection is a common mistake in Delphi code, especially since in most other languages the convention is for the upper bound to be exclusive. If forgotten, this may cause access violations, buffer overruns, and other memory issues.

When using non zero-based collections, the Low and High intrinsics should be used instead of iterating based on length.

This rule catches suspicious cases of System.Length or Count properties being used as an upper bound. Iterations over strings are excluded as they are typically one-based.

How to fix it

If the collection is zero-based, subtract one from the upper bound:

for I := 0 to Length(Array) do
  WriteLn(Array[I]);
for I := 0 to Length(Array) - 1 do
  WriteLn(Array[I]);

If the collection is not zero-based, use the Low and High intrinsics to iterate instead:

for I := 1 to Length(Array) do
  WriteLn(Array[I]);
for I := Low(Array) to High(Array) do
  WriteLn(Array[I]);

Resources