t1_off_by_one_slice_BEGIN
Issue (line 2): `items[len(items) - n - 1:]` returns the last `n + 1` items, not `n` (off-by-one).
Fix: `return items[-n:] if n > 0 else []`
t1_off_by_one_slice_END
t2_mutable_default_dict_BEGIN
Issue (line 1): Mutable default argument `history={}` is shared across all calls, leaking visit counts between unrelated callers.
Fix: `def greet(name, history=None):` with `if history is None: history = {}` at the top.
t2_mutable_default_dict_END
t3_command_injection_BEGIN
Issue (line 4): Shell command injection — `directory` from a web form interpolated into a `shell=True` string allows arbitrary command execution.
Fix: `subprocess.run(["ls", directory], capture_output=True, text=True)` (drop `shell=True`, pass argv as a list).
t3_command_injection_END
t4_forgotten_await_BEGIN
Issue (line 3): `httpx.AsyncClient().get(...)` returns a coroutine that is never awaited; the client is also never closed.
Fix: `async with httpx.AsyncClient() as client: response = await client.get(...); return response.json()`.
t4_forgotten_await_END
t5_dict_iter_mutation_BEGIN
Issue (line 2): Mutating `d` while iterating raises `RuntimeError: dictionary changed size during iteration`.
Fix: `return {k: v for k, v in d.items() if v >= 0}` (or iterate `list(d)` if in-place mutation is required).
t5_dict_iter_mutation_END
t6_clean_code_BEGIN
Issue (line N/A): No defects — bounds are validated and `max(lo, min(value, hi))` correctly clamps.
Fix: None required.
t6_clean_code_END
c1_factorial_BEGIN
Issue (line 3): `range(n)` starts at 0, so `result *= 0` makes `factorial(n)` always return 0 for `n >= 1`.
Fix: `for i in range(1, n + 1): result *= i`.
c1_factorial_END
c2_counter_race_BEGIN
Issue (line 6): `self.count += 1` is not atomic; concurrent `increment()` calls from multiple threads lose updates.
Fix: Guard with a `threading.Lock`: `with self._lock: self.count += 1`.
c2_counter_race_END
c3_sql_injection_BEGIN
Issue (line 1): SQL injection — `user_input` concatenated into the query allows arbitrary SQL.
Fix: `cursor.execute("SELECT * FROM users WHERE name = ?", (user_input,))` (parameterized query).
c3_sql_injection_END
c4_file_leak_BEGIN
Issue (line 2): File handle is never closed — leaks the descriptor; relies on GC timing.
Fix: `with open(path, encoding="utf-8") as f: return f.read()`.
c4_file_leak_END
c5_n_plus_1_BEGIN
Issue (line 3): N+1 query (one SELECT per user) plus SQL injection via f-string interpolation of `u.id`.
Fix: Single parameterized query — `db.query("SELECT * FROM posts WHERE user_id IN %s", (tuple(u.id for u in users),))` — then group by `user_id` in Python.
c5_n_plus_1_END
c6_ordered_check_BEGIN
Issue (line 2): `assert` is stripped by `python -O` (validation disappears in production), and `order['total']` is read before key existence is checked (raises `KeyError`).
Fix: Replace with explicit `raise ValueError(...)` after key-presence checks.
c6_ordered_check_END
c7_concat_loop_BEGIN
Issue (line 3): O(n²) string concatenation — `result += line + '\n'` allocates a new string each iteration.
Fix: `return '\n'.join(lines) + '\n'`.
c7_concat_loop_END
c8_mutable_default_BEGIN
Issue (line 1): Mutable default `log: list = []` is shared across calls, accumulating events across unrelated callers.
Fix: `def add_event(event: str, log: list | None = None) -> list:` with `if log is None: log = []`.
c8_mutable_default_END
c9_late_binding_BEGIN
Issue (line 4): Late-binding closure — all lambdas capture the same `v`, which holds the loop's final value when callbacks run.
Fix: `callbacks.append(lambda v=v: print(v))`.
c9_late_binding_END
c10_clean_code_BEGIN
Issue (line N/A): No correctness defects. `sum(data) % 256` is an equivalent and faster alternative.
Fix: Optional simplification: `return sum(data) % 256`.
c10_clean_code_END
