From 983a3d31a25cde3961b400c3999753f1b01f6860 Mon Sep 17 00:00:00 2001 From: Kevin Partington Date: Sat, 24 Feb 2018 23:12:12 -0600 Subject: [PATCH] fix: Refactored section split logic Rebase of: #73 Author: @platinumazure --- lib/ini.js | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/ini.js b/lib/ini.js index d05682b..3fde6ff 100644 --- a/lib/ini.js +++ b/lib/ini.js @@ -38,7 +38,7 @@ const encode = (obj, opt) => { } for (const k of children) { - const nk = dotSplit(k).join('\\.') + const nk = splitSections(k, '.').join('\\.') const section = (opt.section ? opt.section + '.' : '') + nk const { whitespace } = opt const child = encode(obj[k], { @@ -55,13 +55,31 @@ const encode = (obj, opt) => { return out } -const dotSplit = str => - str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') - .replace(/\\\./g, '\u0001') - .split(/\./) - .map(part => - part.replace(/\1/g, '\\.') - .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001')) +function splitSections (str, separator) { + var lastMatchIndex = 0 + var lastSeparatorIndex = 0 + var nextIndex = 0 + var sections = [] + + do { + nextIndex = str.indexOf(separator, lastMatchIndex) + + if (nextIndex !== -1) { + lastMatchIndex = nextIndex + separator.length + + if (nextIndex > 0 && str[nextIndex - 1] === '\\') { + continue + } + + sections.push(str.slice(lastSeparatorIndex, nextIndex)) + lastSeparatorIndex = nextIndex + separator.length + } + } while (nextIndex !== -1) + + sections.push(str.slice(lastSeparatorIndex)) + + return sections +} const decode = str => { const out = Object.create(null) @@ -132,7 +150,7 @@ const decode = str => { // see if the parent section is also an object. // if so, add it to that, and mark this one for deletion - const parts = dotSplit(k) + const parts = splitSections(k, '.') p = out const l = parts.pop() const nl = l.replace(/\\\./g, '.')