Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/ini.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const decode = (str, opt = {}) => {
// section |key = value
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i
const lines = str.split(/[\r\n]+/g)
const duplicates = {}
let duplicates = {}

for (const line of lines) {
if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) {
Expand All @@ -123,6 +123,9 @@ const decode = (str, opt = {}) => {
}
if (match[1] !== undefined) {
section = unsafe(match[1])
// Reset duplicates counter for each new section
// so keys are only treated as arrays when duplicated within the same section
duplicates = {}
if (section === '__proto__') {
// not allowed
// keep parsing the section, but don't attach it.
Expand Down
40 changes: 40 additions & 0 deletions test/duplicate-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,43 @@ test('encode duplicate properties with bracketedArray=false', function (t) {
t.matchSnapshot(e)
t.end()
})

// Regression test for #298 - same key name across different sections
// should NOT be treated as duplicates
test('bracketedArray=false should scope duplicates per section', function (t) {
const content = `
[section_1]
var = 1

[section_2]
var = 2
`
const d = i.decode(content, { bracketedArray: false })
// Both values should be scalars, not arrays, since each key appears
// only once within its own section
t.equal(d.section_1.var, '1', 'section_1.var should be a scalar')
t.equal(d.section_2.var, '2', 'section_2.var should be a scalar')
t.notOk(Array.isArray(d.section_1.var), 'section_1.var should not be an array')
t.notOk(Array.isArray(d.section_2.var), 'section_2.var should not be an array')
t.end()
})

test('bracketedArray=false still creates arrays for duplicates within same section', function (t) {
const content = `
[section_1]
var = 1
var = 2
var = 3

[section_2]
var = single
`
const d = i.decode(content, { bracketedArray: false })
// section_1.var should be an array since it has duplicates within the section
t.ok(Array.isArray(d.section_1.var), 'section_1.var should be an array')
t.same(d.section_1.var, ['1', '2', '3'], 'section_1.var should have all values')
// section_2.var should be a scalar since it only appears once
t.equal(d.section_2.var, 'single', 'section_2.var should be a scalar')
t.notOk(Array.isArray(d.section_2.var), 'section_2.var should not be an array')
t.end()
})