diff --git a/lib/parse.js b/lib/parse.js index 549de82e..7abe5a66 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -214,6 +214,26 @@ var parseObject = function (chain, val, options, valuesParsed) { return leaf; }; +var findClosingBracket = function (key, start) { + var depth = 0; + + for (var i = start; i < key.length; ++i) { + var char = key.charAt(i); + + if (char === '[') { + depth += 1; + } else if (char === ']') { + depth -= 1; + + if (depth === 0) { + return i; + } + } + } + + return -1; +}; + var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; @@ -227,11 +247,8 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { return [key]; } - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; - - var segment = brackets.exec(key); - var parent = segment ? key.slice(0, segment.index) : key; + var segmentStart = key.indexOf('['); + var parent = segmentStart > -1 ? key.slice(0, segmentStart) : key; var keys = []; @@ -246,25 +263,33 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { } var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { + while (segmentStart > -1 && i < options.depth) { + var segmentEnd = findClosingBracket(key, segmentStart); + + if (segmentEnd === -1) { + break; + } + i += 1; - var segmentContent = segment[1].slice(1, -1); + var segment = key.slice(segmentStart, segmentEnd + 1); + var segmentContent = segment.slice(1, -1); if (!options.plainObjects && has.call(Object.prototype, segmentContent)) { if (!options.allowPrototypes) { return; } } - keys[keys.length] = segment[1]; + keys[keys.length] = segment; + segmentStart = key.indexOf('[', segmentEnd + 1); } - if (segment) { + if (segmentStart > -1) { if (options.strictDepth === true) { throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true'); } - keys[keys.length] = '[' + key.slice(segment.index) + ']'; + keys[keys.length] = '[' + key.slice(segmentStart) + ']'; } return keys;