Skip to content

Exported inner_product() reads past the end of its second argument (undocumented precondition) #193

Description

@robertodr

🤖 AI text below 🤖

What

inner_product iterates to v.size() while indexing into w, with no length precondition anywhere.

cpp/monoprop/MPFunctions.cpp:138-146

auto inner_product(const VecD &v, const VecD &w) -> double {
    const auto *v_data = v.data();
    const auto *w_data = w.data();
    double result = 0.0;
    for (size_t i = 0; i < v.size(); ++i) {
        result += v_data[i] * w_data[i];   // out of bounds if w.size() < v.size()
    }
    return result;
}

The declaration in cpp/include/monoprop/MPFunctions.h says nothing about it:

monoprop_EXPORT auto inner_product(const VecD &v, const VecD &w) -> double;

Why this is a problem

This is an exported symbol (monoprop_EXPORT) with an unstated, unchecked precondition. Every current
caller happens to satisfy it:

  • EvalState::dot (dense arm) checks op.size() >= length_ first, and length_ == values_.size()
    for a dense state.
  • ev_and_grad_impl:122 passes scratch.state and scratch.op, both sized to the operator's term
    count.

So there is no live bug today — but the invariant lives entirely in the callers, and neighbouring code
in the same file (EvalState::dot) does bounds-check and throw. The asymmetry is the hazard: the next
caller has nothing telling it the contract exists.

Suggested fix

Document the precondition on the declaration in MPFunctions.h, and add an assert(w.size() >= v.size()) in the definition. Assertions compile out under NDEBUG, so the hot path is untouched.

(If a Clang RelWithDebInfo build is in use, note the separate issue about that configuration
currently leaving assertions enabled.)

Verification

Builds and the existing suite are unaffected; the assert should be exercised by a debug-build run of
just test.


Found by a code-reading review of the repository at 29a8050. No build tree was available, so the
analysis is from source inspection and should be confirmed against a build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions