Skip to content

feat: add toindefarray struct tag option for indefinite-length CBOR arrays#756

Closed
tdnguyenND wants to merge 1 commit intofxamacker:masterfrom
tdnguyenND:feature/toindefarray
Closed

feat: add toindefarray struct tag option for indefinite-length CBOR arrays#756
tdnguyenND wants to merge 1 commit intofxamacker:masterfrom
tdnguyenND:feature/toindefarray

Conversation

@tdnguyenND
Copy link
Copy Markdown

Summary

Add support for encoding Go structs as CBOR indefinite-length arrays using the struct tag option toindefarray.

Usage

type MyStruct struct {
    _      struct{} `cbor:",toindefarray"`
    Data   []byte
    Count  int
}

This encodes as: 9f <field1> <field2> ff (indefinite-length array)
Instead of: 82 <field1> <field2> (definite-length with toarray)

Motivation

CBOR indefinite-length arrays (0x9f ... 0xff) are used in various protocols (e.g. Cardano smart contract datums). Currently there is no way to encode Go structs directly to this format — only definite-length arrays via toarray.

The decoder already handles both definite and indefinite-length arrays for toarray structs, so this change only adds the encoding path.

Changes

  • cache.go: Add toIndefArray flag to struct types, hasToIndefArrayOption(), getEncodingStructToIndefArrayType()
  • encode.go: Add encodeStructToIndefArray() which writes 0x9f header + fields + 0xff break code, wired into getEncodeFuncInternal()
  • toindefarray_test.go: Tests for basic and nested encoding/decoding

Decoding

No decoder changes needed — the existing decoder handles both definite and indefinite-length arrays for toarray structs via getHeadWithIndefiniteLengthFlag().

Tests

All existing tests pass. New tests cover:

  • Basic struct encode/decode roundtrip
  • Nested indefinite-length structs
  • Verified CBOR output format (0x9f header, 0xff break)

…rrays

Add support for encoding Go structs as CBOR indefinite-length arrays
(major type 4, header 0x9f, break 0xff) using the struct tag option
`toindefarray`.

Usage:
    type MyStruct struct {
        _     struct{} `cbor:",toindefarray"`
        Field1 []byte
        Field2 int
    }

This encodes as: 9f <field1> <field2> ff
Instead of:      82 <field1> <field2>  (definite-length with toarray)

Decoding is fully supported since the decoder already handles both
definite and indefinite-length arrays for toarray structs.

Files changed:
- cache.go: Add toIndefArray flag, hasToIndefArrayOption(),
  getEncodingStructToIndefArrayType()
- encode.go: Add encodeStructToIndefArray(), wire into getEncodeFuncInternal()
- toindefarray_test.go: Tests for basic and nested encoding/decoding
@tdnguyenND
Copy link
Copy Markdown
Author

hi @fxamacker can you have a look at this PR?

@fxamacker
Copy link
Copy Markdown
Owner

hi @fxamacker can you have a look at this PR?

Hi @tdnguyenND, thanks for opening this PR!

This PR should include the PR checklist form that is automatically added to PRs (see CONTRIBUTING).

I can try to take a look at the request next weekend (April 11 or 12) if I have the specs and more context. Please open an issue to add this feature with link(s) to the Cardano CBOR specification, etc. (CDDL notation would be ideal if available).

Thanks!

@fxamacker
Copy link
Copy Markdown
Owner

fxamacker commented Apr 11, 2026

Thanks again for submitting this PR to add a feature.

For non-security issues, I reply on weekends because this CBOR library has been self-funded for years (weekends & public holidays & deferred Christmases), with my weekdays used for paid work.

I didn’t receive full specs or related CDDL yet, so I reviewed your PR without that context.

I’m inclined not to include the requested feature because:

  • It is an edge case to encode a struct (length is always known at runtime) into an indefinite-length array.
  • This codec already has a workaround to do this by implementing the cbor.Marshaler interface.

Also, there are security considerations with using indefinite-length values (unrelated to this library).

In general, please consider avoiding indefinite-length if your specifications allow definite-length.

I'm closing this PR, but please feel free to open an issue to discuss adding the feature if I missed anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants