Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

formatDescriptor() throws on certain deserialized descriptors with deeply-nested self-references #66

Closed
ninevra opened this issue Jan 25, 2021 · 1 comment · Fixed by #67

Comments

@ninevra
Copy link
Contributor

ninevra commented Jan 25, 2021

When formatDescriptor() is called on a deserialized descriptor of an object with a self-referential property at a nesting depth beyond maxDepth, it may throw a PointerLookupError.

MRE:

const value = {};
const actualDescriptor = concordance.describe({
  a: {
    b: value
  },
  c: value
});

const serializedActual = concordance.serialize(actualDescriptor);
const deserializedActual = concordance.deserialize(serializedActual);

concordance.formatDescriptor(deserializedActual, {maxDepth: 1});

This throws:

  PointerLookupError {
    index: 3,
    message: 'Could not deserialize buffer: pointer 3 could not be resolved',
  }

  › mapPointerDescriptor (node_modules/concordance/lib/serialize.js:321:67)
  › node_modules/concordance/lib/serialize.js:336:14
  › deserializeRecord (node_modules/concordance/lib/serialize.js:255:12)
  › recursor (node_modules/concordance/lib/serialize.js:264:12)
  › deserializeComplex (node_modules/concordance/lib/metaDescriptors/property.js:18:17)
  › node_modules/concordance/lib/serialize.js:336:35
  › deserializeRecord (node_modules/concordance/lib/serialize.js:267:10)
  › Object.recursor [as next] (node_modules/concordance/lib/serialize.js:264:12)
  › Object.next [as recursor] (node_modules/concordance/lib/recursorUtils.js:59:44)
  › Object.formatDescriptor (node_modules/concordance/lib/format.js:74:35)

To reproduce the issue, the following must hold:

  • The provided maxDepth is non-zero
  • The deeply-nested self-reference occurs at a depth greater than maxDepth
  • The shallow self-reference occurs at a depth at most maxDepth
  • The name of the property containing the deeply-nested self-reference is lexically less than the name of the property containing the shallow self-reference

I believe the problem to be that the descriptor is deserialized lazily, and the formatter never calls upon the deeply-nested self-referential value, so when the shallow self-reference is called upon, its pointer references a descriptor that hasn't been deserialized yet.

I first encountered this in AVA, where it can cause an error to be thrown when a snapshot assertion comparing against such a value fails.

I'm working on a PR that may fix this presently.

@ninevra
Copy link
Contributor Author

ninevra commented Jan 25, 2021

diffDescriptors() is also affected; that's AVA's entry point to this.

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 a pull request may close this issue.

1 participant