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(Variables): Properly resolve vars if prototype in path #8962

Conversation

pgrzesik
Copy link
Contributor

Properly resolve variables if prototype is present in path to property where that variable should be replaced. Bug was caused by _.set preventing updates if prototype is present and resulted in infinite loop in variables resolver.

Closes: #8956

@codecov
Copy link

codecov bot commented Feb 17, 2021

Codecov Report

Merging #8962 (9279a86) into master (c08b232) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #8962   +/-   ##
=======================================
  Coverage   87.68%   87.69%           
=======================================
  Files         268      268           
  Lines       10045    10050    +5     
=======================================
+ Hits         8808     8813    +5     
  Misses       1237     1237           
Impacted Files Coverage Δ
lib/classes/Variables.js 99.73% <100.00%> (+<0.01%) ⬆️
lib/plugins/aws/package/compile/functions.js 96.23% <100.00%> (+0.02%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c08b232...ea6544c. Read the comment docs.

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

@pgrzesik thanks for tackling that. Still I think this will crash in some situations. See my comment

// security vulnerabilities.
const pathArray = Array.isArray(result.path) ? result.path : result.path.split('.');
if (pathArray.length > 1) {
_.get(target, pathArray.slice(0, -1))[pathArray.slice(-1)] = result.populated;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it won't work if object for which property is destined doesn't already exists, e.g.

obj = {};
_get(obj, ['one'])['two'] = 'value'; // Crash

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's true - I thought about it and I believe in this particular case it's impossible because during assignment, we only deal with paths that are present and point to a value which has a variable that should be resolved. Am I missing something here and we can have a situation where we're resolving variable that will be assigned to a property that didn't exist before?

Copy link
Contributor

@medikoo medikoo Feb 17, 2021

Choose a reason for hiding this comment

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

Indeed, so maybe in that case let's simplify it to not rely on _.get (_.get has built in mechanism which ensures we will not crash if path doesn't exist, and here I believe we do not need it). e.g.

const obj = target;
for (const property of path) obj = obj[property];

Copy link
Contributor Author

Choose a reason for hiding this comment

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

great idea - I've adjusted my implementation

@pgrzesik pgrzesik force-pushed the ensure-proper-variable-resolution-if-prototype-property-is-involved branch from 3e58ed8 to b7fd7c0 Compare February 17, 2021 14:37
Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

Thank you @pgrzesik ! I have some final, more style related suggestions. Let me know what you think

Comment on lines 311 to 313
// We could not use direct `_.set` as due to security measures, it did not allow setting values
// if `prototype` was a part of the path and that caused an infinite loop. In our use-case, there are no
// security vulnerabilities.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can get rid of that comment

At least it's not a real _.set use case (which is more about ensuring that nested objects on they way exist).

Even if _.set would work ok, I think I'd prefer current approach (as _.set confuses what we really deal with here)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed 👍

Comment on lines 316 to 317
for (const property of pathArray.slice(0, -1)) obj = obj[property];
obj[pathArray.slice(-1)] = result.populated;
Copy link
Contributor

Choose a reason for hiding this comment

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

In last line we pass array as property name, and it works by a chance of array stringification.

I would probably literally reference last property via e.g. _.last(pathArray)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call, changed

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

@pgrzesik push :)

@pgrzesik pgrzesik force-pushed the ensure-proper-variable-resolution-if-prototype-property-is-involved branch from b7fd7c0 to ea6544c Compare February 17, 2021 15:45
@pgrzesik
Copy link
Contributor Author

sorry 🤦 Pushed now

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

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

👍

@pgrzesik pgrzesik merged commit 496d357 into master Feb 17, 2021
@pgrzesik pgrzesik deleted the ensure-proper-variable-resolution-if-prototype-property-is-involved branch February 17, 2021 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using ${env:VAR} hangs
2 participants