14:52 | <r3st> | Howdy all, can someone help me understand what 'toString' is? Is it a function object? I don't get it at all. |
14:53 | <jmdyck> | There are built-in functions named 'toString', yes. |
14:54 | <jmdyck> | e.g. Object.prototype.toString, Boolean.prototype.toString |
14:55 | <jmdyck> | Within the spec, there's also ToString (note the capital T ) which is something different. |
14:55 | <r3st> | So this is the part of the specification that pertains to it? https://262.ecma-international.org/12.0/#sec-built-in-function-objects |
14:55 | <r3st> | Thank you for the help btw |
14:57 | <jmdyck> | Yup, that section does pertain to the built-in toString functions, but it's not the only pertinent section. |
14:57 | <jmdyck> | Each built-in toString function has its own section in the spec. |
14:59 | <jmdyck> | e.g. Object.prototype.toString is defined here: https://tc39.es/ecma262/#sec-object.prototype.tostring |
15:01 | <r3st> | Okay, got it. So there's one for each primitive type? |
15:02 | <r3st> | That makes sense. |
15:03 | <r3st> | I have another tangential question. |
15:04 | <r3st> | The expression statement "toString.constructor" is the function constructor for the "toString" method. This is the section related to it, right? https://tc39.es/ecma262/#sec-function-constructor |
15:06 | <r3st> | TLDR, I'm trying to understand how ECMAScript evalutaes the statement "toString.constructor.prototype". |
15:07 | <jmdyck> | Hm... |
15:09 | <jmdyck> | None of the built-in toString functions has a property named constructor , so I wouldn't expect toString.constructor to mean anything. |
15:09 | <jmdyck> | oh no, wait |
15:09 | <jmdyck> | They don't have an own property by that name, |
15:10 | <jmdyck> | but they all have Function.prototype as their [[Prototype]] |
15:10 | <r3st> | So it's accessed by the prototype chain, got it |
15:12 | <jmdyck> | Yup, Function.prototype has a property named constructor , whose value is (initially at least) the Function object. |
15:14 | <jmdyck> | So initially, toString.constructor.prototype would refer to the Function.prototype object. |
15:14 | <jmdyck> | I think I got that right. |
15:17 | <r3st> | Okay. So to summarize: The built-in function =toString= links to the function object Function via the prototype chain. |
15:17 | <r3st> | How did you add that formatting to the chat? |
15:17 | <jmdyck> | backticks |
15:18 | <r3st> | classic |
15:19 | <r3st> | Thanks a lot for your help jmdyck |
15:20 | <jmdyck> | Mind you, I don't think you're guaranteed that there's a toString in the global scope. |
15:23 | <jmdyck> | Yeah, I think that's up to the host. |
15:23 | <r3st> | In this implementation-driven world? I don't doubt it haha |
15:52 | <Mathieu Hofman> | r3st: sounds like you're trying to understand how someone is reaching into Function.prototype , probably related to some prototype pollution ? |
15:55 | <Mathieu Hofman> | there are a million ways to get to intrinsics prototypes. Best defense is usually to check for own properties before drilling into a parsed value. |
15:56 | <Mathieu Hofman> | and to use define prop instead of doing an assignment when the there is no own prop |
15:57 | <Mathieu Hofman> | a ton of query string parsers do this wrong |
16:06 | <r3st> | Mathieu Hofman: Didn't know tc39 chat had mind readers. You're right. I'm trying to understand the solution to a mock vulnerable website (https://portswigger.net/web-security/cross-site-scripting/contexts/angularjs-sandbox/lab-angular-sandbox-escape-without-strings ) |
16:11 | <Mathieu Hofman> | Let's say there is very few reasons why one would walk properties like this ;) |
16:12 | <Mathieu Hofman> | And I have mitigated proto pollution vulnerabilities in the past (PSA: checking for __proto__ is often not enough) |
16:22 | <ljharb> | i'm not aware of a host where the global doesn't inherit from Object.prototype, which would make toString a global |
16:25 | <r3st> | Is there a specific definition for the term 'host'? Just making sure I'm not misunderstanding. |
16:27 | <Mathieu Hofman> | the embedder of a JS engine, like a web browser, node or React Native |
22:33 | <jschoi> | I’m pursuing a Function.prototype.once proposal. But I just discovered that there’s a widely used NPM module that can monkey-patch Function.prototype with a once method: https://www.npmjs.com/package/once. However, the monkey-patching mode has required opting in with an extra method ( So would adding a method named Function.prototype.once to the language core probably still be web compatible?… |
22:41 | <TabAtkins> | Do we consider NPM libraries in the "web compat" category? |
22:42 | <TabAtkins> | If we do, then the answer would be "depends on how popular the library is and how popular using .proto() version is" |
22:44 | <bakkot> | jschoi: monkey patching is actually usually web compat; the problems tend to arise when it's done conditionally, or when something else is then copying methods off of the builtin prototype with for-in (which is a problem because standard methods are not enumerable, and monkey-patched ones usually are) |
22:44 | <bakkot> | "done conditionally" meaning specifically "only done when the property does not already exist", I should say |
22:44 | <jschoi> | Right, it’s conditional monkey-patching that’s the problem…That’s reassuring. |
22:45 | <bakkot> | this one looks like it's fine, unless some popular library is doing something like if (!Function.prototype.once) require('once').proto() |
22:46 | <bakkot> | also I suspect this implementation matches what ours would be anyway [roughly], so even if they were I doubt it would break anything |
22:46 | <bakkot> | so: probably it's fine! |
22:47 | <jschoi> | also I suspect this implementation matches what ours would be anyway [roughly], so even if they were I doubt it would break anything .called boolean property, and I’m uncertain whether we would add a similar property to our version…but yeah, it should be fine. |
22:50 | <bakkot> | I would not expect us to do that, no, but I doubt that sees all that much use |
22:50 | <bakkot> | could be wrong though |