Skip to content

Commit

Permalink
Merge pull request #681 from Leonidas-from-XIV/cve-compat-fix
Browse files Browse the repository at this point in the history
CVE compat fix
  • Loading branch information
Leonidas-from-XIV authored May 25, 2023
2 parents b856cb8 + 5f6620f commit 3b97ae5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 31 deletions.
33 changes: 22 additions & 11 deletions lib/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 15 additions & 10 deletions src/parser.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ defaults = require('./defaults').defaults
isEmpty = (thing) ->
return typeof thing is "object" && thing? && Object.keys(thing).length is 0

isValidKey = (key) ->
return key != '__proto__' && key != 'constructor' && key != 'prototype'

processItem = (processors, item, key) ->
item = process(item, key) for process in processors
return item
Expand Down Expand Up @@ -52,6 +55,7 @@ class exports.Parser extends events
@emit err

assignOrPush: (obj, key, newValue) =>
return if not isValidKey(key)
if key not of obj
if not @options.explicitArray
obj[key] = newValue
Expand Down Expand Up @@ -102,18 +106,19 @@ class exports.Parser extends events
charkey = @options.charkey

@saxParser.onopentag = (node) =>
obj = Object.create(null)
obj = {}
obj[charkey] = ""
unless @options.ignoreAttrs
for own key of node.attributes
if attrkey not of obj and not @options.mergeAttrs
obj[attrkey] = Object.create(null)
obj[attrkey] = {}
newValue = if @options.attrValueProcessors then processItem(@options.attrValueProcessors, node.attributes[key], key) else node.attributes[key]
processedKey = if @options.attrNameProcessors then processItem(@options.attrNameProcessors, key) else key
if @options.mergeAttrs
@assignOrPush obj, processedKey, newValue
else
obj[attrkey][processedKey] = newValue
if isValidKey(processedKey)
if @options.mergeAttrs
@assignOrPush obj, processedKey, newValue
else
obj[attrkey][processedKey] = newValue

# need a place to store the node name
obj["#name"] = if @options.tagNameProcessors then processItem(@options.tagNameProcessors, node.name) else node.name
Expand Down Expand Up @@ -163,7 +168,7 @@ class exports.Parser extends events
# put children into <childkey> property and unfold chars if necessary
if @options.explicitChildren and not @options.mergeAttrs and typeof obj is 'object'
if not @options.preserveChildrenOrder
node = Object.create(null)
node = {}
# separate attributes
if @options.attrkey of obj
node[@options.attrkey] = obj[@options.attrkey]
Expand All @@ -181,9 +186,9 @@ class exports.Parser extends events
# append current node onto parent's <childKey> array
s[@options.childkey] = s[@options.childkey] or []
# push a clone so that the node in the children array can receive the #name property while the original obj can do without it
objClone = Object.create(null)
objClone = {}
for own key of obj
objClone[key] = obj[key]
objClone[key] = obj[key] if isValidKey(key)
s[@options.childkey].push objClone
delete obj["#name"]
# re-check whether we can collapse the node now to just the charkey value
Expand All @@ -198,7 +203,7 @@ class exports.Parser extends events
if @options.explicitRoot
# avoid circular references
old = obj
obj = Object.create(null)
obj = {}
obj[nodeName] = old

@resultObject = obj
Expand Down
20 changes: 10 additions & 10 deletions test/parser.test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -547,13 +547,13 @@ module.exports =

'test single attrNameProcessors': skeleton(attrNameProcessors: [nameToUpperCase], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
equ {}.hasOwnProperty.call(r.sample.attrNameProcessTest[0].$, 'CAMELCASEATTR'), true
equ {}.hasOwnProperty.call(r.sample.attrNameProcessTest[0].$, 'LOWERCASEATTR'), true)
equ r.sample.attrNameProcessTest[0].$.hasOwnProperty('CAMELCASEATTR'), true
equ r.sample.attrNameProcessTest[0].$.hasOwnProperty('LOWERCASEATTR'), true)

'test multiple attrNameProcessors': skeleton(attrNameProcessors: [nameToUpperCase, nameCutoff], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
equ {}.hasOwnProperty.call(r.sample.attrNameProcessTest[0].$, 'CAME'), true
equ {}.hasOwnProperty.call(r.sample.attrNameProcessTest[0].$, 'LOWE'), true)
equ r.sample.attrNameProcessTest[0].$.hasOwnProperty('CAME'), true
equ r.sample.attrNameProcessTest[0].$.hasOwnProperty('LOWE'), true)

'test single attrValueProcessors': skeleton(attrValueProcessors: [nameToUpperCase], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
Expand All @@ -575,21 +575,21 @@ module.exports =

'test single tagNameProcessors': skeleton(tagNameProcessors: [nameToUpperCase], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
equ {}.hasOwnProperty.call(r, 'SAMPLE'), true
equ {}.hasOwnProperty.call(r.SAMPLE, 'TAGNAMEPROCESSTEST'), true)
equ r.hasOwnProperty('SAMPLE'), true
equ r.SAMPLE.hasOwnProperty('TAGNAMEPROCESSTEST'), true)

'test single tagNameProcessors in simple callback': (test) ->
fs.readFile fileName, (err, data) ->
xml2js.parseString data, tagNameProcessors: [nameToUpperCase], (err, r)->
console.log 'Result object: ' + util.inspect r, false, 10
equ {}.hasOwnProperty.call(r, 'SAMPLE'), true
equ {}.hasOwnProperty.call(r.SAMPLE, 'TAGNAMEPROCESSTEST'), true
equ r.hasOwnProperty('SAMPLE'), true
equ r.SAMPLE.hasOwnProperty('TAGNAMEPROCESSTEST'), true
test.finish()

'test multiple tagNameProcessors': skeleton(tagNameProcessors: [nameToUpperCase, nameCutoff], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
equ {}.hasOwnProperty.call(r, 'SAMP'), true
equ {}.hasOwnProperty.call(r.SAMP, 'TAGN'), true)
equ r.hasOwnProperty('SAMP'), true
equ r.SAMP.hasOwnProperty('TAGN'), true)

'test attrValueProcessors key param': skeleton(attrValueProcessors: [replaceValueByName], (r)->
console.log 'Result object: ' + util.inspect r, false, 10
Expand Down

0 comments on commit 3b97ae5

Please sign in to comment.