flatbuffers icon indicating copy to clipboard operation
flatbuffers copied to clipboard

[TS] Flexbuffers fails to decode root vector

Open Stumblinbear opened this issue 2 years ago • 13 comments

This was noticed in version 23.1.21 however is still occurring in the latest version (23.3.3).

When decoding a flexbuffer where the root element is a vector, it fails to decode properly when there are 4 or more items. If the vector is nested within an object it decodes successfully.

RangeError: Offset is outside the bounds of the DataView
    at DataView.getUint8 (<anonymous>)
    at Reference.get (reference.js:102:45)
    at <snip>

Minimum reproducible example:

import * as flexbuffers from "flatbuffers/ts/flexbuffers";

flexbuffers.toObject(
    flexbuffers.encode(["1", "2", "3", "4"]).buffer
)

Stumblinbear avatar Mar 06 '23 11:03 Stumblinbear

@bjornharrtell

dbaileychess avatar Mar 15 '23 02:03 dbaileychess

Unfortunately I have no experience with flexbuffers so this is far off my chart at the moment.

bjornharrtell avatar Mar 15 '23 06:03 bjornharrtell

@Stumblinbear did you ever find a resolution for this? I'm running into the same issue.

lenaguerrero avatar Sep 13 '23 17:09 lenaguerrero

@Stumblinbear did you ever find a resolution for this? I'm running into the same issue.

I've just nested it in an object with a single field for the time being

Stumblinbear avatar Sep 13 '23 19:09 Stumblinbear

I believe I have a lead on this. In https://github.com/google/flatbuffers/blob/master/ts/flexbuffers/reference.ts#L109 it attempts to read the packed type from the end of the vector, even if the reference is a typed vector and has no type bytes at the end. This will intermittently fail if you don't have enough extra bytes at the end of your buffer which is probably why nesting it in an object "fixes" the problem.

The solution might be to only look for the packed type bytes in the else condition of the conditional on the next line:

let _packedType = -1;
if (isTypedVector(this.valueType)) {
  const _valueType = typedVectorElementType(this.valueType);
  _packedType = packedType(_valueType, BitWidth.WIDTH8);
} else if (isFixedTypedVector(this.valueType)) {
  const _valueType = fixedTypedVectorElementType(this.valueType);
  _packedType = packedType(_valueType, BitWidth.WIDTH8);
} else {
 _packedType = this.dataView.getUint8(_indirect + length * this.byteWidth + key);
}

dristic avatar Sep 21 '23 00:09 dristic

This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.

github-actions[bot] avatar Mar 21 '24 20:03 github-actions[bot]

This is still an issue

Stumblinbear avatar Mar 22 '24 22:03 Stumblinbear