-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Domain feature must not clobber EventEmitter#domain field. #3922
Comments
+1 I had the same problem earlier today |
I could make a pull request if you have no time to fix it right now.. Because it's really stopping me from doing work on my project. |
/cc @isaacs |
+1 |
This causes a regression on several benchmarks: https://gist.github.com/4747944 At least for now, I'm afraid the name |
Ugh... This breaks any Mongoose schema with a "domain" property. See reports on the mailing list. I'm sure fingers can point both ways between the projects, but this is common enough and a particularly nasty way to fail. Have you had any discussions with them about the issue? |
Why are your Mongoose schema event emitters? It will break much worse if you have schema that have an "emit" or "on" property. |
It's probably not the schemas that are event emitters, but the models/documents that are constructed from them (which will naturally have a "domain" property too). I haven't dug too deep into Mongoose to comment with much confidence past that. I'm the messenger here, having just been bitten hard. I have a lot of Schemas with "domain" properties, and any attempt to create and save one back to MongoDB fails with the following stack trace:
In this case, "github.com" is the value I assigned to my The appropriate fix/workaround may indeed be in the Mongoose project, although they've fingered Node core in their discussions. This seems to me likely to be a common scenario and source of frustration, and it doesn't seem good for both projects to consider the issue "won't fix". I don't think the workaround for this should be "change your schemas." |
+1 |
So... Why are the "models/documents that are constructed from them" EventEmitters? Something is calling EventEmitter.emit() on that object. That is highly unsafe for random bag-o-data objects like you'd expect to be backed by a database. Whatever program is doing this has a hideous and awful bug, which is likely a serious security issue (depending on how the |
These are just standard https://github.com/LearnBoost/mongoose/blob/master/lib/model.js
https://github.com/LearnBoost/mongoose/blob/master/lib/document.js#L919 I see nothing "highly unsafe" about this, and it is, in fact, pretty standard usage of EventEmitter and not a "hideous and awful bug". The problem is, that any given https://github.com/joyent/node/blob/master/lib/events.js#L81 As noted in the bug, anything with a Please take a moment to investigate this further, rather than dismissing it as "likely a serious security issue" (which I doubt). If, in fact, it is a security issue, then it impacts not only every Mongoose deployment, but likely many other places that |
Cross-referencing the issue I just filed with Mongooose: |
The unsafe thing is that you're using an EventEmitter as an arbitrary data store. It's not for that. It has a specific API. It also doesn't "hide" the If
As noted in my response, anything with an |
I'm afraid I can't agree with the point you are making.
Every Node project that inherits If this is your guidance, it'd would also set a good example if Node core would make |
It's not reactionary, it's just common sense. Same reason why you shouldn't let Though I agree that the name 'domain' is unfortunate. |
I agree, in JavaScript there are certain properties of "prime" importance, and you need to code carefully (as is the case for any highly dynamic language). For Node, EventEmitter and its properties reach close to that level, since it is probably one of the most widely inherited classes. If we are at the point where we are going to start canonizing classes and their properties, that is fine. But, let's be explicit about the pros and cons, and what the recommended patterns are. My personal solution would be:
If @issacs solution, as Node's maintainer, is that EventEmitter should not be extended with additional properties, I'll reluctantly follow suit (while raising hell until the hammer falls). However, some things should be done in that case:
The clearly drastic downside of this latter path would be that inheriting "properly" from EventEmitter would be really fugly, looking like:
In my opinion, there's nothing pragmatic or rational in declaring that EventEmitter should be inherited in such a manner. |
Mongoose is at fault here. We need to add domain and friends to our reserved properties list. As for the security concerns, we already store all data in an internal _doc object. Properties are just getters/setters to this store. In 4x we plan on revisiting the document model. If anyone would like to discuss the Mongoose related details further feel free to comment on the Mongoose issue mentioned above. |
I've been burned a lot of times by using class instance objects as bag-o-data stores. It's always a mess. Even using You have a few options:
|
I would like to chime in as someone who just had to track this issue down. I think that assuming that anyone who tries to define a "domain" property is using objects as "bag-o-data" stores is a bit off. In my case, I have a "XyzClient" instance that inherits from EventEmitter. This "XyzClient" reaches into a endpoint, where a set of 5-10 "services" will be made available. In my case one of these services was named "domain". The client then assigned a XyzClient.domain property, for the user to have easy access to this service. Is there a way around this? Sure I can make it XyzClient.foobar('domain') for example. However, at this point how is XyzClient any more wrong then the EventEmitter? Lets just say I made a bad design decision.. which is subjective but I can accept that, regardless the NodeJS team has to EXPECT bad code to be written at times. I mean javascript is not exactly the paragon platform of best coding practices. This is the first issue I've needed to track down on github and found a discussion for, but as a new advocate for NodeJS I am a bit disappointed to see a rather elitist position here of "YOUR CODE WRONG" as opposed to looking at the bigger picture and understanding your users will not write code how you think they should. If you guys wont fix this, I have to think what happens if in version 1.0 of node you guys decide to add a property to EventEmitter or another core class I inherit and depend upon called "CorePublicPropertyOfMyLibraries", in the process of which you break all of my code? Knowing that it's my problem, because well, I shouldn't of added the property to begin with! Sorry this came a little lengthy, but I just wanted to voice my opinion on the importance of a humble foresight into the horrible things your users will do with your libraries. |
@cstockton then don't inherit your prototype from |
That |
What happens here is that EventEmitter uses a field named 'domain' to store its domain, and tries to call
this.domain.enter()
, which is neither documented, nor expected.Solution: At least rename it to '_domain' (like '_events', internal by convention).
Background: I have a Mongoose model with field 'domain' and cannot rename it easily as the database depends on it. Therefore I have no choice but to get back to Node v0.6, until this bug is fixed. Please, help!
The text was updated successfully, but these errors were encountered: