{"record":{"id":"b35aaa3edc9946eb","repo":"grafana/k6","slug":"typedarray-parameter-s-length-is-negative","errorCode":null,"errorMessage":"typedArray parameter's length is negative","messagePattern":"typedArray parameter's length is negative","errorType":"panic","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/webcrypto/crypto.go","lineNumber":76,"sourceCode":"\t// 1.\n\tif !IsInstanceOf(c.vu.Runtime(), typedArray, acceptedTypes...) {\n\t\tcommon.Throw(c.vu.Runtime(), NewError(TypeMismatchError, \"typedArray parameter isn't a TypedArray instance\"))\n\t}\n\n\t// 2.\n\t// Obtain the length of the typed array, and throw a QuotaExceededError if\n\t// it's too big, as specified in the [spec's] 10.2.1.2 paragraph.\n\t// [spec]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues\n\tobj := typedArray.ToObject(c.vu.Runtime())\n\tobjLength, ok := obj.Get(\"length\").ToNumber().Export().(int64)\n\tif !ok {\n\t\tcommon.Throw(c.vu.Runtime(), NewError(TypeMismatchError, \"typedArray parameter isn't a TypedArray instance\"))\n\t}\n\n\t// The length property is script-controlled and can be overridden with a\n\t// negative value, which would make the make() call below panic.\n\tif objLength < 0 {\n\t\tpanic(c.vu.Runtime().NewTypeError(\"typedArray parameter's length is negative\"))\n\t}\n\n\tif objLength > maxRandomValuesLength {\n\t\tcommon.Throw(\n\t\t\tc.vu.Runtime(),\n\t\t\tNewError(\n\t\t\t\tQuotaExceededError,\n\t\t\t\tfmt.Sprintf(\"typedArray parameter is too big; maximum length is %d\", maxRandomValuesLength),\n\t\t\t),\n\t\t)\n\t}\n\n\t// 3.\n\t// Create a buffer of a matching size and fill\n\t// it with random values.\n\t//\n\t// We use crypto/rand.Read() here as it will use /dev/urandom or\n\t// an equivalent on Unix-like systems, and CryptGenRandom()","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/webcrypto/crypto.go#L58-L94","documentation":"A generic argument validation guard in GetRandomValues: before filling the buffer with random bytes, the method verifies the passed TypedArray-derived object exposes a usable numeric length; when the extracted length is negative it is rejected. The input at fault is the typedArray argument whose length is negative, which would make the random-byte fill invalid, so the operation aborts before any random data is generated.","triggerScenarios":"Calling crypto.getRandomValues(arr) where arr.length has been manually overridden to a negative number, e.g. Object.defineProperty(arr, 'length', {value: -1}) or a subclass returning a negative length.","commonSituations":"Deliberately adversarial scripts (fuzzing the runtime); buggy custom TypedArray subclasses; accidental property override via Proxy or defineProperty.","solutions":["Don't override the length property of the TypedArray; pass a plain new Uint8Array(n) with a non-negative n.","Replace custom/Proxy-wrapped array objects with genuine TypedArrays before calling.","Validate the array yourself before the call and reject negative lengths."],"exampleFix":"// before\nconst arr = new Uint8Array(16);\nObject.defineProperty(arr, 'length', { value: -1 });\ncrypto.getRandomValues(arr);\n// after\nconst arr = new Uint8Array(16);\ncrypto.getRandomValues(arr);","handlingStrategy":"validation","validationCode":"if (!(buf instanceof Uint8Array) || buf.length < 0) {\n  throw new TypeError('need a TypedArray with non-negative length');\n}\ncrypto.getRandomValues(buf);","typeGuard":"function hasValidLength(v) {\n  return ArrayBuffer.isView(v) && v.length >= 0;\n}","tryCatchPattern":"try {\n  crypto.getRandomValues(buf);\n} catch (e) {\n  if (String(e).includes('length is negative')) {\n    buf = new Uint8Array(buf.byteLength); // recreate pristine array\n    crypto.getRandomValues(buf);\n  } else { throw e; }\n}","preventionTips":["Never override or redefine the length property of TypedArrays.","Avoid Proxy-wrapping or subclassing TypedArrays passed to crypto APIs.","Recreate arrays fresh instead of mutating their metadata."],"tags":["webcrypto","typedarray","javascript","k6"],"backgroundTag":"argument-out-of-range","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-09-20T22:01:45.163Z","contentChangedAt":"2026-09-20T22:01:45.163Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}