65 lines
3.3 KiB
Markdown
65 lines
3.3 KiB
Markdown
# Review checklist
|
|
|
|
Ask these per function. Skip what does not apply; stop at the first real problem
|
|
in a function and verify it before going on.
|
|
|
|
## Inputs and edge cases
|
|
- Empty (`[]`, `""`, `{}`), zero, negative, very large, None/null/undefined?
|
|
- First/last element, off-by-one in ranges and slices, inclusive vs exclusive end?
|
|
- Unicode, whitespace, different line endings, case differences?
|
|
- Duplicate keys/ids, unsorted input, input that changes while iterating?
|
|
|
|
## Errors
|
|
- Which calls can fail (I/O, parsing, network, lookups)? What happens then?
|
|
- Errors swallowed (`except: pass`, empty `catch {}`), or turned into a wrong
|
|
default that flows on (None, 0, "")?
|
|
- Is the error message useful? Is cleanup done on the error path
|
|
(files/sockets/locks closed - `with`, `try/finally`, RAII)?
|
|
- Retries without limit or backoff? Timeouts missing on network/subprocess calls?
|
|
|
|
## State and data flow
|
|
- Is every variable initialised on every path? Used after being freed/closed?
|
|
- Shared mutable state: module globals, class attributes, mutable default
|
|
arguments, objects passed by reference and then modified?
|
|
- Two representations of the same thing that can drift apart (cache vs source,
|
|
UI vs model, serialized format vs in-memory)?
|
|
- Save/load and export/import: is every field written AND read back?
|
|
|
|
## Security (wherever input crosses a boundary)
|
|
- Shell: command built from input with string formatting / `shell=True`?
|
|
- Paths: input joined into a path without checking `..` and absolute paths?
|
|
- SQL / HTML / JS: string concatenation instead of parameters / escaping
|
|
(`innerHTML`, template strings into the DOM)?
|
|
- Secrets in code, logs or error messages? `eval`/`exec`/`pickle` on input?
|
|
- Downloads/requests: TLS verification disabled, URLs from input (SSRF)?
|
|
|
|
## Concurrency and async
|
|
- Awaited everything that returns a promise/coroutine? Fire-and-forget errors lost?
|
|
- Check-then-act races (exists() then open(), read-modify-write without lock)?
|
|
- Event handlers registered repeatedly (leak) or never removed?
|
|
|
|
## Performance (only if it matters at the expected size)
|
|
- Work inside a loop that belongs outside (re-reading files, re-compiling regexes,
|
|
O(n^2) membership tests on lists)?
|
|
- Unbounded growth: caches, histories, listeners, logs?
|
|
|
|
## Language specifics
|
|
- **Python:** `is` vs `==`, late-binding closures in loops, `except Exception`
|
|
catching too much, integer vs float division, iterator consumed twice,
|
|
`open()` without `encoding=`.
|
|
- **JavaScript:** `==` coercion, `this` in callbacks, missing `await`,
|
|
`parseInt` without radix, `forEach` with async callbacks, module scope vs
|
|
inline `onclick`, floating point money/coordinates.
|
|
- **C/C++:** buffer sizes (`strcpy`, `sprintf`, missing `\0`), signed/unsigned
|
|
comparisons, integer overflow, missing `return`, ownership/double free,
|
|
uninitialised memory, `sizeof(pointer)` vs `sizeof(array)`.
|
|
- **Java:** `==` on strings/boxed types, unclosed streams (try-with-resources),
|
|
`equals` without `hashCode`, swallowed `InterruptedException`.
|
|
- **PHP:** `==` juggling, unescaped output (`htmlspecialchars`), SQL without
|
|
prepared statements, `include` with input.
|
|
- **Shell:** unquoted variables, missing `set -euo pipefail`, `cd` without check.
|
|
|
|
## Tests
|
|
- Do tests exist for the changed behaviour? Do they assert the result, or only
|
|
that nothing crashed? Would they fail if the bug above were present?
|