Skip to content

Guard out-of-bounds accesses in SisoZpk minreal#1060

Merged
baggepinnen merged 2 commits into
masterfrom
fix/sisozpk-minreal-bounds
May 16, 2026
Merged

Guard out-of-bounds accesses in SisoZpk minreal#1060
baggepinnen merged 2 commits into
masterfrom
fix/sisozpk-minreal-bounds

Conversation

@baggepinnen
Copy link
Copy Markdown
Member

Summary

minreal(::SisoZpk, eps) had two unguarded accesses in the pole-zero cancellation loop:

  • newZ[zidx+1] = real(newZ[zidx+1]) assumed the matched complex zero had a conjugate partner immediately after it.
  • After pidx += 1, sys.p[pidx] was indexed without checking whether another pole existed.

Both raise BoundsError on malformed inputs or on inputs that become so after the loop's earlier deleteat! operations. The fix adds the missing checks (still removing the matched zero in the second case for consistency).

Test plan

  • Run existing test_zpk.jl / minreal tests.
  • Hand-construct a pathological SisoZpk (e.g. a complex zero at the end of the z vector without its conjugate partner) and verify minreal no longer throws.

🤖 Generated with Claude Code

The pole-zero cancellation loop accessed `newZ[zidx+1]` (assuming the
matched complex zero has a conjugate partner immediately after it) and
`sys.p[pidx]` after `pidx += 1` (assuming another pole exists) without
bounds checks. Both raise `BoundsError` on malformed inputs (or inputs
that become so after earlier `deleteat!` operations).

Add a `zidx < length(newZ)` check before the conjugate-cleanup, and
break out of the loop after incrementing `pidx` past the available
poles (still removing the matched zero for consistency).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JuliaControlBot
Copy link
Copy Markdown

This is an automated message.
Plots were compared to references. 4/11 images have changed, see differences below.
After pulling this PR, please update the reference images by creating a PR to ControlExamplePlots.jl here.

Difference Reference Image New Image
✔️ 0.0 Reference New
✔️ 0.0 Reference New
✔️ 0.0 Reference New
✔️ 0.0 Reference New

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.55%. Comparing base (0aa6e4c) to head (925eaa5).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1060      +/-   ##
==========================================
- Coverage   91.61%   91.55%   -0.07%     
==========================================
  Files          42       42              
  Lines        5653     5660       +7     
==========================================
+ Hits         5179     5182       +3     
- Misses        474      478       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Construct complex-valued zpk inputs that exercise both unguarded
accesses in the cancellation loop (lines 83 and 87 of SisoZpk.jl):
one where a real pole matches a -imag complex zero whose conjugate
partner was already deleted (newZ[zidx+1] out of bounds), and one
where a complex pole at the last index is increment-matched past the
end of sys.p. Both inputs threw BoundsError on master and now return
the fully cancelled `zpk([], [], k)`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@baggepinnen baggepinnen merged commit 856eb2b into master May 16, 2026
4 of 5 checks passed
@baggepinnen baggepinnen deleted the fix/sisozpk-minreal-bounds branch May 16, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants