webarkit / webarkit/jsfeatNext

fast_corners.detect writes past the end of the caller's corners array without checking its length

Open
#205 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
12
Forks
4
Avg merge
16h 24m
Merged PRs (30d)
34

Description

Summary

fast_corners.detect(src, corners, border) writes each accepted corner with

pt = corners[corners_cnt];
((pt.x = j), (pt.y = i - 1), (pt.score = score));
corners_cnt++;

and never checks corners_cnt against corners.length. If the caller's pre-allocated pool is smaller than the number of corners the image yields, corners[corners_cnt] is undefined and the assignment throws TypeError: Cannot set properties of undefined.

The pool is the caller's responsibility by design (it is how the detector avoids allocating in a hot loop), so the fix is not necessarily "grow the array" — but failing with a raw TypeError from inside the detector gives the caller nothing to act on.

Why now

Not a regression, and not introduced by #202 — the missing check predates it. But #202 raised the corner count on every image (each row's last candidate was being dropped and is now recovered), which makes an existing borderline pool marginally more likely to overflow. A caller who sized their pool empirically against the old behaviour could start hitting this.

Found during the review of #203.

Suggested direction

Decide deliberately between:

  1. Stop at capacity — write at most corners.length corners and return that count. Cheap, never throws, but silently truncates, which is its own trap.
  2. Throw a diagnostic error naming the pool size and the count reached, so the caller knows exactly what to pre-allocate.
  3. Document the contract and leave the behaviour, if the cost of a per-corner bounds check in the hot loop is judged too high — in which case detect's JSDoc should say plainly that the pool must be large enough and what happens if it is not.

Option 3 is the only one with zero runtime cost, and the check is per accepted corner rather than per pixel, so options 1 and 2 are likely cheaper than they sound. Worth measuring against bench/detectors.bench.ts before deciding.

Whichever is chosen, the same question applies to the other detectors that fill a caller-supplied pool (yape, yape06) — they should end up with one consistent, documented contract rather than three different behaviours.

Related

  • #202 — the off-by-one that raised corner counts
  • #203 — the PR fixing it, where this was flagged

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at fast_corners.detect and inspect how the caller-supplied corners pool is filled, then compare the corresponding yape and yape06 detectors for their current capacity behavior. Run the measurements in bench/detectors.bench.ts before choosing a contract. Done means the chosen overflow behavior is implemented consistently and documented for all three detectors.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
computer-vision
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.