mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 16:12:24 -05:00 
			
		
		
		
	Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.1.0 to 1.2.2. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.1.0...v1.2.2) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
		
			
				
	
	
		
			562 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			562 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
|  * Copyright 2022 ByteDance Inc.
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| package ast
 | |
| 
 | |
| import (
 | |
| 	"encoding/base64"
 | |
| 	"runtime"
 | |
| 	"strconv"
 | |
| 	"unsafe"
 | |
| 
 | |
| 	"github.com/bytedance/sonic/internal/native/types"
 | |
| 	"github.com/bytedance/sonic/internal/rt"
 | |
| 	"github.com/bytedance/sonic/internal/utils"
 | |
| )
 | |
| 
 | |
| // Hack: this is used for both checking space and cause friendly compile errors in 32-bit arch.
 | |
| const _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
 | |
| 
 | |
| var bytesNull   = []byte("null")
 | |
| 
 | |
| const (
 | |
|     strNull   = "null"
 | |
|     bytesTrue   = "true"
 | |
|     bytesFalse  = "false"
 | |
|     bytesObject = "{}"
 | |
|     bytesArray  = "[]"
 | |
| )
 | |
| 
 | |
| func isSpace(c byte) bool {
 | |
|     return (int(1<<c) & _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here) != 0
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func skipBlank(src string, pos int) int {
 | |
|     se := uintptr(rt.IndexChar(src, len(src)))
 | |
|     sp := uintptr(rt.IndexChar(src, pos))
 | |
| 
 | |
|     for sp < se {
 | |
|         if !isSpace(*(*byte)(unsafe.Pointer(sp))) {
 | |
|             break
 | |
|         }
 | |
|         sp += 1
 | |
|     }
 | |
|     if sp >= se {
 | |
|         return -int(types.ERR_EOF)
 | |
|     }
 | |
|     runtime.KeepAlive(src)
 | |
|     return int(sp - uintptr(rt.IndexChar(src, 0)))
 | |
| }
 | |
| 
 | |
| func decodeNull(src string, pos int) (ret int) {
 | |
|     ret = pos + 4
 | |
|     if ret > len(src) {
 | |
|         return -int(types.ERR_EOF)
 | |
|     }
 | |
|     if src[pos:ret] == strNull {
 | |
|         return ret
 | |
|     } else {
 | |
|         return -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
| }
 | |
| 
 | |
| func decodeTrue(src string, pos int) (ret int) {
 | |
|     ret = pos + 4
 | |
|     if ret > len(src) {
 | |
|         return -int(types.ERR_EOF)
 | |
|     }
 | |
|     if src[pos:ret] == bytesTrue {
 | |
|         return ret
 | |
|     } else {
 | |
|         return -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| func decodeFalse(src string, pos int) (ret int) {
 | |
|     ret = pos + 5
 | |
|     if ret > len(src) {
 | |
|         return -int(types.ERR_EOF)
 | |
|     }
 | |
|     if src[pos:ret] == bytesFalse {
 | |
|         return ret
 | |
|     }
 | |
|     return -int(types.ERR_INVALID_CHAR)
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func decodeString(src string, pos int) (ret int, v string) {
 | |
|     ret, ep := skipString(src, pos)
 | |
|     if ep == -1 {
 | |
|         (*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1)
 | |
|         (*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2
 | |
|         return ret, v
 | |
|     }
 | |
| 
 | |
|     vv, ok := unquoteBytes(rt.Str2Mem(src[pos:ret]))
 | |
|     if !ok {
 | |
|         return -int(types.ERR_INVALID_CHAR), ""
 | |
|     }
 | |
| 
 | |
|     runtime.KeepAlive(src)
 | |
|     return ret, rt.Mem2Str(vv)
 | |
| }
 | |
| 
 | |
| func decodeBinary(src string, pos int) (ret int, v []byte) {
 | |
|     var vv string
 | |
|     ret, vv = decodeString(src, pos)
 | |
|     if ret < 0 {
 | |
|         return ret, nil
 | |
|     }
 | |
|     var err error
 | |
|     v, err = base64.StdEncoding.DecodeString(vv)
 | |
|     if err != nil {
 | |
|         return -int(types.ERR_INVALID_CHAR), nil
 | |
|     }
 | |
|     return ret, v
 | |
| }
 | |
| 
 | |
| func isDigit(c byte) bool {
 | |
|     return c >= '0' && c <= '9'
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func decodeInt64(src string, pos int) (ret int, v int64, err error) {
 | |
|     sp := uintptr(rt.IndexChar(src, pos))
 | |
|     ss := uintptr(sp)
 | |
|     se := uintptr(rt.IndexChar(src, len(src)))
 | |
|     if uintptr(sp) >= se {
 | |
|         return -int(types.ERR_EOF), 0, nil
 | |
|     }
 | |
| 
 | |
|     if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
 | |
|         sp += 1
 | |
|     }
 | |
|     if sp == se {
 | |
|         return -int(types.ERR_EOF), 0, nil
 | |
|     }
 | |
| 
 | |
|     for ; sp < se; sp += uintptr(1) {
 | |
|         if !isDigit(*(*byte)(unsafe.Pointer(sp))) {
 | |
|             break
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if sp < se {
 | |
|         if c := *(*byte)(unsafe.Pointer(sp)); c == '.' || c == 'e' || c == 'E' {
 | |
|             return -int(types.ERR_INVALID_NUMBER_FMT), 0, nil
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     var vv string
 | |
|     ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
 | |
|     (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
 | |
|     (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
 | |
| 
 | |
|     v, err = strconv.ParseInt(vv, 10, 64)
 | |
|     if err != nil {
 | |
|         //NOTICE: allow overflow here
 | |
|         if err.(*strconv.NumError).Err == strconv.ErrRange {
 | |
|             return ret, 0, err
 | |
|         }
 | |
|         return -int(types.ERR_INVALID_CHAR), 0, err
 | |
|     }
 | |
| 
 | |
|     runtime.KeepAlive(src)
 | |
|     return ret, v, nil
 | |
| }
 | |
| 
 | |
| func isNumberChars(c byte) bool {
 | |
|     return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.'
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
 | |
|     sp := uintptr(rt.IndexChar(src, pos))
 | |
|     ss := uintptr(sp)
 | |
|     se := uintptr(rt.IndexChar(src, len(src)))
 | |
|     if uintptr(sp) >= se {
 | |
|         return -int(types.ERR_EOF), 0, nil
 | |
|     }
 | |
| 
 | |
|     if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
 | |
|         sp += 1
 | |
|     }
 | |
|     if sp == se {
 | |
|         return -int(types.ERR_EOF), 0, nil
 | |
|     }
 | |
| 
 | |
|     for ; sp < se; sp += uintptr(1) {
 | |
|         if !isNumberChars(*(*byte)(unsafe.Pointer(sp))) {
 | |
|             break
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     var vv string
 | |
|     ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
 | |
|     (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
 | |
|     (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
 | |
| 
 | |
|     v, err = strconv.ParseFloat(vv, 64)
 | |
|     if err != nil {
 | |
|         //NOTICE: allow overflow here
 | |
|         if err.(*strconv.NumError).Err == strconv.ErrRange {
 | |
|             return ret, 0, err
 | |
|         }
 | |
|         return -int(types.ERR_INVALID_CHAR), 0, err
 | |
|     }
 | |
| 
 | |
|     runtime.KeepAlive(src)
 | |
|     return ret, v, nil
 | |
| }
 | |
| 
 | |
| func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState) {
 | |
|     pos = skipBlank(src, pos)
 | |
|     if pos < 0 {
 | |
|         return pos, types.JsonState{Vt: types.ValueType(pos)}
 | |
|     }
 | |
|     switch c := src[pos]; c {
 | |
|     case 'n':
 | |
|         ret = decodeNull(src, pos)
 | |
|         if ret < 0 {
 | |
|             return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|         }
 | |
|         return ret, types.JsonState{Vt: types.V_NULL}
 | |
|     case '"':
 | |
|         var ep int
 | |
|         ret, ep = skipString(src, pos)
 | |
|         if ret < 0 {
 | |
|             return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|         }
 | |
|         return ret, types.JsonState{Vt: types.V_STRING, Iv: int64(pos + 1), Ep: ep}
 | |
|     case '{':
 | |
|         return pos + 1, types.JsonState{Vt: types.V_OBJECT}
 | |
|     case '[':
 | |
|         return pos + 1, types.JsonState{Vt: types.V_ARRAY}
 | |
|     case 't':
 | |
|         ret = decodeTrue(src, pos)
 | |
|         if ret < 0 {
 | |
|             return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|         }
 | |
|         return ret, types.JsonState{Vt: types.V_TRUE}
 | |
|     case 'f':
 | |
|         ret = decodeFalse(src, pos)
 | |
|         if ret < 0 {
 | |
|             return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|         }
 | |
|         return ret, types.JsonState{Vt: types.V_FALSE}
 | |
|     case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | |
|         if skipnum {
 | |
|             ret = skipNumber(src, pos)
 | |
|             if ret >= 0 {
 | |
|                 return ret, types.JsonState{Vt: types.V_DOUBLE, Iv: 0, Ep: pos}
 | |
|             } else {
 | |
|                 return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|             }
 | |
|         } else {
 | |
|             var iv int64
 | |
|             ret, iv, _ = decodeInt64(src, pos)
 | |
|             if ret >= 0 {
 | |
|                 return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos}
 | |
|             } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) {
 | |
|                 return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|             }
 | |
|             var fv float64
 | |
|             ret, fv, _ = decodeFloat64(src, pos)
 | |
|             if ret >= 0 {
 | |
|                 return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos}
 | |
|             } else {
 | |
|                 return ret, types.JsonState{Vt: types.ValueType(ret)}
 | |
|             }
 | |
|         }
 | |
|         
 | |
|     default:
 | |
|         return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)}
 | |
|     }
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func skipNumber(src string, pos int) (ret int) {
 | |
|     return utils.SkipNumber(src, pos)
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func skipString(src string, pos int) (ret int, ep int) {
 | |
|     if pos+1 >= len(src) {
 | |
|         return -int(types.ERR_EOF), -1
 | |
|     }
 | |
| 
 | |
|     sp := uintptr(rt.IndexChar(src, pos))
 | |
|     se := uintptr(rt.IndexChar(src, len(src)))
 | |
| 
 | |
|     // not start with quote
 | |
|     if *(*byte)(unsafe.Pointer(sp)) != '"' {
 | |
|         return -int(types.ERR_INVALID_CHAR), -1
 | |
|     }
 | |
|     sp += 1
 | |
| 
 | |
|     ep = -1
 | |
|     for sp < se {
 | |
|         c := *(*byte)(unsafe.Pointer(sp))
 | |
|         if c == '\\' {
 | |
|             if ep == -1 {
 | |
|                 ep = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
 | |
|             }
 | |
|             sp += 2
 | |
|             continue
 | |
|         }
 | |
|         sp += 1
 | |
|         if c == '"' {
 | |
|             return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     runtime.KeepAlive(src)
 | |
|     // not found the closed quote until EOF
 | |
|     return -int(types.ERR_EOF), -1
 | |
| }
 | |
| 
 | |
| //go:nocheckptr
 | |
| func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) {
 | |
|     if pos+1 >= len(src) {
 | |
|         return -int(types.ERR_EOF)
 | |
|     }
 | |
| 
 | |
|     sp := uintptr(rt.IndexChar(src, pos))
 | |
|     se := uintptr(rt.IndexChar(src, len(src)))
 | |
| 
 | |
|     if *(*byte)(unsafe.Pointer(sp)) != lchar {
 | |
|         return -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
| 
 | |
|     sp += 1
 | |
|     nbrace := 1
 | |
|     inquote := false
 | |
| 
 | |
|     for sp < se {
 | |
|         c := *(*byte)(unsafe.Pointer(sp))
 | |
|         if c == '\\' {
 | |
|             sp += 2
 | |
|             continue
 | |
|         } else if c == '"' {
 | |
|             inquote = !inquote
 | |
|         } else if c == lchar {
 | |
|             if !inquote {
 | |
|                 nbrace += 1
 | |
|             }
 | |
|         } else if c == rchar {
 | |
|             if !inquote {
 | |
|                 nbrace -= 1
 | |
|                 if nbrace == 0 {
 | |
|                     sp += 1
 | |
|                     break
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         sp += 1
 | |
|     }
 | |
| 
 | |
|     if nbrace != 0 {
 | |
|         return -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
| 
 | |
|     runtime.KeepAlive(src)
 | |
|     return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
 | |
| }
 | |
| 
 | |
| func skipValueFast(src string, pos int) (ret int, start int) {
 | |
|     pos = skipBlank(src, pos)
 | |
|     if pos < 0 {
 | |
|         return pos, -1
 | |
|     }
 | |
|     switch c := src[pos]; c {
 | |
|     case 'n':
 | |
|         ret = decodeNull(src, pos)
 | |
|     case '"':
 | |
|         ret, _ = skipString(src, pos)
 | |
|     case '{':
 | |
|         ret = skipPair(src, pos, '{', '}')
 | |
|     case '[':
 | |
|         ret = skipPair(src, pos, '[', ']')
 | |
|     case 't':
 | |
|         ret = decodeTrue(src, pos)
 | |
|     case 'f':
 | |
|         ret = decodeFalse(src, pos)
 | |
|     case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | |
|         ret = skipNumber(src, pos)
 | |
|     default:
 | |
|         ret = -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
|     return ret, pos
 | |
| }
 | |
| 
 | |
| func skipValue(src string, pos int) (ret int, start int) {
 | |
|     pos = skipBlank(src, pos)
 | |
|     if pos < 0 {
 | |
|         return pos, -1
 | |
|     }
 | |
|     switch c := src[pos]; c {
 | |
|     case 'n':
 | |
|         ret = decodeNull(src, pos)
 | |
|     case '"':
 | |
|         ret, _ = skipString(src, pos)
 | |
|     case '{':
 | |
|         ret, _ = skipObject(src, pos)
 | |
|     case '[':
 | |
|         ret, _ = skipArray(src, pos)
 | |
|     case 't':
 | |
|         ret = decodeTrue(src, pos)
 | |
|     case 'f':
 | |
|         ret = decodeFalse(src, pos)
 | |
|     case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | |
|         ret = skipNumber(src, pos)
 | |
|     default:
 | |
|         ret = -int(types.ERR_INVALID_CHAR)
 | |
|     }
 | |
|     return ret, pos
 | |
| }
 | |
| 
 | |
| func skipObject(src string, pos int) (ret int, start int) {
 | |
|     start = skipBlank(src, pos)
 | |
|     if start < 0 {
 | |
|         return start, -1
 | |
|     }
 | |
| 
 | |
|     if src[start] != '{' {
 | |
|         return -int(types.ERR_INVALID_CHAR), -1
 | |
|     }
 | |
| 
 | |
|     pos = start + 1
 | |
|     pos = skipBlank(src, pos)
 | |
|     if pos < 0 {
 | |
|         return pos, -1
 | |
|     }
 | |
|     if src[pos] == '}' {
 | |
|         return pos + 1, start
 | |
|     }
 | |
| 
 | |
|     for {
 | |
|         pos, _ = skipString(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
| 
 | |
|         pos = skipBlank(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
|         if src[pos] != ':' {
 | |
|             return -int(types.ERR_INVALID_CHAR), -1
 | |
|         }
 | |
| 
 | |
|         pos++
 | |
|         pos, _ = skipValue(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
| 
 | |
|         pos = skipBlank(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
|         if src[pos] == '}' {
 | |
|             return pos + 1, start
 | |
|         }
 | |
|         if src[pos] != ',' {
 | |
|             return -int(types.ERR_INVALID_CHAR), -1
 | |
|         }
 | |
| 
 | |
|         pos++
 | |
|         pos = skipBlank(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| func skipArray(src string, pos int) (ret int, start int) {
 | |
|     start = skipBlank(src, pos)
 | |
|     if start < 0 {
 | |
|         return start, -1
 | |
|     }
 | |
| 
 | |
|     if src[start] != '[' {
 | |
|         return -int(types.ERR_INVALID_CHAR), -1
 | |
|     }
 | |
| 
 | |
|     pos = start + 1
 | |
|     pos = skipBlank(src, pos)
 | |
|     if pos < 0 {
 | |
|         return pos, -1
 | |
|     }
 | |
|     if src[pos] == ']' {
 | |
|         return pos + 1, start
 | |
|     }
 | |
| 
 | |
|     for {
 | |
|         pos, _ = skipValue(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
| 
 | |
|         pos = skipBlank(src, pos)
 | |
|         if pos < 0 {
 | |
|             return pos, -1
 | |
|         }
 | |
|         if src[pos] == ']' {
 | |
|             return pos + 1, start
 | |
|         }
 | |
|         if src[pos] != ',' {
 | |
|             return -int(types.ERR_INVALID_CHAR), -1
 | |
|         }
 | |
|         pos++
 | |
|     }
 | |
| }
 | |
| 
 | |
| // DecodeString decodes a JSON string from pos and return golang string.
 | |
| //   - needEsc indicates if to unescaped escaping chars
 | |
| //   - hasEsc tells if the returned string has escaping chars
 | |
| //   - validStr enables validating UTF8 charset
 | |
| //
 | |
| func _DecodeString(src string, pos int, needEsc bool, validStr bool) (v string, ret int, hasEsc bool) {
 | |
|     p := NewParserObj(src)
 | |
|     p.p = pos
 | |
|     switch val := p.decodeValue(); val.Vt {
 | |
|     case types.V_STRING:
 | |
|         str := p.s[val.Iv : p.p-1]
 | |
|         if validStr && !validate_utf8(str) {
 | |
|            return "", -int(types.ERR_INVALID_UTF8), false
 | |
|         }
 | |
|         /* fast path: no escape sequence */
 | |
|         if val.Ep == -1 {
 | |
|             return str, p.p, false
 | |
|         } else if !needEsc {
 | |
|             return str, p.p, true
 | |
|         }
 | |
|         /* unquote the string */
 | |
|         out, err := unquote(str)
 | |
|         /* check for errors */
 | |
|         if err != 0 {
 | |
|             return "", -int(err), true
 | |
|         } else {
 | |
|             return out, p.p, true
 | |
|         }
 | |
|     default:
 | |
|         return "", -int(_ERR_UNSUPPORT_TYPE), false
 | |
|     }
 | |
| }
 |