acc-find-infinite-loops

📁 dykyi-roman/awesome-claude-code 📅 2 days ago
1
总安装量
1
周安装量
#47219
全站排名
安装命令
npx skills add https://github.com/dykyi-roman/awesome-claude-code --skill acc-find-infinite-loops

Agent 安装分布

opencode 1
claude-code 1

Skill 文档

Infinite Loop Detection

Analyze PHP code for potential infinite loops and unbounded execution.

Detection Patterns

1. Missing Break Conditions

// BUG: No exit condition
while (true) {
    $item = $queue->pop();
    process($item);
    // No break when queue is empty
}

// BUG: Condition never changes
$running = true;
while ($running) {
    doWork();
    // $running never set to false
}

// BUG: Break inside nested condition
while ($items) {
    foreach ($items as $item) {
        if ($item->isDone()) {
            break; // Only breaks inner loop
        }
    }
}

2. Incorrect Loop Variable Modification

// BUG: Wrong variable incremented
for ($i = 0; $i < count($items); $j++) { // Should be $i++
    process($items[$i]);
}

// BUG: Variable modified in wrong direction
for ($i = 10; $i > 0; $i++) { // Should be $i--
    process($i);
}

// BUG: Loop variable reset
$i = 0;
while ($i < 10) {
    if ($condition) {
        $i = 0; // Resets counter
    }
    $i++;
}

3. Unbounded Recursion

// BUG: No base case
function factorial(int $n): int
{
    return $n * factorial($n - 1); // Never stops
}

// BUG: Base case unreachable
function traverse(Node $node): void
{
    $this->traverse($node->getNext()); // What if getNext returns self?
    // Missing: if ($node === null) return;
}

// BUG: Mutual recursion
function a($n) { return b($n); }
function b($n) { return a($n); } // Infinite cycle

4. Circular References

// BUG: Circular linked list traversal
while ($node !== null) {
    $node = $node->next; // What if list is circular?
}

// BUG: Object graph cycle
function serialize($obj, $visited = []): string
{
    foreach ($obj->getRelations() as $rel) {
        $result .= serialize($rel); // May revisit objects
    }
}

// FIXED:
function serialize($obj, array &$visited = []): string
{
    if (in_array($obj, $visited, true)) {
        return '[circular]';
    }
    $visited[] = $obj;
    // ...
}

5. Event/Listener Loops

// BUG: Event triggers itself
class UserUpdatedListener
{
    public function handle(UserUpdated $event): void
    {
        $user = $event->getUser();
        $user->touch(); // Triggers another UserUpdated event
    }
}

// BUG: Message queue requeue loop
public function handle(Message $message): void
{
    try {
        $this->process($message);
    } catch (Exception $e) {
        $this->queue->publish($message); // Requeues failed message infinitely
    }
}

6. Retry Without Limit

// BUG: Infinite retry
function fetch(string $url): string
{
    while (true) {
        try {
            return $this->httpClient->get($url);
        } catch (Exception $e) {
            sleep(1);
            // No max retries, infinite loop on persistent failure
        }
    }
}

// FIXED:
function fetch(string $url, int $maxRetries = 3): string
{
    $attempts = 0;
    while ($attempts < $maxRetries) {
        try {
            return $this->httpClient->get($url);
        } catch (Exception $e) {
            $attempts++;
            if ($attempts >= $maxRetries) {
                throw $e;
            }
            sleep(1);
        }
    }
}

7. Generator Infinite Yield

// BUG: Generator never ends
function allNumbers(): Generator
{
    $i = 0;
    while (true) {
        yield $i++;
        // Fine for generators, but consuming code may not limit
    }
}

// Usage BUG:
foreach (allNumbers() as $n) {
    echo $n; // Infinite loop
}

8. Database Pagination Without Limit

// BUG: Potentially infinite
$offset = 0;
while (true) {
    $batch = $repository->findBy([], null, 100, $offset);
    if (empty($batch)) {
        break;
    }
    process($batch);
    // Missing: $offset += 100;
}

Grep Patterns

# while(true) without break
Grep: "while\s*\(\s*true\s*\)" --glob "**/*.php"

# Recursion
Grep: "function\s+(\w+)\([^)]*\)[^{]*\{[^}]*\1\s*\(" --glob "**/*.php"

# for loop with wrong increment
Grep: "for\s*\([^;]+;\s*\$\w+\s*[<>]\s*[^;]+;\s*\$(?!\1)" --glob "**/*.php"

# while without modification
Grep: "while\s*\(\s*\$\w+\s*\)" --glob "**/*.php"

Severity Classification

Pattern Severity
Infinite retry without limit 🔴 Critical
Missing recursion base case 🔴 Critical
Wrong loop variable 🔴 Critical
Circular reference traversal 🟠 Major
Event self-triggering 🟠 Major
while(true) without clear exit 🟠 Major

Prevention Patterns

Always Use Limits

const MAX_ITERATIONS = 1000;

$iterations = 0;
while ($condition && $iterations < self::MAX_ITERATIONS) {
    // ...
    $iterations++;
}

if ($iterations >= self::MAX_ITERATIONS) {
    throw new RuntimeException('Max iterations exceeded');
}

Track Visited Nodes

function traverse($node, array &$visited = []): void
{
    $id = spl_object_id($node);
    if (isset($visited[$id])) {
        return;
    }
    $visited[$id] = true;
    // ...
}

Recursion Depth Limit

function process($data, int $depth = 0): mixed
{
    if ($depth > 100) {
        throw new RuntimeException('Max recursion depth');
    }
    return process($child, $depth + 1);
}

Output Format

### Infinite Loop Risk: [Description]

**Severity:** 🔴/🟠/🟡
**Location:** `file.php:line`
**Type:** [Missing Break|Wrong Variable|Unbounded Recursion|...]

**Issue:**
[Description of how infinite loop can occur]

**Code:**
```php
// Problematic code

Fix:

// With proper termination

Trigger Condition: [When this infinite loop would occur]