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

fix(marshal)!: Reject null as a substitute for Object.prototype #1328

Merged
merged 5 commits into from
Oct 20, 2022

Conversation

gibson042
Copy link
Contributor

Fixes #1324

Copy link
Contributor

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just comments so far. Review not done yet.

(!canBeMethod(candidate[key]) ||
(!!reject &&
reject(
X`Records cannot contain non-far functions because they may be methods of an implicit Remotable: ${candidate}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message needs revision because there is no longer any such thing as an "implicit Remotable". For this PR, a TODO is adequate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

reject(
X`Records can only have string-named properties: ${candidate}`,
))) &&
(!canBeMethod(candidate[key]) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR, canBeMethod tests desc.value. This PR tests candidate[key]. Where does the new code ensure that candidate is frozen and has no own accessor properties? Were we previously being reflective unnecessarily? Isn't reflective examination the safer style anyway? Is a reflective check significantly slower on XS?

Copy link
Contributor Author

@gibson042 gibson042 Oct 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in canBeValid, where my understanding is that we should return true because e.g. { get foo(){ return nonFunction; } } cannot be any kind of passable other than copyRecord. assertValid still uses checkNormalProperty to reject it, and I've added some tests for coverage.

Comment on lines 112 to 114
(!!check &&
check(
false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reject style?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

check(false, X`A tagRecord must inherit from Object.prototype: ${val}`)),
);

export const checkFunctionTagRecord = makeCheckTagRecord(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is our stance on builtin Function subclasses, such as async functions, generator functions, or async generators? Can these be far functions? These do not directly inherit from Function.prototype, but they do inherit from known primordial prototypes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preserves the existing behavior, which allows far async functions if their prototype chain has been suitably manipulated (e.g., setPrototypeOf(async () => {}, makeTagishRecord('Remotable', getPrototypeOf(async () => {})))) while rejecting generators and async generators—and classes, for that matter—by dint of a non-removable "prototype" property ("Far functions unexpected properties besides .name and .length"). But an (async)generator is basically a callable factory for (async)iterator objects which at their core are a bag of inherited methods, so I could definitely see extending support in that direction, probably with a helper like ExoGenerator(async function* () { … }) to alter the prototype chain and harden responses.

@gibson042 gibson042 self-assigned this Oct 16, 2022
@erights erights self-requested a review October 17, 2022 22:25
Copy link
Contributor

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@gibson042 gibson042 force-pushed the gibson-1324-reject-null-proto branch from 06060c5 to 843fa3e Compare October 20, 2022 15:22
@gibson042 gibson042 force-pushed the gibson-1324-reject-null-proto branch from 843fa3e to 02744b9 Compare October 20, 2022 15:25
@gibson042 gibson042 merged commit 66808be into master Oct 20, 2022
@gibson042 gibson042 deleted the gibson-1324-reject-null-proto branch October 20, 2022 15:34
gibson042 added a commit that referenced this pull request Oct 20, 2022
gibson042 added a commit that referenced this pull request Oct 22, 2022
gibson042 added a commit that referenced this pull request Oct 22, 2022
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 this pull request may close these issues.

marshal: null should not be accepted in place of Object.prototype
2 participants