jcs

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2020 License: MIT Imports: 7 Imported by: 1

README

jcs

GoDev GitHub Workflow Status

This package is a Golang implementation of JSON Canonicalization Scheme ("JCS"), aka RFC 8785. This package complies with all test data supplied by the JCS spec authors.

Installation

To install this package, run:

go get github.com/ucarion/jcs

Usage

This package works on the standard JSON-like Golang data structures, namely:

  • bool, for JSON booleans
  • float64, for JSON numbers
  • string, for JSON strings
  • []interface{}, for JSON arrays
  • map[string]interface{}, for JSON objects
  • nil for JSON null

These are the types of data you get out of json.Unmarshal by default. So, to encode some existing JSON data into canonical format, you can do something like:

import (
  "encoding/json"
  "fmt"

  "github.com/ucarion/jcs"
)

fn main() {
  input := `{"z": [1, 2, 3], "a": "foo" }`

  var v interface{}
  if err := json.Unmarshal([]byte(input), &v); err != nil {
    panic(err)
  }

  // See note about error handling below
  out, _ := jcs.Format(v)
  fmt.Println(out)
}

If you have an existing buffer you'd prefer to output to instead, use jcs.Append instead of jcs.Format:

var buf []byte

// See note about error handling below
buf, _ = jcs.Append(buf, &input)

You can, of course, pass your own data structures to Format or Append, but note that you will get an error if you use a type other than those described above.

Error Handling

See the documentation for more details, but note that Append and Format may return errors if any of the following are true:

  • The inputted data contains types other than those listed in "Usage".
  • The inputted data contains NaN.
  • The inputted data contains positive or negative infinity.

If your inputted data is an interface{} from json.Unmarshal, then you do not need to worry about errors from this package. Otherwise, you will need to somehow ensure you don't pass unsupported data, or otherwise add support for an error from this package.

Contributing

A note on testing in this package: the TestFormatFloat100M test in this package is disabled by default, because it takes too long time and compute power to run by default. Plus, the required test file takes 3.8G of disk space.

If you would like to thoroughly test the encoding of float64 values in this package, download es6testfile100m.txt from the link in the testdata dir of the JCS repo. When running tests, pass JCS_TEST_100M=1, for instance:

JCS_TEST_100M=1 go test ./... -v

Passing -v will show you a progress indication once for every million tests run.

Documentation

Overview

Package jcs implements JSON Canonicalization Scheme, formalized as RFC8785:

https://www.rfc-editor.org/rfc/rfc8785.html

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrInf = errors.New("jcs: cannot c14n Inf")

ErrInf indicates that the inputted value is or contains infinity or negative infinity.

View Source
var ErrNaN = errors.New("jcs: cannot c14n NaN")

ErrNaN indicates that the inputted value is or contains NaN.

View Source
var ErrUnsupportedType = errors.New("jcs: value has unsupported type")

ErrUnsupportedType indicates the inputted value is or contains a type outside the set of types described in Append.

Functions

func Append

func Append(b []byte, v interface{}) ([]byte, error)

Append appends the JCS canonical representation of the value v to b and returns the extended buffer.

Append only supports the types used by encoding/json to unmarshal into an interface value, namely:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

Any other types, including types embedded within maps or arrays in the value v, will result in Append returning ErrUnsupportedType.

Furthermore, if v contains float64 values that are NaN, Infinity, or negative Infinity, then Append will return either ErrNaN or ErrInf.

Append does not check if strings contain invalid surrogate pairs. Codepoints in strings will be appended to b as-is, with the appropriate escaping required by JCS.

func Format

func Format(v interface{}) (string, error)

Format returns the JCS canonical representation of the given value.

See Append for the types of data supported, and possible error conditions.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/ucarion/jcs"
)

func main() {
	input := `{"z": [1, 2, 3], "a": "<foo>" }`

	var v interface{}
	if err := json.Unmarshal([]byte(input), &v); err != nil {
		panic(err)
	}

	// This is not going to output JCS canonical JSON, because of quirks in
	// encoding/json's output format.
	outNaive, _ := json.Marshal(v)
	fmt.Println(string(outNaive))

	out, _ := jcs.Format(v)
	fmt.Println(out)
}
Output:

{"a":"\u003cfoo\u003e","z":[1,2,3]}
{"a":"<foo>","z":[1,2,3]}

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL