Skip to content

Commit 30f9d61

Browse files
committedJul 25, 2023
Replace filtering of names with defineProperty
Closes #682
1 parent ba46e54 commit 30f9d61

File tree

2 files changed

+39
-35
lines changed

2 files changed

+39
-35
lines changed
 

‎lib/parser.js

+20-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/parser.coffee

+19-14
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ defaults = require('./defaults').defaults
1111
isEmpty = (thing) ->
1212
return typeof thing is "object" && thing? && Object.keys(thing).length is 0
1313

14-
isValidKey = (key) ->
15-
return key != '__proto__' && key != 'constructor' && key != 'prototype'
16-
1714
processItem = (processors, item, key) ->
1815
item = process(item, key) for process in processors
1916
return item
2017

18+
defineProperty = (obj, key, value) ->
19+
# make sure the descriptor hasn't been prototype polluted
20+
descriptor = Object.create null
21+
descriptor.value = value
22+
descriptor.writeable = true
23+
descriptor.enumerable = true
24+
descriptor.configurable = true
25+
Object.defineProperty obj, key, descriptor
26+
2127
class exports.Parser extends events
2228
constructor: (opts) ->
2329
# if this was called without 'new', create an instance with new and return
@@ -55,14 +61,14 @@ class exports.Parser extends events
5561
@emit err
5662

5763
assignOrPush: (obj, key, newValue) =>
58-
return if not isValidKey(key)
5964
if key not of obj
6065
if not @options.explicitArray
61-
obj[key] = newValue
66+
defineProperty obj, key, newValue
6267
else
63-
obj[key] = [newValue]
68+
defineProperty obj, key, [newValue]
6469
else
65-
obj[key] = [obj[key]] if not (obj[key] instanceof Array)
70+
unless obj[key] instanceof Array
71+
defineProperty obj, key, [obj[key]]
6672
obj[key].push newValue
6773

6874
reset: =>
@@ -114,11 +120,10 @@ class exports.Parser extends events
114120
obj[attrkey] = {}
115121
newValue = if @options.attrValueProcessors then processItem(@options.attrValueProcessors, node.attributes[key], key) else node.attributes[key]
116122
processedKey = if @options.attrNameProcessors then processItem(@options.attrNameProcessors, key) else key
117-
if isValidKey(processedKey)
118-
if @options.mergeAttrs
119-
@assignOrPush obj, processedKey, newValue
120-
else
121-
obj[attrkey][processedKey] = newValue
123+
if @options.mergeAttrs
124+
@assignOrPush obj, processedKey, newValue
125+
else
126+
defineProperty obj[attrkey], processedKey, newValue
122127

123128
# need a place to store the node name
124129
obj["#name"] = if @options.tagNameProcessors then processItem(@options.tagNameProcessors, node.name) else node.name
@@ -188,7 +193,7 @@ class exports.Parser extends events
188193
# push a clone so that the node in the children array can receive the #name property while the original obj can do without it
189194
objClone = {}
190195
for own key of obj
191-
objClone[key] = obj[key] if isValidKey(key)
196+
defineProperty objClone, key, obj[key]
192197
s[@options.childkey].push objClone
193198
delete obj["#name"]
194199
# re-check whether we can collapse the node now to just the charkey value
@@ -204,7 +209,7 @@ class exports.Parser extends events
204209
# avoid circular references
205210
old = obj
206211
obj = {}
207-
obj[nodeName] = old
212+
defineProperty obj, nodeName, old
208213

209214
@resultObject = obj
210215
# parsing has ended, mark that so we won't throw exceptions from

0 commit comments

Comments
 (0)
Please sign in to comment.