json_canonicalizer 1.1.0 copy "json_canonicalizer: ^1.1.0" to clipboard
json_canonicalizer: ^1.1.0 copied to clipboard

A dependency-free RFC 8785 JSON Canonicalization Scheme implementation for Dart.

json_canonicalizer #

A dependency-free RFC 8785 JSON Canonicalization Scheme implementation for Dart.

Install #

dart pub add json_canonicalizer

Usage #

Both accept an already-parsed JSON value.

  • canonicalize(value) returns canonical JSON as a String.
  • canonicalizeUtf8(value) returns the same JSON as UTF-8 bytes for hashing or signing.

Both also take allowInvalidUnicode. Pass true to escape a lone UTF-16 surrogate as \uXXXX instead of throwing. RFC 8785 requires rejecting a lone surrogate, but Dart strings can contain one from truncated or malformed input.

Examples #

import 'package:json_canonicalizer/json_canonicalizer.dart';

// Sorts object keys by UTF-16 order and removes extra spaces.
canonicalize({'b': 1, '\u{e000}': 'private use', '😳': 'flushed', 'a': 2});
// {"a":2,"b":1,"😳":"flushed","ξ€€":"private use"}

// Formats numbers the same way as JavaScript JSON.
canonicalize(<Object?>[-0.0, 333333333.33333329, 1e30, 0.000001]);
// [0,333333333.3333333,1e+30,0.000001]

// Returns UTF-8 bytes for hashing or signing.
canonicalizeUtf8({'currency': '€'});
// [123, 34, 99, 117, 114, 114, 101, 110, 99, 121, 34, 58, 34, 226, 130, 172, 34, 125]

// A lone surrogate throws by default.
canonicalize('a\ud800b');
// Throws JsonCanonicalizationException.

// allowInvalidUnicode escapes it instead.
canonicalize('a\ud800b', allowInvalidUnicode: true);
// "a\ud800b"

Boundaries #

Pass in a JSON value that has already been parsed. It can contain null, booleans, finite numbers, valid Unicode strings, lists, and maps with string keys. This package only canonicalizes the value; it does not parse, normalize, hash, sign, or call toJson.

Case Result
Arrays Preserve their original order.
Object keys Sort by UTF-16 code units.
Strings Escape control characters, quotes, and backslashes. Keep other Unicode unchanged.
-0.0 Writes 0.
NaN, infinity, lossy int, non-string key, cycle Throw JsonCanonicalizationException.
Lone surrogate Throws, unless you pass allowInvalidUnicode.
Nested lists and maps Work up to 100,000 levels deep.

Errors point to the invalid value with an RFC 6901 path:

try {
  canonicalize({
    'payload': [
      {'a/b~c': double.nan},
    ],
  });
} on JsonCanonicalizationException catch (error) {
  print(error.path);
  // /payload/0/a~1b~0c
}

The test suite covers RFC 8785 examples, Appendix B number vectors, the upstream JCS corpus, Unicode, escaping, invalid input, cycles, shared subtrees, allowInvalidUnicode, and 100,000-level lists and maps.

License #

Unlicense. Upstream test vectors in test/ are Apache-2.0.

0
likes
150
points
192
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A dependency-free RFC 8785 JSON Canonicalization Scheme implementation for Dart.

Repository (GitHub)
View/report issues

Topics

#canonicalization #cryptography #json #rfc-8785

License

Unlicense (license)

More

Packages that depend on json_canonicalizer