@@ -176,6 +176,24 @@ export function decodeStream<Wire, Instance extends XdrValue>(
176176 return out ;
177177}
178178
179+ /** Options shared by {@link encodeArray} and {@link decodeArray}. */
180+ export interface XdrArrayOptions {
181+ /**
182+ * Largest element count to accept, defaulting to the XDR maximum of
183+ * 2^32 - 1. Both encoding and decoding throw `XdrError` past this many
184+ * elements. Pass the bound from the XDR definition, so a field declared
185+ * `TimeSlicedPeerData peers<25>` decodes with `maxLength: 25`, or any cap
186+ * you want to enforce, to reject an oversized array before its elements are
187+ * decoded.
188+ */
189+ maxLength ?: number ;
190+ /**
191+ * How many nested schemas may be entered, counting the array itself as the
192+ * first level.
193+ */
194+ maxDepth ?: number ;
195+ }
196+
179197/**
180198 * Encode a list of XDR values as a single length-prefixed XDR variable-length
181199 * array (`T values<>` — a 4-byte count followed by the elements). This is the
@@ -188,25 +206,33 @@ export function decodeStream<Wire, Instance extends XdrValue>(
188206export function encodeArray < Wire , Instance extends XdrValue > (
189207 type : XdrValueConstructor < Wire , Instance > ,
190208 values : readonly Instance [ ] ,
209+ options ?: XdrArrayOptions ,
191210) : Uint8Array ;
192211export function encodeArray < Wire , Instance extends XdrValue > (
193212 type : XdrValueConstructor < Wire , Instance > ,
194213 values : readonly Instance [ ] ,
195214 format : "raw" ,
215+ options ?: XdrArrayOptions ,
196216) : Uint8Array ;
197217export function encodeArray < Wire , Instance extends XdrValue > (
198218 type : XdrValueConstructor < Wire , Instance > ,
199219 values : readonly Instance [ ] ,
200220 format : "hex" | "base64" ,
221+ options ?: XdrArrayOptions ,
201222) : string ;
202223export function encodeArray < Wire , Instance extends XdrValue > (
203224 type : XdrValueConstructor < Wire , Instance > ,
204225 values : readonly Instance [ ] ,
205- format : XdrFormat = "raw" ,
226+ formatOrOptions ?: XdrFormat | XdrArrayOptions ,
227+ maybeOptions ?: XdrArrayOptions ,
206228) : Uint8Array | string {
207- const codec = array ( type . schema , UNBOUNDED_MAX_LENGTH ) ;
208- const bytes = codec . encode ( values . map ( ( v ) => v . toXdrObject ( ) as Wire ) ) ;
209- return encodeBytes ( bytes , format ) ;
229+ const [ format , options ] = splitArrayArgs ( formatOrOptions , maybeOptions ) ;
230+ const codec = array ( type . schema , options . maxLength ?? UNBOUNDED_MAX_LENGTH ) ;
231+ const bytes = codec . encode (
232+ values . map ( ( v ) => v . toXdrObject ( ) as Wire ) ,
233+ { maxDepth : options . maxDepth } ,
234+ ) ;
235+ return encodeBytes ( bytes , format ?? "raw" ) ;
210236}
211237
212238/**
@@ -219,22 +245,42 @@ export function encodeArray<Wire, Instance extends XdrValue>(
219245export function decodeArray < Wire , Instance extends XdrValue > (
220246 type : XdrValueConstructor < Wire , Instance > ,
221247 input : Uint8Array ,
248+ options ?: XdrArrayOptions ,
222249) : Instance [ ] ;
223250export function decodeArray < Wire , Instance extends XdrValue > (
224251 type : XdrValueConstructor < Wire , Instance > ,
225252 input : string ,
226253 format : "hex" | "base64" ,
254+ options ?: XdrArrayOptions ,
227255) : Instance [ ] ;
228256export function decodeArray < Wire , Instance extends XdrValue > (
229257 type : XdrValueConstructor < Wire , Instance > ,
230258 input : Uint8Array | string ,
231- format ?: "hex" | "base64" ,
259+ formatOrOptions ?: "hex" | "base64" | XdrArrayOptions ,
260+ maybeOptions ?: XdrArrayOptions ,
232261) : Instance [ ] {
233- const codec = array ( type . schema , UNBOUNDED_MAX_LENGTH ) ;
234- const wires = codec . decode ( decodeBytes ( input , format ) ) ;
262+ const [ format , options ] = splitArrayArgs ( formatOrOptions , maybeOptions ) ;
263+ const codec = array ( type . schema , options . maxLength ?? UNBOUNDED_MAX_LENGTH ) ;
264+ const wires = codec . decode (
265+ decodeBytes ( input , format as "hex" | "base64" | undefined ) ,
266+ { maxDepth : options . maxDepth } ,
267+ ) ;
235268 return wires . map ( ( w ) => type . fromXdrObject ( w ) ) ;
236269}
237270
271+ /**
272+ * Sort out the trailing `(format?, options?)` arguments of the array helpers,
273+ * where the format may be omitted and the options object take its place.
274+ */
275+ function splitArrayArgs (
276+ formatOrOptions ?: XdrFormat | XdrArrayOptions ,
277+ maybeOptions ?: XdrArrayOptions ,
278+ ) : [ XdrFormat | undefined , XdrArrayOptions ] {
279+ return typeof formatOrOptions === "string"
280+ ? [ formatOrOptions , maybeOptions ?? { } ]
281+ : [ undefined , formatOrOptions ?? maybeOptions ?? { } ] ;
282+ }
283+
238284export function encodeBytes (
239285 bytes : Uint8Array ,
240286 format : XdrFormat ,
0 commit comments