fix(info): handle missing deps field without unsigned indexOf wrap
This commit is contained in:
@@ -1399,3 +1399,22 @@ The sandbox test (test 2) creates a sentinel file, serves an index containing `o
|
||||
- `-S nonexistent --noconfirm` → exit 2 (package not found in index)
|
||||
- No-args → exit 1, `--help` → exit 0
|
||||
|
||||
|
||||
## Task 27 — `std.string.indexOf` unsigned-wrap trap (info.d fix)
|
||||
|
||||
- **`std.string.indexOf` returns `ptrdiff_t`** — `-1` means "not found". Assigning it to
|
||||
an unsigned type (`size_t`/`uint`) silently wraps `-1` to `SIZE_MAX`, and a following
|
||||
`if (pos < 0)` guard becomes a compile-time-legal but always-false no-op. Downstream
|
||||
`content[pos .. $]` then throws `ArrayIndexError` — a D `Error` (NOT an `Exception`),
|
||||
so `catch (Exception)` blocks do not trap it and the process aborts.
|
||||
- **`auto` is the safe default**: `auto idx = content.indexOf(key)` infers `ptrdiff_t`,
|
||||
so `if (idx < 0)` works. Only explicit unsigned typing (`size_t pos = ...`) is broken.
|
||||
Audit rule: when declaring a named variable for an `indexOf`/`indexOfSlice` result,
|
||||
always use `ptrdiff_t` (or `auto`).
|
||||
- **D `Error` vs `Exception`**: out-of-bounds slice indexing throws `ArrayIndexError`
|
||||
which derives from `Error`, bypassing `catch (Exception)`. A whole-program crash
|
||||
(uncaught Error) is a strong smell of this class of bug — the run-time failure mode
|
||||
is a naked `core.exception.ArrayIndexError` on stderr.
|
||||
- **Escape in unit tests**: all 8 pre-existing info.d tests used recipes WITH a `deps`
|
||||
field, so the absent-deps path was never exercised. Regression tests must cover the
|
||||
*negative* field, not just happy paths.
|
||||
|
||||
Reference in New Issue
Block a user