From<u8> for Mode maps 252 of 256 inputs to Continuous (probably wontfix)

Ouverte
#80 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
25/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
rust
Domaine
embedded-iot

Piste de recherche

Read tmp108.ddsl:27-33 and :40 to understand the documented conversion precondition and generator input, then inspect generated src/inner.rs:794. Check tests/reexports.rs and sources/datasheet.txt:754 for public API and device behavior. Done means confirming the recommended wontfix, or narrowing work to the optional rustdoc clarification.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

audit:SBOS663A impact:latent question verdict:unsupported

Mode is the only one of the five re-exported configuration enums with an
infallible u8 conversion. Polarity, Hysteresis, ConversionRate
and Thermostat all get TryFrom<u8> with
device_driver::ConversionError<u8>; Mode gets:

impl From<u8> for Mode {
    fn from(val: u8) -> Self {
        match val {
            0 => Self::Shutdown,
            1 => Self::OneShot,
            _ => Self::default(),      // Continuous
        }
    }
}

src/inner.rs:794

So 252 of 256 inputs — every value above 3 — silently become
Continuous. tmp108::Mode::from(0x20) reports continuous conversion,
although the M field of the configuration byte 0x20 is 00, shutdown.

This is probably working as intended

Filing for the record rather than as an action item, because the obvious
fixes are all worse than the problem:

The field is two bits wide. Every path inside the driver reaches this
conversion through the generated field accessor, which masks to 1:0
first. Only a caller invoking Mode::from directly on an unmasked byte
can reach the catch-all with an out-of-domain value.

The code is generated. src/inner.rs is machine output from
tmp108.ddsl (AGENTS.md gotcha #2 forbids hand-editing it), and the
catch-all is not an accident of the generator — it is what
tmp108.ddsl:40 asks for:

enum Mode {
    shutdown: 0,
    one-shot: 1,
    continuous: default 2,
},

default is what makes device-driver emit From + catch-all instead of
TryFrom. It is there deliberately, from bbcfbe5 fix!: decode M = 0b11 as continuous mode, because 0b10 and 0b11 are both continuous:

When the TMP108 is in continuous conversion mode (M1 = 1), a single conversion is performed at a rate

SBOS663A §7.4.3, sources/datasheet.txt:754

Getting "accept 0..=3, reject 4.." out of the generator would need either
a fourth enum variant for 0b11 — which would be a worse public API,
since it is not a distinct mode — or hand-edited generated code.

It is already documented. tmp108.ddsl:27-33 spells out the exact
hazard:

From<u8> converts an already-extracted M-field value, not
a whole configuration byte: it neither masks nor validates
its input.

Options

  1. Wontfix. The precondition is documented at the DDSL and flows into
    the generated rustdoc; the field is two bits; no internal path can
    violate it. Recommended.
  2. Strengthen the rustdoc only — e.g. an explicit "callers must mask
    with & 0b11" sentence plus a doctest showing the trap. Cheap,
    non-breaking.
  3. Stop re-exporting the From impl. Not possible without dropping
    the Mode re-export, which tests/reexports.rs pins as public API.

Note on semver

The v0.6.0 tag did export TryFrom<u8> for Mode; the change to From
landed in bbcfbe5, correctly marked fix!. That bump is already owed
and release-plz will take it. No action needed here.

Provenance

Raised by the datasheet compliance audit of PR #77. The audit's architect
agent reported this as a defect requiring a checked conversion and
attributed it to the PR stack; both the severity and the attribution were
wrong, and are corrected above.

Langage dominant
Rust
Étoiles
2
Forks
7
Métriques de merge des PR
Aucune PR mergée en 30 j

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de OpenDevicePartnership/tmp108

Toutes les issues de OpenDevicePartnership/tmp108

Issues similaires

Plus d'issues Rust

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.