Skip to content

Commit 6ee392e

Browse files
authored
Merge pull request #37 from sidorares/fix/prototype
Add protoAction and constructorAction options
2 parents 4c2dbf4 + c85a430 commit 6ee392e

File tree

4 files changed

+494
-336
lines changed

4 files changed

+494
-336
lines changed

.prettierrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"tabWidth": 2
2+
"tabWidth": 2,
3+
"singleQuote": true
34
}

README.md

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
json-bigint
2-
===========
1+
# json-bigint
32

43
[![Build Status](https://secure.travis-ci.org/sidorares/json-bigint.png)](http://travis-ci.org/sidorares/json-bigint)
54
[![NPM](https://nodei.co/npm/json-bigint.png?downloads=true&stars=true)](https://nodei.co/npm/json-bigint/)
65

7-
JSON.parse/stringify with bigints support. Based on Douglas Crockford [JSON.js](https://github.com/douglascrockford/JSON-js) package and [bignumber.js](https://github.com/MikeMcl/bignumber.js) library.
6+
JSON.parse/stringify with bigints support. Based on Douglas Crockford [JSON.js](https://github.com/douglascrockford/JSON-js) package and [bignumber.js](https://github.com/MikeMcl/bignumber.js) library.
87

98
Native `Bigint` was added to JS recently, so we added an option to leverage it instead of `bignumber.js`. However, the parsing with native `BigInt` is kept an option for backward compability.
109

@@ -21,7 +20,7 @@ var json = '{ "value" : 9223372036854775807, "v2": 123 }';
2120
console.log('Input:', json);
2221
console.log('');
2322

24-
console.log('node.js bult-in JSON:')
23+
console.log('node.js bult-in JSON:');
2524
var r = JSON.parse(json);
2625
console.log('JSON.parse(input).value : ', r.value.toString());
2726
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));
@@ -46,35 +45,43 @@ big number JSON:
4645
JSONbig.parse(input).value : 9223372036854775807
4746
JSONbig.stringify(JSONbig.parse(input)): {"value":9223372036854775807,"v2":123}
4847
```
48+
4949
### Options
50+
5051
The behaviour of the parser is somewhat configurable through 'options'
5152

5253
#### options.strict, boolean, default false
54+
5355
Specifies the parsing should be "strict" towards reporting duplicate-keys in the parsed string.
5456
The default follows what is allowed in standard json and resembles the behavior of JSON.parse, but overwrites any previous values with the last one assigned to the duplicate-key.
5557

5658
Setting options.strict = true will fail-fast on such duplicate-key occurances and thus warn you upfront of possible lost information.
5759

5860
example:
61+
5962
```js
6063
var JSONbig = require('json-bigint');
61-
var JSONstrict = require('json-bigint')({"strict": true});
64+
var JSONstrict = require('json-bigint')({ strict: true });
6265

6366
var dupkeys = '{ "dupkey": "value 1", "dupkey": "value 2"}';
6467
console.log('\n\nDuplicate Key test with both lenient and strict JSON parsing');
6568
console.log('Input:', dupkeys);
6669
var works = JSONbig.parse(dupkeys);
6770
console.log('JSON.parse(dupkeys).dupkey: %s', works.dupkey);
68-
var fails = "will stay like this";
71+
var fails = 'will stay like this';
6972
try {
70-
fails = JSONstrict.parse(dupkeys);
71-
console.log('ERROR!! Should never get here');
73+
fails = JSONstrict.parse(dupkeys);
74+
console.log('ERROR!! Should never get here');
7275
} catch (e) {
73-
console.log('Succesfully catched expected exception on duplicate keys: %j', e);
76+
console.log(
77+
'Succesfully catched expected exception on duplicate keys: %j',
78+
e
79+
);
7480
}
7581
```
7682

7783
Output
84+
7885
```
7986
Duplicate Key test with big number JSON
8087
Input: { "dupkey": "value 1", "dupkey": "value 2"}
@@ -84,24 +91,30 @@ Succesfully catched expected exception on duplicate keys: {"name":"SyntaxError",
8491
```
8592

8693
#### options.storeAsString, boolean, default false
94+
8795
Specifies if BigInts should be stored in the object as a string, rather than the default BigNumber.
8896

8997
Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all BigInts to be-and-stay strings).
9098

9199
example:
100+
92101
```js
93102
var JSONbig = require('json-bigint');
94-
var JSONbigString = require('json-bigint')({"storeAsString": true});
103+
var JSONbigString = require('json-bigint')({ storeAsString: true });
95104
var key = '{ "key": 1234567890123456789 }';
96105
console.log('\n\nStoring the BigInt as a string, instead of a BigNumber');
97106
console.log('Input:', key);
98107
var withInt = JSONbig.parse(key);
99108
var withString = JSONbigString.parse(key);
100-
console.log('Default type: %s, With option type: %s', typeof withInt.key, typeof withString.key);
101-
109+
console.log(
110+
'Default type: %s, With option type: %s',
111+
typeof withInt.key,
112+
typeof withString.key
113+
);
102114
```
103115

104116
Output
117+
105118
```
106119
Storing the BigInt as a string, instead of a BigNumber
107120
Input: { "key": 1234567890123456789 }
@@ -110,48 +123,60 @@ Default type: object, With option type: string
110123
```
111124

112125
#### options.useNativeBigInt, boolean, default false
126+
113127
Specifies if parser uses native BigInt instead of bignumber.js
114128

115129
example:
130+
116131
```js
117132
var JSONbig = require('json-bigint');
118-
var JSONbigNative = require('json-bigint')({"useNativeBigInt": true});
133+
var JSONbigNative = require('json-bigint')({ useNativeBigInt: true });
119134
var key = '{ "key": 993143214321423154315154321 }';
120135
console.log(`\n\nStoring the Number as native BigInt, instead of a BigNumber`);
121136
console.log('Input:', key);
122137
var normal = JSONbig.parse(key);
123138
var nativeBigInt = JSONbigNative.parse(key);
124-
console.log('Default type: %s, With option type: %s', typeof normal.key, typeof nativeBigInt.key);
125-
139+
console.log(
140+
'Default type: %s, With option type: %s',
141+
typeof normal.key,
142+
typeof nativeBigInt.key
143+
);
126144
```
127145

128146
Output
147+
129148
```
130149
Storing the Number as native BigInt, instead of a BigNumber
131150
Input: { "key": 993143214321423154315154321 }
132-
Default type: object, With option type: bigint
151+
Default type: object, With option type: bigint
133152
134153
```
135154

136155
#### options.alwaysParseAsBig, boolean, default false
156+
137157
Specifies if all numbers should be stored as BigNumber.
138158

139159
Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all Number to be-and-stay BigNumber)
140160

141161
example:
162+
142163
```js
143164
var JSONbig = require('json-bigint');
144-
var JSONbigAlways = require('json-bigint')({"alwaysParseAsBig": true});
165+
var JSONbigAlways = require('json-bigint')({ alwaysParseAsBig: true });
145166
var key = '{ "key": 123 }'; // there is no need for BigNumber by default, but we're forcing it
146167
console.log(`\n\nStoring the Number as a BigNumber, instead of a Number`);
147168
console.log('Input:', key);
148169
var normal = JSONbig.parse(key);
149170
var always = JSONbigAlways.parse(key);
150-
console.log('Default type: %s, With option type: %s', typeof normal.key, typeof always.key);
151-
171+
console.log(
172+
'Default type: %s, With option type: %s',
173+
typeof normal.key,
174+
typeof always.key
175+
);
152176
```
153177

154178
Output
179+
155180
```
156181
Storing the Number as a BigNumber, instead of a Number
157182
Input: { "key": 123 }
@@ -161,11 +186,33 @@ Default type: number, With option type: object
161186

162187
If you want to force all numbers to be parsed as native `BigInt`
163188
(you probably do! Otherwise any calulations become a real headache):
189+
190+
```js
191+
var JSONbig = require('json-bigint')({
192+
alwaysParseAsBig: true,
193+
useNativeBigInt: true,
194+
});
195+
```
196+
197+
#### options.protoAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"
198+
199+
#### options.constructorAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"
200+
201+
Controls how `__proto__` and `constructor` properties are treated. If set to "error" they are not allowed and
202+
parse() call will throw an error. If set to "ignore" the prroperty and it;s value is skipped from parsing and object building.
203+
If set to "preserve" the `__proto__` property is set. One should be extra careful and make sure any other library consuming generated data
204+
is not vulnerable to prototype poisoning attacks.
205+
206+
example:
207+
164208
```js
165-
var JSONbig = require('json-bigint')({"alwaysParseAsBig": true, "useNativeBigInt": true});
209+
var JSONbigAlways = require('json-bigint')({ protoAction: 'ignore' });
210+
const user = JSONbig.parse('{ "__proto__": { "admin": true }, "id": 12345 }');
211+
// => result is { id: 12345 }
166212
```
167213

168214
### Links:
215+
169216
- [RFC4627: The application/json Media Type for JavaScript Object Notation (JSON)](http://www.ietf.org/rfc/rfc4627.txt)
170217
- [Re: \[Json\] Limitations on number size?](http://www.ietf.org/mail-archive/web/json/current/msg00297.html)
171218
- [Is there any proper way to parse JSON with large numbers? (long, bigint, int64)](http://stackoverflow.com/questions/18755125/node-js-is-there-any-proper-way-to-parse-json-with-large-numbers-long-bigint)
@@ -175,17 +222,19 @@ var JSONbig = require('json-bigint')({"alwaysParseAsBig": true, "useNativeBigInt
175222
### Note on native BigInt support
176223

177224
#### Stringifying
225+
178226
Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no `n`)
179227

180228
#### Limitations
229+
181230
- Roundtrip operations
182231

183232
`s === JSONbig.stringify(JSONbig.parse(s))` but
184233

185-
`o !== JSONbig.parse(JSONbig.stringify(o))`
234+
`o !== JSONbig.parse(JSONbig.stringify(o))`
186235

187-
when `o` has a value with something like `123n`.
236+
when `o` has a value with something like `123n`.
188237

189-
`JSONbig` stringify `123n` as `123`, which becomes `number` (aka `123` not `123n`) by default when being reparsed.
238+
`JSONbig` stringify `123n` as `123`, which becomes `number` (aka `123` not `123n`) by default when being reparsed.
190239

191-
There is currently no consistent way to deal with this issue, so we decided to leave it, handling this specific case is then up to users.
240+
There is currently no consistent way to deal with this issue, so we decided to leave it, handling this specific case is then up to users.

0 commit comments

Comments
 (0)