You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
insertBefore()/insert() accept prototype-inherited keys (e.g. "toString") and then silently insert nothingΒ #4174
While playing with the grammar utilities on master (v2 alpha), I noticed the anchor-key guard in insert() uses the in operator:
src/util/insert.js:57
if(!(atKeyingrammar)){thrownewError(`"${atKey}" has to be a key of grammar.`);}``"
Because`in`walkstheprototypechain,anykeyinheritedfrom`Object.prototype`β`toString`,`constructor`,`hasOwnProperty`,`__proto__`, ... βpassesthecheckeventhoughitisnotakeyofthegrammaratall.Afterthat,`key === atKey`nevermatcheswhilere-insertingthegrammar's own keys, so `betterAssign(grammar, insert)` is never called: **no error is thrown and the new tokens are silently dropped**.
Minimalreproagainstthecurrent`src/util/insert.js`(runwithnode,thepackageisESM):
```jsimport{insertBefore}from'./prism/src/util/insert.js';constgrammar={comment: {pattern: /x/,greedy: true},string: {pattern: /y/},};// "toString" is not a key of the grammar β this should throwinsertBefore(grammar,'toString',{'new-token': {pattern: /z/}});console.log(JSON.stringify(Object.keys(grammar)));// -> ["comment","string"] (expected: TypeError "toString has to be a key of grammar.")
Same outcome for insertAfter(grammar, 'constructor', {...}) and insert(grammar, 'hasOwnProperty', {...}). As a control, a genuinely missing key like a typo ("strng") does throw correctly, and a valid own key works as intended β it is only the Object.prototype names that slip through the guard and turn into a silent no-op.
Since the whole point of this guard is to catch a wrong anchor key with a loud error, I'd expect it to check own properties only, e.g.:
if(!Object.hasOwn(grammar,atKey)){ ... }
For context, this bit me while wiring up a small grammar-patching utility where the anchor key came from user input; the call "succeeded" and nothing showed up in the output, which took a while to track down. Apologies if this is known/duplicate β I searched the tracker for insertBefore reports and found nothing matching.
Activity