mirror of
https://github.com/github/codeql.git
synced 2026-05-04 13:15:21 +02:00
Merge pull request #705 from asger-semmle/loop-index-concurrent-modification
Approved by mc-semmle, xiemaisi
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
| tst.js:4:27:4:44 | parts.splice(i, 1) | Removing an array item without adjusting the loop index 'i' causes the subsequent array item to be skipped. |
|
||||
| tst.js:13:29:13:46 | parts.splice(i, 1) | Removing an array item without adjusting the loop index 'i' causes the subsequent array item to be skipped. |
|
||||
| tst.js:24:9:24:26 | parts.splice(i, 1) | Removing an array item without adjusting the loop index 'i' causes the subsequent array item to be skipped. |
|
||||
@@ -0,0 +1 @@
|
||||
Statements/LoopIterationSkippedDueToShifting.ql
|
||||
@@ -0,0 +1,123 @@
|
||||
function removeX(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') parts.splice(i, 1); // NOT OK
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function removeXInnerLoop(string, n) {
|
||||
let parts = string.split('/');
|
||||
for (let j = 0; j < n; ++j) {
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') parts.splice(i, 1); // NOT OK
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function removeXOuterLoop(string, n) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
for (let j = 0; j < n; ++j) {
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i, 1); // NOT OK
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function decrementAfter(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i, 1); // OK
|
||||
--i;
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function postDecrementArgument(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i--, 1); // OK
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
|
||||
function breakAfter(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i, 1); // OK - only removes first occurrence
|
||||
break;
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function insertNewElements(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i, 1, '.'); // OK - no shifting due to insert
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function spliceAfterLoop(string) {
|
||||
let parts = string.split('/');
|
||||
let i = 0;
|
||||
for (; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') break;
|
||||
}
|
||||
if (parts[i] === 'X') {
|
||||
parts.splice(i, 1); // OK - not inside loop
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function spliceAfterLoopNested(string) {
|
||||
let parts = string.split('/');
|
||||
for (let j = 0; j < parts.length; ++j) {
|
||||
let i = j;
|
||||
for (; i < parts.length; ++i) {
|
||||
if (parts[i] === 'X') break;
|
||||
}
|
||||
parts.splice(i, 1); // OK - not inside 'i' loop
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function removeAtSpecificPlace(string, k) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (i === k && parts[i] === 'X') parts.splice(i, 1); // OK - more complex logic
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function removeFirstAndLast(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (i === 0 || i === parts.length - 1) parts.splice(i, 1); // OK - out of scope of this query
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function inspectNextElement(string) {
|
||||
let parts = string.split('/');
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (i < parts.length - 1 && parts[i] === parts[i + 1]) {
|
||||
parts.splice(i, 1); // OK - next element has been looked at
|
||||
}
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
Reference in New Issue
Block a user