Skip to content

openapi: a $ref beside a path item's $ref is read outside the external-document budgets #818

Open

Description

@fuad-daoud

Problem

#591 lowers the fields written beside a path item's $ref (#577). The loader never models those fields, so the references inside them are resolved during lowering, in resolveSiblingRefs (compilers/openapi/internal/operation/pathitemref.go). It honours AllowExternalRefs, through lowering.Ctx.AllowExternalRefs, but resolves with bare soa.ResolveOptions. The loader's external reader is not there: no VirtualFS, no HTTPClient. When external references are allowed, the library opens those documents itself.

Everything the reader does for an external document is therefore skipped for these references. The concrete, probed case is the source budgets. With Limits.MaxSourceBytes: 2000 and a 13,573-byte big.yaml:

# refused by the loader, as it should be
paths:
  /b:
    get:
      operationId: getB
      parameters:
        - {$ref: './big.yaml#/components/parameters/P'}
      responses: {"200": {description: OK}}

reports openapi/unresolved-ref ... external document .../big.yaml refused: it is past the 2000-byte budget, and the parameter stays out of the IR. The same reference written beside a path item's $ref:

paths:
  /a:
    $ref: '#/paths/~1b'
    put:
      operationId: putA
      parameters:
        - {$ref: './big.yaml#/components/parameters/P'}
      responses: {"200": {description: OK}}
  /b:
    get:
      operationId: getB
      responses: {"200": {description: OK}}

reads the file anyway, with no diagnostic, and putA carries extP. MaxSourceNodes goes the same way, since the reader is where both are charged. The reader's other work, such as reading each document once under one identity, is bypassed as well. That part was not probed.

Expected

A reference beside a path item's $ref leaves the document under the same reader, with the same budgets, as every other reference. The likely shape is to hand the loader's reader, or resolve options built around it, to lowering through the context, in place of the boolean that WithExternalRefs carries today. An alternative is to have the loader model the sibling subtree, so its references resolve in the loader's own pass.

The default compile is unaffected: with external references refused, these references are reported unresolved, as the loader would report them.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions