Concise Binary Object Representation (CBOR) Tags for Typed Arrays
Extracted elements (18)
A sizable chunk of the single-byte CBOR tag space (64–87, plus 40–41) is allocated because typed arrays are widely used in data interchange, justifying the code point consumption.
Applying a Homogeneous Array tag (41) to a Typed Array would be redundant and is therefore not provided by this specification.
Column-major order (tag 1040) is allocated from a higher number space than row-major (tag 40) to signal that row-major is the preferred variant; it was included because it is cheap to define and is still in use by some consumers.
Support for both little- and big-endian typed arrays is included despite CBOR being otherwise fully big-endian. This is to allow direct interchange of ArrayBuffers from JavaScript typed arrays without re-encoding each element.
There is no 'preferred' encoding for typed arrays analogous to CBOR's preferred encoding for single numbers. Protocols using these tags must explicitly specify which encoding variants they use if deterministic encoding is required.
The second array in a multi-dimensional array tag (40 or 1040) may be a native CBOR array (major type 4), a Typed Array (tags 64–87), or a Homogeneous Array (tag 41), allowing interoperability with different array representations.
The tag that would signify the little-endian variant of sint8 MUST NOT be used; its tag number (76) is marked as reserved.
For float variants (f==1), the s bit is always zero because IEEE 754 floats are always signed. Tag numbers 88–95 (where s would be 1 for floats) are left free for other specifications.
Tag 1040 defines a column-major multi-dimensional array with the same structure as tag 40 except the first dimension is considered contiguous. It is allocated from the 'first come first served' space (256+) to signal that row-major (tag 40) is preferred.
Tag 40 defines a row-major multi-dimensional array: a CBOR array (major type 4) of two arrays, where the first array lists the dimensions (unsigned integers, non-zero) and the second holds the element data in row-major order.
Tag 41 identifies a classical CBOR array (major type 4) as a homogeneous array whose elements all share the same application model data type. The element type is determined by the type of the first array element.
Tag 68 (which would otherwise be the little-endian uint8 variant) is instead assigned to signify uint8 arrays using clamped conversion ('ToUint8Clamp' per ECMAScript), enabling roundtripping of JavaScript Uint8ClampedArray through CBOR.
Typed arrays are encoded as a CBOR byte string (major type 2) enclosed by a single tag indicating the type and encoding of all numbers. Tag values 64–87 cover 24 variants combining integer/float, signedness, endianness, and element length.
IANA allocated CBOR tags 40, 41, 64–87, and 1040 with this document as the specification reference. Tags 64–87 cover typed arrays; tags 40 and 1040 cover row-major and column-major multi-dimensional arrays; tag 41 covers homogeneous arrays; tag 76 is reserved.
A decoder must not be driven into an undefined state by array elements that violate the homogeneous array tag's promise, since a maliciously constructed CBOR input can tag non-homogeneous data with tag 41. The decoder must continue to fulfill its API contract regardless.
An attacker may substitute a Uint8ClampedArray (tag 68) for a Uint8Array (tag 64) or vice versa, causing unexpected processing semantics. Applications must validate the specific typed array variant during input validation to prevent this.
The tag number for typed arrays uses 5 bit fields within its low 8 bits: constant 0b010, f (0=integer/1=float), s (0=unsigned or float/1=signed), e (0=big-endian/1=little-endian), and ll (length index 0–3). Element byte size is computed as 2**(f+ll).
The total number of elements in a typed array is not encoded explicitly; it is derived from the byte string length divided by the per-element size: bytelength >> (f + ll).