From d3cc887d91df1dfe2d526bd45b350163f0dcad00 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 24 Jul 2026 15:25:47 -0400 Subject: [PATCH] format: tighten type and context validation constraints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six constraint fixes from the schema sweep, each closing a case where an invalid instance validated (or a valid one could not be expressed): - type/elementary: the canonical elementary schemas never forbade a `contains` field, so e.g. {kind: bool, contains: ...} validated as an elementary type while the same object was a *complex* type under type/base — breaking the elementary-vs-complex discriminator. Elementary types now reject `contains`, matching type/base. - type/complex/function: alone among the complex types it had no top-level `required: [kind, contains]`, so {external: true} validated as a function. Now required. - type/complex/function: `parameters` (and the external `contract`) were pinned to a concrete type, so they could not be given as an { id } reference even though `returns` and the wrapper machinery allow it. Both now accept a type reference. - type/elementary/contract: `library` and `interface` were only constrained inside the oneOf consts, so {library: true, interface: 42} passed. Both are now typed `boolean` at the top level. - program/context/name: `name` was a bare string, so `name: ""` validated; it now carries minLength: 1, matching the identifier-like strings elsewhere in the context family. - pointer/region: the location dispatcher's `if` clauses omitted `required: [location]`, so a location-less object vacuously satisfied all seven branches and was rejected only by accident (with errors implicating every region type). `location` is now required at the top level, and each `if` guards on it, so a missing location yields one clear error. --- schemas/pointer/region.schema.yaml | 19 +++++++++++++++++-- schemas/program/context/name.schema.yaml | 1 + schemas/type/complex/function.schema.yaml | 12 ++++++++++-- schemas/type/elementary.schema.yaml | 4 ++++ schemas/type/elementary/contract.schema.yaml | 4 ++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/schemas/pointer/region.schema.yaml b/schemas/pointer/region.schema.yaml index 0ab06a053c..e2f7f5e705 100644 --- a/schemas/pointer/region.schema.yaml +++ b/schemas/pointer/region.schema.yaml @@ -9,24 +9,31 @@ properties: location: $ref: "#/$defs/Location" +required: + - location + allOf: - if: + required: + - location properties: location: const: stack - then: $ref: "schema:ethdebug/format/pointer/region/stack" - if: + required: + - location properties: location: const: memory - then: $ref: "schema:ethdebug/format/pointer/region/memory" - if: + required: + - location properties: location: const: storage @@ -34,6 +41,8 @@ allOf: $ref: "schema:ethdebug/format/pointer/region/storage" - if: + required: + - location properties: location: const: calldata @@ -41,6 +50,8 @@ allOf: $ref: "schema:ethdebug/format/pointer/region/calldata" - if: + required: + - location properties: location: const: returndata @@ -48,6 +59,8 @@ allOf: $ref: "schema:ethdebug/format/pointer/region/returndata" - if: + required: + - location properties: location: const: transient @@ -55,6 +68,8 @@ allOf: $ref: "schema:ethdebug/format/pointer/region/transient" - if: + required: + - location properties: location: const: code diff --git a/schemas/program/context/name.schema.yaml b/schemas/program/context/name.schema.yaml index bbac4c8b48..0c0d48daca 100644 --- a/schemas/program/context/name.schema.yaml +++ b/schemas/program/context/name.schema.yaml @@ -25,6 +25,7 @@ type: object properties: name: type: string + minLength: 1 required: - name diff --git a/schemas/type/complex/function.schema.yaml b/schemas/type/complex/function.schema.yaml index 21b8992e45..b6c61c8736 100644 --- a/schemas/type/complex/function.schema.yaml +++ b/schemas/type/complex/function.schema.yaml @@ -62,6 +62,10 @@ properties: definition: $ref: "schema:ethdebug/format/type/definition" +required: + - kind + - contains + oneOf: - type: object title: External function type @@ -86,7 +90,9 @@ oneOf: title: Contract type wrapper properties: type: - $ref: "schema:ethdebug/format/type/elementary/contract" + oneOf: + - $ref: "schema:ethdebug/format/type/elementary/contract" + - $ref: "schema:ethdebug/format/type/reference" required: - external @@ -161,4 +167,6 @@ $defs: type: object properties: type: - $ref: "schema:ethdebug/format/type/complex/tuple" + oneOf: + - $ref: "schema:ethdebug/format/type/complex/tuple" + - $ref: "schema:ethdebug/format/type/reference" diff --git a/schemas/type/elementary.schema.yaml b/schemas/type/elementary.schema.yaml index 91642bf965..0dfb9168be 100644 --- a/schemas/type/elementary.schema.yaml +++ b/schemas/type/elementary.schema.yaml @@ -8,6 +8,10 @@ type: object properties: kind: $ref: "#/$defs/Kind" + contains: + not: + description: "Elementary types **must not** specify a `contains` field + (to make it easier to discriminate elementary vs. complex)" required: - kind diff --git a/schemas/type/elementary/contract.schema.yaml b/schemas/type/elementary/contract.schema.yaml index df90907758..48d4eeb47d 100644 --- a/schemas/type/elementary/contract.schema.yaml +++ b/schemas/type/elementary/contract.schema.yaml @@ -14,6 +14,10 @@ properties: type: boolean description: If this field is omitted, this type represents an address whose payability is not known. + library: + type: boolean + interface: + type: boolean definition: $ref: "schema:ethdebug/format/type/definition"