Skip to content

Validate TruthTable invariants during deserialization #1142

Description

@isPANN

Problem

TruthTable::from_outputs() requires exactly 2^num_inputs output values, but the custom Deserialize implementation constructs TruthTable directly and bypasses that invariant.

A small malformed value such as:

{"num_inputs": 2, "outputs": [true]}

deserializes successfully. Later operations assume four rows and may index past the stored output vector.

Root cause

The deserialization boundary duplicates construction instead of applying the type invariant. As a result, serialized input can create states that the public constructor rejects.

The expected-length calculation also uses an unchecked native shift, so an unrepresentable 2^num_inputs can panic before a useful deserialization error is produced.

Required behavior

  • Deserialization must reject any output length other than exactly 2^num_inputs.
  • If 2^num_inputs is not representable as usize, deserialization must return an explicit error.
  • Valid serialized truth tables must retain the current representation and round-trip behavior.
  • Do not add compatibility handling for malformed tables.

Keep the invariant in one construction path or perform the same direct validation at the deserialization boundary; do not add a generic validation framework.

Verification

Add focused tests proving:

  1. {"num_inputs":2,"outputs":[true]} is rejected;
  2. both short and extra output vectors are rejected;
  3. an unrepresentable row count returns a deserialization error without panicking;
  4. a valid truth table still round-trips and evaluates every row correctly.

Run make check.

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

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions