Off-by-one comparison against length¶
ID: js/index-out-of-boundsKind: problemSecurity severity: Severity: warningPrecision: highTags: - quality - reliability - correctness - logic - language-features - external/cwe/cwe-193Query suites: - javascript-security-and-quality.qls
Click to see the query in the CodeQL repository
Reading an array element from an index that is greater than the array length always returnsundefined. If the index is compared to the array length using the less-than-or-equal operator<= instead of the less-than operator<, the index could be out of bounds, which may not be intentional and may adversely affect performance.
Recommendation¶
Use less-than (<) rather than less-than-or-equal (<=) when comparing a potential index against the array length. For loops that iterate over every element in an array, use afor...of loop or theforEach method instead of explicitly iterating over all indices.
Example¶
The following example shows a function that intends to check whether an arraya contains an elementelt by iterating over its elements and comparing them toelt. However, the terminating condition of the loop is incorrectly specified asi<=a.length, noti<a.length, soelt will additionally be compared against the valueundefined read from indexa.length, meaning that the function considers every array to containundefined:
functioncontains(a,elt){for(leti=0;i<=a.length;++i)if(a[i]===elt)returntrue;returnfalse;}
The problem can be fixed by using less-than instead of less-than-or-equals:
functioncontains(a,elt){for(leti=0;i<a.length;++i)if(a[i]===elt)returntrue;returnfalse;}
References¶
Mozilla Developer Network:Array.length
Mozilla Developer Network:Array.forEach
Mozilla Developer Network:for…of
Common Weakness Enumeration:CWE-193.