feat: add vendor

This commit is contained in:
fengcaiwen
2023-10-21 20:48:01 +08:00
parent 1c637f45b5
commit 6a6c4e3257
8701 changed files with 2400820 additions and 1 deletions

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2021 NYU Secure Systems Lab
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,145 @@
package cjson
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"reflect"
"regexp"
"sort"
)
/*
encodeCanonicalString is a helper function to canonicalize the passed string
according to the OLPC canonical JSON specification for strings (see
http://wiki.laptop.org/go/Canonical_JSON). String canonicalization consists of
escaping backslashes ("\") and double quotes (") and wrapping the resulting
string in double quotes (").
*/
func encodeCanonicalString(s string) string {
re := regexp.MustCompile(`([\"\\])`)
return fmt.Sprintf("\"%s\"", re.ReplaceAllString(s, "\\$1"))
}
/*
encodeCanonical is a helper function to recursively canonicalize the passed
object according to the OLPC canonical JSON specification (see
http://wiki.laptop.org/go/Canonical_JSON) and write it to the passed
*bytes.Buffer. If canonicalization fails it returns an error.
*/
func encodeCanonical(obj interface{}, result *bytes.Buffer) (err error) {
// Since this function is called recursively, we use panic if an error occurs
// and recover in a deferred function, which is always called before
// returning. There we set the error that is returned eventually.
defer func() {
if r := recover(); r != nil {
err = errors.New(r.(string))
}
}()
switch objAsserted := obj.(type) {
case string:
result.WriteString(encodeCanonicalString(objAsserted))
case bool:
if objAsserted {
result.WriteString("true")
} else {
result.WriteString("false")
}
// The wrapping `EncodeCanonical` function decodes the passed json data with
// `decoder.UseNumber` so that any numeric value is stored as `json.Number`
// (instead of the default `float64`). This allows us to assert that it is a
// non-floating point number, which are the only numbers allowed by the used
// canonicalization specification.
case json.Number:
if _, err := objAsserted.Int64(); err != nil {
panic(fmt.Sprintf("Can't canonicalize floating point number '%s'",
objAsserted))
}
result.WriteString(objAsserted.String())
case nil:
result.WriteString("null")
// Canonicalize slice
case []interface{}:
result.WriteString("[")
for i, val := range objAsserted {
if err := encodeCanonical(val, result); err != nil {
return err
}
if i < (len(objAsserted) - 1) {
result.WriteString(",")
}
}
result.WriteString("]")
case map[string]interface{}:
result.WriteString("{")
// Make a list of keys
var mapKeys []string
for key := range objAsserted {
mapKeys = append(mapKeys, key)
}
// Sort keys
sort.Strings(mapKeys)
// Canonicalize map
for i, key := range mapKeys {
// Note: `key` must be a `string` (see `case map[string]interface{}`) and
// canonicalization of strings cannot err out (see `case string`), thus
// no error handling is needed here.
encodeCanonical(key, result)
result.WriteString(":")
if err := encodeCanonical(objAsserted[key], result); err != nil {
return err
}
if i < (len(mapKeys) - 1) {
result.WriteString(",")
}
i++
}
result.WriteString("}")
default:
// We recover in a deferred function defined above
panic(fmt.Sprintf("Can't canonicalize '%s' of type '%s'",
objAsserted, reflect.TypeOf(objAsserted)))
}
return nil
}
/*
EncodeCanonical JSON canonicalizes the passed object and returns it as a byte
slice. It uses the OLPC canonical JSON specification (see
http://wiki.laptop.org/go/Canonical_JSON). If canonicalization fails the byte
slice is nil and the second return value contains the error.
*/
func EncodeCanonical(obj interface{}) ([]byte, error) {
// FIXME: Terrible hack to turn the passed struct into a map, converting
// the struct's variable names to the json key names defined in the struct
data, err := json.Marshal(obj)
if err != nil {
return nil, err
}
var jsonMap interface{}
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
if err := dec.Decode(&jsonMap); err != nil {
return nil, err
}
// Create a buffer and write the canonicalized JSON bytes to it
var result bytes.Buffer
if err := encodeCanonical(jsonMap, &result); err != nil {
return nil, err
}
return result.Bytes(), nil
}