Audit finding
- ID:
AUD-010
- Status: Verified defect
- Severity: High
- Confidence: High
- Audited revision:
2f479320d805a1f9f35ebe4afaaeeded48913a94
Problem
FrequencyResponse::Calculate() appends to three bounded member vectors without clearing or overwriting them. The public object appears reusable, but a second call exceeds capacity and aborts.
Source:
|
FrequencyResponse<T, NumberOfPoints>::Calculate() |
|
{ |
|
const auto maxSize = static_cast<T>(response.max_size()); |
|
const auto fstart = sampleFrequency / maxSize; |
|
const auto fend = sampleFrequency / static_cast<T>(2); |
|
const auto multiplier = static_cast<T>(math::Pow(static_cast<double>(fend / fstart), 1.0 / (static_cast<double>(maxSize) - 1.0))); |
|
|
|
for (std::size_t n = 0; n < response.max_size(); ++n) |
|
{ |
|
auto f = fstart * static_cast<T>(math::Pow(static_cast<double>(multiplier), static_cast<double>(n))); |
|
auto omega = static_cast<T>(2) * static_cast<T>(std::numbers::pi) * f / sampleFrequency; |
|
|
|
std::complex<T> numerator(static_cast<T>(0), static_cast<T>(0)); |
|
std::complex<T> denominator(static_cast<T>(0), static_cast<T>(0)); |
|
|
|
for (std::size_t i = 0; i < b.size(); ++i) |
|
numerator += b[i] * std::polar(static_cast<T>(1), -omega * static_cast<T>(i)); |
|
|
|
for (std::size_t i = 0; i < a.size(); ++i) |
|
denominator += a[i] * std::polar(static_cast<T>(1), -omega * static_cast<T>(i)); |
|
|
|
if (denominator == static_cast<T>(0)) |
|
denominator.real(static_cast<T>(1)); |
|
|
|
auto h = numerator / denominator; |
|
auto magnitude = std::max(std::abs(h), std::numeric_limits<T>::min()); |
|
|
|
frequencies.emplace_back(f); |
|
response.emplace_back(static_cast<T>(20) * math::Log10(magnitude)); |
|
phase.emplace_back(std::arg(h) * static_cast<T>(180) / static_cast<T>(std::numbers::pi)); |
|
} |
|
|
|
return std::make_tuple(frequencies, response, phase); |
Reproduction
Construct FrequencyResponse<float, 8> with numerator/denominator {1} and call Calculate() twice. The second call asserts in BoundedVector::emplace_back. Current determinism coverage compares two fresh objects instead.
Acceptance criteria
Audit finding
AUD-0102f479320d805a1f9f35ebe4afaaeeded48913a94Problem
FrequencyResponse::Calculate()appends to three bounded member vectors without clearing or overwriting them. The public object appears reusable, but a second call exceeds capacity and aborts.Source:
numerical-toolbox-cpp/numerical/control_analysis/FrequencyResponse.hpp
Lines 51 to 83 in 2f47932
Reproduction
Construct
FrequencyResponse<float, 8>with numerator/denominator{1}and callCalculate()twice. The second call asserts inBoundedVector::emplace_back. Current determinism coverage compares two fresh objects instead.Acceptance criteria
TEST_Fonfloat.