Uh oh!
There was an error while loading. Please reload this page.
http: don't inherit from Object.prototype - #6102
Conversation
This commit safely allows header names that are named the same as properties that are ordinarily inherited from Object.prototype such as __proto__.
mscdex
commented
Apr 7, 2016
CI: https://ci.nodejs.org/job/node-test-pull-request/2205/ I also took the liberty of putting the prototype-less constructor in |
mscdex
commented
Apr 7, 2016
One other thing to note: the check introduced by 2a1ef97 was already preventing weird things from happening when setting header names that coincide with |
mscdex
commented
Apr 7, 2016
jasnell
commented
Apr 7, 2016
This one could be fairly significant given how extensively the That said, the change LGTM |
Fishrock123
commented
Apr 7, 2016
Everyone accesses |
mscdex
commented
Apr 7, 2016
So it looks like there is a problem that is going to be a common theme for any of these instances where we replace I'm not sure what to do about that... |
jasnell
commented
Apr 7, 2016
Yeah, that's the kind of breakage I was afraid of. I'm not sure there's So it looks like there is a problem that is going to be a common theme for — |
mscdex
commented
Apr 7, 2016
I suppose these libraries could monkey-patch varcreate=Object.create;Object.create=function(){varobj=create.apply(null,arguments);if(obj.prototype==null)obj.prototype=Object.prototype;returnobj;};Yeah it's hacky, but then again they're already mutating |
jasnell
commented
Apr 7, 2016
That's pretty ugly. I'm wondering if there's a chance anything can be done
|
Fishrock123
commented
Apr 7, 2016
Idea: we expose a base null object and let people set onto that for these, then we inherit from it. |
mscdex
commented
Apr 7, 2016
@Fishrock123 So in this case you're saying expose |
Fishrock123
commented
Apr 7, 2016
I would actually expose a "BaseObject" directly (Which would be a I'm not 100% that is a good idea, but it is what first comes to mind.. |
mscdex
commented
Apr 7, 2016
@Fishrock123 Wouldn't exposing the prototype vs the constructor complicate things by having to lazily set the constructor's prototype? |
Fishrock123
commented
Apr 7, 2016
@mscdex Wouldn't it still have the same reference everwhere? I don't think there would actually need to be lazy loading or special hooks. |
mscdex
commented
Apr 7, 2016
@Fishrock123 Oh I thought you meant have the ability to replace the prototype entirely and not just mutate it. |
jasnell
commented
Apr 8, 2016
working through the options I think it's likely going to be ok to simply require that if someone wants to treat these return values as objects they'll need to set the prototype themselves. We could make it slightly easier by providing a utility function but doing so isn't critical. It is a semver-major change, after all. constheaders=Object.setPrototypeOf(req.headers,Object.prototype);or, using a utility method: constheaders=util.asObject(req.headers); |
evanlucas
commented
Apr 8, 2016
If this breaks |
addaleax
commented
Apr 8, 2016
|
evanlucas
commented
Apr 8, 2016
@addaleax That is a good point |
evanlucas
commented
Apr 8, 2016
@addaleax but that will be null as a string, not the |
addaleax
commented
Apr 8, 2016
@evanlucas Hm yeah, you’re right… this still feels like the right kind of thing to do. At least for HTTP, where incoming headers are always converted to lower-case, maybe one could cherry-pick |
jasnell
commented
Apr 20, 2016
Hmm... that's certainly possible. I would just be a bit worried about user expectations... that is, if the thing has |
mscdex
commented
Apr 20, 2016
I think I tend to agree that cherry picking methods like that could be misleading, so it should be all or nothing IMHO. |
mscdex
commented
Apr 20, 2016
Do any other @nodejs/collaborators have any suggestions/opinions/comments/etc. about this? Does @jasnell's suggestion about simply requiring end users to call /cc @btd too as he seems to be the maintainer of |
jasnell
commented
Apr 20, 2016
We should get some feedback from folks like @dougwilson also |
MylesBorins
commented
Dec 29, 2016
@mscdex is this something we still want to explore? |
jasnell
commented
Dec 29, 2016
This is still something that ultimately should happen but there's still quite a bit of uncertainty around what would actually break. If we're going to do it, then I'm thinking we should be printing deprecation warnings whenever any Object.prototype methods or properties are accessed on this object in Node.js 8.0.0 and actually do switch in Node.js 9.0.0 |
mscdex
commented
Dec 29, 2016
@thealphanerd I've always been for it, hence the PR, but the issue for |
fhinkel
commented
Mar 26, 2017
ping @mscdex |
mscdex
commented
Mar 26, 2017
@fhinkel This will be stalled until either the breakage is no longer a concern or the community is weaned off of the likes of |
richardlau
commented
Mar 26, 2017
Sorry, accidental close. |
ljharb
commented
Mar 26, 2017
@mscdex given that the breakage should always be a concern, and 15+ years of it being a bad practice to chain |
mscdex
commented
Mar 26, 2017
@ljharb That was just one example though. As mentioned earlier in this PR, another example is users adding to |
ljharb
commented
Mar 26, 2017
Gotcha. I consider "should" patterns deprecated in favor of "expect" patterns, but just like normal chaining that's still going to be around forever. Has the CTC been able to discuss this yet and come to a conclusion? If not, could it go on the agenda? |
refack
left a comment
There was a problem hiding this comment.
Add note about type in docs
refack
commented
May 16, 2017
If this ever matures is should include notes in the docs similier to e1cabf6#diff-69e1ac0b5bfc06e74f2c1ab7b062c6af |
Trott
commented
Aug 16, 2017
@mscdex Should this remain open? Does it make sense to at least rebase so we can CITGM it again? |
jasnell
commented
Aug 24, 2017
Going to close this due to lack of forward progress. @mscdex ... when you're ready to revisit this, feel free to reopen or open a new PR |
Checklist
Affected core subsystem(s)
Description of change
This commit safely allows header names that are named the same as properties that are ordinarily inherited from
Object.prototypesuch as__proto__.