Socket
Socket
Sign inDemoInstall

ini

Package Overview
Dependencies
0
Maintainers
7
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.0 to 4.1.0

115

lib/ini.js
const { hasOwnProperty } = Object.prototype
/* istanbul ignore next */
const eol = typeof process !== 'undefined' &&
process.platform === 'win32' ? '\r\n' : '\n'
const encode = (obj, opt = {}) => {
if (typeof opt === 'string') {
opt = { section: opt }
}
opt.align = opt.align === true
opt.newline = opt.newline === true
opt.sort = opt.sort === true
opt.whitespace = opt.whitespace === true || opt.align === true
/* istanbul ignore next */
opt.platform = opt.platform || process?.platform
opt.bracketedArray = opt.bracketedArray !== false
const encode = (obj, opt) => {
/* istanbul ignore next */
const eol = opt.platform === 'win32' ? '\r\n' : '\n'
const separator = opt.whitespace ? ' = ' : '='
const children = []
let out = ''
if (typeof opt === 'string') {
opt = {
section: opt,
whitespace: false,
}
} else {
opt = opt || Object.create(null)
opt.whitespace = opt.whitespace === true
const keys = opt.sort ? Object.keys(obj).sort() : Object.keys(obj)
let padToChars = 0
// If aligning on the separator, then padToChars is determined as follows:
// 1. Get the keys
// 2. Exclude keys pointing to objects unless the value is null or an array
// 3. Add `[]` to array keys
// 4. Ensure non empty set of keys
// 5. Reduce the set to the longest `safe` key
// 6. Get the `safe` length
if (opt.align) {
padToChars = safe(
(
keys
.filter(k => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== 'object')
.map(k => Array.isArray(obj[k]) ? `${k}[]` : k)
)
.concat([''])
.reduce((a, b) => safe(a).length >= safe(b).length ? a : b)
).length
}
const separator = opt.whitespace ? ' = ' : '='
let out = ''
const arraySuffix = opt.bracketedArray ? '[]' : ''
for (const k of Object.keys(obj)) {
for (const k of keys) {
const val = obj[k]
if (val && Array.isArray(val)) {
for (const item of val) {
out += safe(k + '[]') + separator + safe(item) + eol
out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol
}

@@ -32,3 +54,3 @@ } else if (val && typeof val === 'object') {

} else {
out += safe(k) + separator + safe(val) + eol
out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol
}

@@ -38,12 +60,11 @@ }

if (opt.section && out.length) {
out = '[' + safe(opt.section) + ']' + eol + out
out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out
}
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], {
...opt,
section,
whitespace,
})

@@ -60,20 +81,40 @@ if (out.length && child.length) {

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 = []
const decode = str => {
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, opt = {}) => {
opt.bracketedArray = opt.bracketedArray !== false
const out = Object.create(null)
let p = out
let section = null
// section |key = value
const re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i
// section |key = value
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i
const lines = str.split(/[\r\n]+/g)
const duplicates = {}
for (const line of lines) {
if (!line || line.match(/^\s*[;#]/)) {
if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) {
continue

@@ -97,3 +138,9 @@ }

const keyRaw = unsafe(match[2])
const isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]'
let isArray
if (opt.bracketedArray) {
isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]'
} else {
duplicates[keyRaw] = (duplicates?.[keyRaw] || 0) + 1
isArray = duplicates[keyRaw] > 1
}
const key = isArray ? keyRaw.slice(0, -2) : keyRaw

@@ -139,3 +186,3 @@ if (key === '__proto__') {

// if so, add it to that, and mark this one for deletion
const parts = dotSplit(k)
const parts = splitSections(k, '.')
p = out

@@ -142,0 +189,0 @@ const l = parts.pop()

@@ -5,3 +5,3 @@ {

"description": "An ini encoder/decoder for node",
"version": "4.0.0",
"version": "4.1.0",
"repository": {

@@ -24,3 +24,3 @@ "type": "git",

"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.12.0",
"@npmcli/template-oss": "4.13.0",
"tap": "^16.0.1"

@@ -38,3 +38,4 @@ },

"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.12.0"
"version": "4.13.0",
"publish": "true"
},

@@ -41,0 +42,0 @@ "tap": {

@@ -79,4 +79,9 @@ An ini format parser and serializer for node.

* `section` A string which will be the first `section` in the encoded
* `align` Boolean to specify whether to align the `=` characters for
each section. This option will automatically enable `whitespace`.
Defaults to `false`.
* `section` String which will be the first `section` in the encoded
ini data. Defaults to none.
* `sort` Boolean to specify if all keys in each section, as well as
all sections, will be alphabetically sorted. Defaults to `false`.
* `whitespace` Boolean to specify whether to put whitespace around the

@@ -86,2 +91,14 @@ `=` character. By default, whitespace is omitted, to be friendly to

find that it's more human-readable and pretty with the whitespace.
Defaults to `false`.
* `newline` Boolean to specify whether to put an additional newline
after a section header. Some INI file parsers (for example the TOSHIBA
FlashAir one) need this to parse the file successfully. By default,
the additional newline is omitted.
* `platform` String to define which platform this INI file is expected
to be used with: when `platform` is `win32`, line terminations are
CR+LF, for other platforms line termination is LF. By default, the
current platform name is used.
* `bracketedArrays` Boolean to specify whether array values are appended
with `[]`. By default this is true but there are some ini parsers
that instead treat duplicate names as arrays.

@@ -88,0 +105,0 @@ For backwards compatibility reasons, if a `string` options is passed

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc