Nested generic rules get the wrong argument when the outer rule is instantiated more than once

Ouverte
#215 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
45/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Domaine
devtools

Piste de recherche

Start by reproducing with the nested.cddl schema and value.cbor (82 81 82 00 01 81 82 00 61 61) using cuddle validate-cbor root value.cbor nested.cddl -f binary. The trace labels the nested instance %inner<x> instead of the substituted argument, so look at how generic rule arguments are substituted and how instances are named and shared during validation. Done when the reproducer prints Validation successful and the existing controls in the table still behave the same.

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

Description

bug

Summary

When a generic rule passes its parameter on to another generic rule, and the
outer rule is instantiated more than once in the same file with different
arguments, validate-cbor checks the nested rule with the argument of a
different instantiation. Valid CBOR is then rejected.

The validation trace suggests why: the nested instance is labelled with the
outer rule's formal parameter name (%inner<x>) rather than with the
substituted argument (%inner<int>, %inner<tstr>), so all instantiations of
the outer rule seem to share one nested instance.

Version: cuddle 1.8.1.0.

Reproducer

nested.cddl:

root = [a, b]

a = outer<int>
b = outer<tstr>

outer<x> = [inner<x>]
inner<y> = [0, y]

value.cbor is [[[0, 1]], [[0, "a"]]], which matches root:

82 81 82 00 01 81 82 00 61 61
$ cuddle validate-cbor root value.cbor nested.cddl -f binary
array
└ failed to apply required rule:
  └ ref: a
    └ ref: %outer<int>
      └ array
        └ failed to apply required rule:
          └ ref: %inner<x>
            └ array
              └ 1 valid elements
                failed to apply required rule:
                └ failed to apply:
                    text

Validation failed

Inside a = outer<int>, the nested inner<x> is checked against text, the
argument of the other instantiation (b = outer<tstr>), so the integer 1 is
rejected.

Expected

Validation successful: a is [[0, int]] and b is [[0, tstr]].

Controls

All against [[[0, 1]], [[0, "a"]]] unless noted:

Variant Result
As above (outer instantiated twice, nested generic inner) fails
Only one instantiation (root = a, value [[0, 1]]) passes
outer inlined, no nested generic: outer<x> = [[0, x]] passes
Definitions of a and b in the opposite order fails the same way
root = [b, a] with value [[[0, "a"]], [[0, 1]]] fails the same way (%outer<int> → %inner<x> → text)
inner's parameter also named x (inner<x> = [0, x]) fails

So it takes two instantiations of the outer rule, and the order of the rules
or of the elements doesn't matter. cuddle validate nested.cddl accepts the
schema without complaint.

Where we hit it

ouroboros-consensus describes hard-fork-combinator state with

telescope8<byron, shelley, ..., dijkstra>
  = [pastEra, ..., currentEra<dijkstra>] / ...
currentEra<st> = [bound, st]

and uses telescope8 several times in the same file (for the ledger state and
for the chain-dependent state), which has the same shape as the reproducer:
the generic telescope8 passes its parameters on to the generic currentEra.
Valid snapshots were rejected until we worked around it by writing
currentEra<st> out inline as [bound, st] inside telescope8.

Langage dominant
Haskell
Étoiles
8
Forks
5
Merge moyen
3 j 12 h
PR mergées (30 j)
4

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

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 IntersectMBO/cuddle

Toutes les issues de IntersectMBO/cuddle

Issues similaires

Plus d'issues Haskell

Recevez les nouvelles issues par e-mail

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