Skip to content

Protect constructors from empty opts #55

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

Merged
merged 2 commits into from
Sep 17, 2018
Merged

Protect constructors from empty opts #55

merged 2 commits into from
Sep 17, 2018

Conversation

jonathantneal
Copy link
Collaborator

@jonathantneal jonathantneal commented Sep 17, 2018

Which issue # if any, does this resolve?

There is a critical issue cloning nodes with children. The internal cloning function calls Node constructors without arguments, but those constructors require them. There were no tests for this. This PR:

  1. Adds a test that triggers the existing error.
  2. Fixes all affected constructors, causing the test to pass.

Please check one:

  • New tests created for this change
  • Tests updated for this change

Some Node constructors require an options argument that is an object (See https://github.com/shellscape/postcss-values-parser/blob/v1.5.0/lib/number.js#L7-L11)

class NumberNode extends Node {
  constructor (opts) {
    super(opts);
    this.type = 'number';
    this.unit = opts.unit || ''; // <- See that opts must present and an object
  }

However, the internal cloneNode function does pass any parameters to constructors (See https://github.com/shellscape/postcss-values-parser/blob/v1.5.0/lib/node.js#L4).

let cloned = new obj.constructor(); // <- See that nothing will be passed

Therefore, when cloning a parent node like rgb(255, 0, 0), this tool throws an error: Cannot read property 'unit' of undefined.

This error has been reported in one of my projects using postcss-values-parser: postcss/postcss-custom-properties#134


This PR allows Node constructors to work without an object.

Could this be slipped into a PATCH release?

@@ -7,7 +7,7 @@ class Comment extends Node {
constructor (opts) {
super(opts);
this.type = 'comment';
this.inline = opts.inline || false;
this.inline = Object(opts).inline || false;
Copy link
Owner

Choose a reason for hiding this comment

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

with Node 4 out of LTS (for some time now) we can accomplish this with a default parameter.

constructor(opts = {})

I know it's six of one, half dozen of another, but I'd rather have the moving in a forward direction there. any objections?

Copy link
Collaborator Author

@jonathantneal jonathantneal Sep 17, 2018

Choose a reason for hiding this comment

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

Thanks for reviewing, @shellscape. I will make this change if this sole argument does not convince you:

Handling opts within the function means accidental arguments like new Comment(null) and new Comment(false) still work.

Handling opts within params means potentially getting errors like Cannot read property 'unit' of null, which may not be descriptive enough.

If you are unconvinced, let me know, and I will make the change within 5 minutes of your decision. 😄

Copy link
Owner

Choose a reason for hiding this comment

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

man, I'd hate to be the dev trying those wonky incantations, but you have a point.

@shellscape shellscape merged commit f321723 into shellscape:master Sep 17, 2018
@shellscape
Copy link
Owner

Cheers 🎉

@jonathantneal
Copy link
Collaborator Author

Thank you so much, @shellscape. May we have a 1.5.1 or 1.6.0 release for this?

According to the commit log @ https://github.com/shellscape/postcss-values-parser/commits/master we are still in PATCH status.

@shellscape
Copy link
Owner

When I get the chance to, yes.

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.

2 participants