Showing with 1,315 additions and 715 deletions.
  1. +0 −1 .travis.yml
  2. +13 −2 CHANGELOG.md
  3. +64 −20 README.md
  4. +34 −7 lib/parse.js
  5. +433 −1 package-lock.json
  6. +7 −4 package.json
  7. +7 −4 package.json5
  8. +0 −5 test/.eslintrc.json
  9. +3 −2 test/cli.js
  10. +371 −438 test/errors.js
  11. +7 −2 test/parse.js
  12. +10 −5 test/require.js
  13. +366 −224 test/stringify.js
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ node_js:
- "11"
- "10"
- "8"
- "6"
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
### Unreleased [[code][c-unreleased], [diff][d-unreleased]]

[c-unreleased]: https://github.com/json5/json5/tree/master
[d-unreleased]: https://github.com/json5/json5/compare/v2.2.0...HEAD
[c-unreleased]: https://github.com/json5/json5/tree/main
[d-unreleased]: https://github.com/json5/json5/compare/v2.2.2...HEAD

### v2.2.2 [[code][c2.2.2], [diff][d2.2.2]]

[c2.2.2]: https://github.com/json5/json5/tree/v2.2.2
[d2.2.2]: https://github.com/json5/json5/compare/v2.2.1...v2.2.2

- Fix: Properties with the name `__proto__` are added to objects and arrays.
([#199]) This also fixes a prototype pollution vulnerability reported by
Jonathan Gregson! ([#295]).

### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]]

Expand Down Expand Up @@ -360,6 +369,7 @@ parser for the regular JSON format.
[#182]: https://github.com/json5/json5/issues/182
[#187]: https://github.com/json5/json5/issues/187
[#196]: https://github.com/json5/json5/issues/196
[#199]: https://github.com/json5/json5/issues/199
[#208]: https://github.com/json5/json5/issues/208
[#210]: https://github.com/json5/json5/issues/210
[#222]: https://github.com/json5/json5/issues/222
Expand All @@ -368,3 +378,4 @@ parser for the regular JSON format.
[#236]: https://github.com/json5/json5/issues/236
[#244]: https://github.com/json5/json5/issues/244
[#266]: https://github.com/json5/json5/issues/266
[#295]: https://github.com/json5/json5/issues/295
84 changes: 64 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
# JSON5 – JSON for Humans

[![Build Status](https://travis-ci.com/json5/json5.svg)][Build Status]
[![Coverage
[![Build Status](https://app.travis-ci.com/json5/json5.svg?branch=main)][Build
Status] [![Coverage
Status](https://coveralls.io/repos/github/json5/json5/badge.svg)][Coverage
Status]

The JSON5 Data Interchange Format (JSON5) is a superset of [JSON] that aims to
alleviate some of the limitations of JSON by expanding its syntax to include
some productions from [ECMAScript 5.1].

This JavaScript library is the official reference implementation for JSON5
parsing and serialization libraries.

[Build Status]: https://travis-ci.com/json5/json5
JSON5 is an extension to the popular [JSON] file format that aims to be
easier to **write and maintain _by hand_ (e.g. for config files)**.
It is _not intended_ to be used for machine-to-machine communication.
(Keep using JSON or other file formats for that. 🙂)

JSON5 was started in 2012, and as of 2022, now gets **[>65M downloads/week](https://www.npmjs.com/package/json5)**,
ranks in the **[top 0.1%](https://gist.github.com/anvaka/8e8fa57c7ee1350e3491)** of the most depended-upon packages on npm,
and has been adopted by major projects like
**[Chromium](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=5de823b36e68fd99009a29281b17bc3a1d6b329c),
[Next.js](https://github.com/vercel/next.js/blob/b88f20c90bf4659b8ad5cb2a27956005eac2c7e8/packages/next/lib/find-config.ts#L43-L46),
[Babel](https://babeljs.io/docs/en/config-files#supported-file-extensions),
[Retool](https://community.retool.com/t/i-am-attempting-to-append-several-text-fields-to-a-google-sheet-but-receiving-a-json5-invalid-character-error/7626),
[WebStorm](https://www.jetbrains.com/help/webstorm/json.html),
and [more](https://github.com/json5/json5/wiki/In-the-Wild)**.
It's also natively supported on **[Apple platforms](https://developer.apple.com/documentation/foundation/jsondecoder/3766916-allowsjson5)**
like **MacOS** and **iOS**.

Formally, the **[JSON5 Data Interchange Format](https://spec.json5.org/)** is a superset of JSON
(so valid JSON files will always be valid JSON5 files)
that expands its syntax to include some productions from [ECMAScript 5.1] (ES5).
It's also a strict _subset_ of ES5, so valid JSON5 files will always be valid ES5.

This JavaScript library is a reference implementation for JSON5 parsing and serialization,
and is directly used in many of the popular projects mentioned above
(where e.g. extreme performance isn't necessary),
but others have created [many other libraries](https://github.com/json5/json5/wiki/In-the-Wild)
across many other platforms.

[Build Status]: https://app.travis-ci.com/json5/json5

[Coverage Status]: https://coveralls.io/github/json5/json5

Expand Down Expand Up @@ -52,7 +73,9 @@ been extended to JSON5.

[IEEE 754]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933

## Short Example
## Example
Kitchen-sink example:

```js
{
// comments
Expand All @@ -68,26 +91,42 @@ No \\n's!",
}
```

A more real-world example is [this config file](https://github.com/chromium/chromium/blob/feb3c9f670515edf9a88f185301cbd7794ee3e52/third_party/blink/renderer/platform/runtime_enabled_features.json5)
from the Chromium/Blink project.

## Specification
For a detailed explanation of the JSON5 format, please read the [official
specification](https://json5.github.io/json5-spec/).

## Installation
## Installation and Usage
### Node.js
```sh
npm install json5
```

#### CommonJS
```js
const JSON5 = require('json5')
```

#### Modules
```js
import JSON5 from 'json5'
```

### Browsers
#### UMD
```html
<script src="https://unpkg.com/json5@^2.0.0/dist/index.min.js"></script>
<!-- This will create a global `JSON5` variable. -->
<script src="https://unpkg.com/json5@2/dist/index.min.js"></script>
```

This will create a global `JSON5` variable.
#### Modules
```html
<script type="module">
import JSON5 from 'https://unpkg.com/json5@2/dist/index.min.mjs'
</script>
```

## API
The JSON5 API is compatible with the [JSON API].
Expand Down Expand Up @@ -195,18 +234,23 @@ run lint` before submitting pull requests. Please use an editor that supports
[EditorConfig](http://editorconfig.org/).

### Issues
To report bugs or request features regarding the JSON5 data format, please
submit an issue to the [official specification
repository](https://github.com/json5/json5-spec).
To report bugs or request features regarding the JSON5 **data format**,
please submit an issue to the official
**[_specification_ repository](https://github.com/json5/json5-spec)**.

Note that we will never add any features that make JSON5 incompatible with ES5;
that compatibility is a fundamental premise of JSON5.

To report bugs or request features regarding the JavaScript implementation of
JSON5, please submit an issue to this repository.
To report bugs or request features regarding this **JavaScript implementation**
of JSON5, please submit an issue to **_this_ repository**.

## License
MIT. See [LICENSE.md](./LICENSE.md) for details.

## Credits
[Assem Kishore](https://github.com/aseemk) founded this project.
[Aseem Kishore](https://github.com/aseemk) founded this project.
He wrote a [blog post](https://aseemk.substack.com/p/ignore-the-f-ing-haters-json5)
about the journey and lessons learned 10 years in.

[Michael Bolin](http://bolinfest.com/) independently arrived at and published
some of these same ideas with awesome explanations and detail. Recommended
Expand Down
41 changes: 34 additions & 7 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,34 @@ module.exports = function parse (text, reviver) {
function internalize (holder, name, reviver) {
const value = holder[name]
if (value != null && typeof value === 'object') {
for (const key in value) {
const replacement = internalize(value, key, reviver)
if (replacement === undefined) {
delete value[key]
} else {
value[key] = replacement
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
const key = String(i)
const replacement = internalize(value, key, reviver)
if (replacement === undefined) {
delete value[key]
} else {
Object.defineProperty(value, key, {
value: replacement,
writable: true,
enumerable: true,
configurable: true,
})
}
}
} else {
for (const key in value) {
const replacement = internalize(value, key, reviver)
if (replacement === undefined) {
delete value[key]
} else {
Object.defineProperty(value, key, {
value: replacement,
writable: true,
enumerable: true,
configurable: true,
})
}
}
}
}
Expand Down Expand Up @@ -973,7 +995,12 @@ function push () {
if (Array.isArray(parent)) {
parent.push(value)
} else {
parent[key] = value
Object.defineProperty(parent, key, {
value,
writable: true,
enumerable: true,
configurable: true,
})
}
}

Expand Down
Loading