Skip to content

Commit 1d420ee

Browse files
committed
Code style
1 parent fd02454 commit 1d420ee

File tree

3 files changed

+100
-116
lines changed

3 files changed

+100
-116
lines changed

index.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'use strict'
2+
3+
const suspectRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/
4+
5+
function parse (text, reviver, options) {
6+
// Normalize arguments
7+
if (options == null) {
8+
if (reviver != null && typeof reviver === 'object') {
9+
options = reviver
10+
reviver = undefined
11+
} else {
12+
options = {}
13+
}
14+
}
15+
16+
// Parse normally, allowing exceptions
17+
const obj = JSON.parse(text, reviver)
18+
19+
// options.protoAction: 'error' (default) / 'remove' / 'ignore'
20+
if (options.protoAction === 'ignore') {
21+
return obj
22+
}
23+
24+
// Ignore null and non-objects
25+
if (!obj || typeof obj !== 'object') {
26+
return obj
27+
}
28+
29+
// Check original string for potential exploit
30+
if (!text.match(suspectRx)) {
31+
return obj
32+
}
33+
34+
// Scan result for proto keys
35+
scan(obj, options)
36+
37+
return obj
38+
}
39+
40+
function scan (obj, options) {
41+
options = options || {}
42+
43+
var next = [obj]
44+
45+
while (next.length) {
46+
const nodes = next
47+
next = []
48+
49+
for (const node of nodes) {
50+
if (Object.prototype.hasOwnProperty.call(node, '__proto__')) { // Avoid calling node.hasOwnProperty directly
51+
if (options.protoAction !== 'remove') {
52+
throw new SyntaxError('Object contains forbidden prototype property')
53+
}
54+
55+
delete node.__proto__ // eslint-disable-line
56+
}
57+
58+
for (const key in node) {
59+
const value = node[key]
60+
if (value && typeof value === 'object') {
61+
next.push(node[key])
62+
}
63+
}
64+
}
65+
}
66+
}
67+
68+
function safeParse (text, reviver) {
69+
try {
70+
return parse(text, reviver)
71+
} catch (ignoreError) {
72+
return null
73+
}
74+
}
75+
76+
module.exports = {
77+
parse,
78+
scan,
79+
safeParse
80+
}

lib/index.js

Lines changed: 0 additions & 97 deletions
This file was deleted.

package.json

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
{
2-
"name": "@hapi/bourne",
2+
"name": "secure-json-parse",
3+
"version": "1.0.0",
34
"description": "JSON parse with prototype poisoning protection",
4-
"version": "1.3.2",
5-
"repository": "git://github.com/hapijs/bourne",
6-
"main": "lib/index.js",
7-
"keywords": [
8-
"JSON",
9-
"parse",
10-
"safe",
11-
"prototype"
12-
],
13-
"dependencies": {},
14-
"devDependencies": {
15-
"@hapi/code": "5.x.x",
16-
"@hapi/lab": "18.x.x",
17-
"benchmark": "^2.1.4"
18-
},
5+
"main": "index.js",
196
"scripts": {
20-
"test": "lab -a @hapi/code -t 100 -L",
21-
"test-cov-html": "lab -a @hapi/code -r html -o coverage.html"
7+
"test": "tap test.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/fastify/secure-json-parse.git"
2212
},
23-
"license": "BSD-3-Clause"
13+
"keywords": [],
14+
"author": "Tomas Della Vedova",
15+
"license": "BSD-3-Clause",
16+
"bugs": {
17+
"url": "https://github.com/fastify/secure-json-parse/issues"
18+
},
19+
"homepage": "https://github.com/fastify/secure-json-parse#readme",
20+
"dependencies": {},
21+
"devDependencies": {
22+
"standard": "^12.0.1",
23+
"tap": "^12.7.0"
24+
}
2425
}

0 commit comments

Comments
 (0)