@@ -8385,10 +8385,10 @@ function encode (obj, opt) {
8385
8385
if (typeof opt === 'string') {
8386
8386
opt = {
8387
8387
section: opt,
8388
- whitespace: false
8388
+ whitespace: false,
8389
8389
};
8390
8390
} else {
8391
- opt = opt || {} ;
8391
+ opt = opt || Object.create(null) ;
8392
8392
opt.whitespace = opt.whitespace === true;
8393
8393
}
8394
8394
@@ -8400,27 +8400,25 @@ function encode (obj, opt) {
8400
8400
val.forEach(function (item) {
8401
8401
out += safe(k + '[]') + separator + safe(item) + '\n';
8402
8402
});
8403
- } else if (val && typeof val === 'object') {
8403
+ } else if (val && typeof val === 'object')
8404
8404
children.push(k);
8405
- } else {
8405
+ else
8406
8406
out += safe(k) + separator + safe(val) + eol;
8407
- }
8408
8407
});
8409
8408
8410
- if (opt.section && out.length) {
8409
+ if (opt.section && out.length)
8411
8410
out = '[' + safe(opt.section) + ']' + eol + out;
8412
- }
8413
8411
8414
8412
children.forEach(function (k, _, __) {
8415
8413
var nk = dotSplit(k).join('\\.');
8416
8414
var section = (opt.section ? opt.section + '.' : '') + nk;
8417
8415
var child = encode(obj[k], {
8418
8416
section: section,
8419
- whitespace: opt.whitespace
8417
+ whitespace: opt.whitespace,
8420
8418
});
8421
- if (out.length && child.length) {
8419
+ if (out.length && child.length)
8422
8420
out += eol;
8423
- }
8421
+
8424
8422
out += child;
8425
8423
});
8426
8424
@@ -8432,28 +8430,38 @@ function dotSplit (str) {
8432
8430
.replace(/\\\./g, '\u0001')
8433
8431
.split(/\./).map(function (part) {
8434
8432
return part.replace(/\1/g, '\\.')
8435
- .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001')
8433
+ .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001')
8436
8434
})
8437
8435
}
8438
8436
8439
8437
function decode (str) {
8440
- var out = {} ;
8438
+ var out = Object.create(null) ;
8441
8439
var p = out;
8442
8440
var section = null;
8443
8441
// section |key = value
8444
8442
var re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i;
8445
8443
var lines = str.split(/[\r\n]+/g);
8446
8444
8447
8445
lines.forEach(function (line, _, __) {
8448
- if (!line || line.match(/^\s*[;#]/)) return
8446
+ if (!line || line.match(/^\s*[;#]/))
8447
+ return
8449
8448
var match = line.match(re);
8450
- if (!match) return
8449
+ if (!match)
8450
+ return
8451
8451
if (match[1] !== undefined) {
8452
8452
section = unsafe(match[1]);
8453
- p = out[section] = out[section] || {};
8453
+ if (section === '__proto__') {
8454
+ // not allowed
8455
+ // keep parsing the section, but don't attach it.
8456
+ p = Object.create(null);
8457
+ return
8458
+ }
8459
+ p = out[section] = out[section] || Object.create(null);
8454
8460
return
8455
8461
}
8456
8462
var key = unsafe(match[2]);
8463
+ if (key === '__proto__')
8464
+ return
8457
8465
var value = match[3] ? unsafe(match[4]) : true;
8458
8466
switch (value) {
8459
8467
case 'true':
@@ -8464,43 +8472,46 @@ function decode (str) {
8464
8472
// Convert keys with '[]' suffix to an array
8465
8473
if (key.length > 2 && key.slice(-2) === '[]') {
8466
8474
key = key.substring(0, key.length - 2);
8467
- if (!p[key]) {
8475
+ if (key === '__proto__')
8476
+ return
8477
+ if (!p[key])
8468
8478
p[key] = [];
8469
- } else if (!Array.isArray(p[key])) {
8479
+ else if (!Array.isArray(p[key]))
8470
8480
p[key] = [p[key]];
8471
- }
8472
8481
}
8473
8482
8474
8483
// safeguard against resetting a previously defined
8475
8484
// array by accidentally forgetting the brackets
8476
- if (Array.isArray(p[key])) {
8485
+ if (Array.isArray(p[key]))
8477
8486
p[key].push(value);
8478
- } else {
8487
+ else
8479
8488
p[key] = value;
8480
- }
8481
8489
});
8482
8490
8483
8491
// {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}}
8484
8492
// use a filter to return the keys that have to be deleted.
8485
8493
Object.keys(out).filter(function (k, _, __) {
8486
8494
if (!out[k] ||
8487
8495
typeof out[k] !== 'object' ||
8488
- Array.isArray(out[k])) {
8496
+ Array.isArray(out[k]))
8489
8497
return false
8490
- }
8498
+
8491
8499
// see if the parent section is also an object.
8492
8500
// if so, add it to that, and mark this one for deletion
8493
8501
var parts = dotSplit(k);
8494
8502
var p = out;
8495
8503
var l = parts.pop();
8496
8504
var nl = l.replace(/\\\./g, '.');
8497
8505
parts.forEach(function (part, _, __) {
8498
- if (!p[part] || typeof p[part] !== 'object') p[part] = {};
8506
+ if (part === '__proto__')
8507
+ return
8508
+ if (!p[part] || typeof p[part] !== 'object')
8509
+ p[part] = Object.create(null);
8499
8510
p = p[part];
8500
8511
});
8501
- if (p === out && nl === l) {
8512
+ if (p === out && nl === l)
8502
8513
return false
8503
- }
8514
+
8504
8515
p[nl] = out[k];
8505
8516
return true
8506
8517
}).forEach(function (del, _, __) {
@@ -8522,42 +8533,43 @@ function safe (val) {
8522
8533
(val.length > 1 &&
8523
8534
isQuoted(val)) ||
8524
8535
val !== val.trim())
8525
- ? JSON.stringify(val)
8526
- : val.replace(/;/g, '\\;').replace(/#/g, '\\#')
8536
+ ? JSON.stringify(val)
8537
+ : val.replace(/;/g, '\\;').replace(/#/g, '\\#')
8527
8538
}
8528
8539
8529
8540
function unsafe (val, doUnesc) {
8530
8541
val = (val || '').trim();
8531
8542
if (isQuoted(val)) {
8532
8543
// remove the single quotes before calling JSON.parse
8533
- if (val.charAt(0) === "'") {
8544
+ if (val.charAt(0) === "'")
8534
8545
val = val.substr(1, val.length - 2);
8535
- }
8536
- try { val = JSON.parse(val); } catch (_) {}
8546
+
8547
+ try {
8548
+ val = JSON.parse(val);
8549
+ } catch (_) {}
8537
8550
} else {
8538
8551
// walk the val to find the first not-escaped ; character
8539
8552
var esc = false;
8540
8553
var unesc = '';
8541
8554
for (var i = 0, l = val.length; i < l; i++) {
8542
8555
var c = val.charAt(i);
8543
8556
if (esc) {
8544
- if ('\\;#'.indexOf(c) !== -1) {
8557
+ if ('\\;#'.indexOf(c) !== -1)
8545
8558
unesc += c;
8546
- } else {
8559
+ else
8547
8560
unesc += '\\' + c;
8548
- }
8561
+
8549
8562
esc = false;
8550
- } else if (';#'.indexOf(c) !== -1) {
8563
+ } else if (';#'.indexOf(c) !== -1)
8551
8564
break
8552
- } else if (c === '\\') {
8565
+ else if (c === '\\')
8553
8566
esc = true;
8554
- } else {
8567
+ else
8555
8568
unesc += c;
8556
- }
8557
8569
}
8558
- if (esc) {
8570
+ if (esc)
8559
8571
unesc += '\\';
8560
- }
8572
+
8561
8573
return unesc.trim()
8562
8574
}
8563
8575
return val
0 commit comments