github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/jsonbytes/jsonbytes.go (about) 1 // Copyright 2020 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package jsonbytes 12 13 import "unicode/utf8" 14 15 const hexAlphabet = "0123456789abcdef" 16 17 // EncodeString writes a string literal to b as a JSON string. 18 // Note that the delimiting double quotes are not included. 19 // Cribbed from https://github.com/golang/go/blob/7badae85f20f1bce4cc344f9202447618d45d414/src/encoding/json/encode.go. 20 func EncodeString(buf []byte, s string) []byte { 21 start := 0 22 for i := 0; i < len(s); { 23 if b := s[i]; b < utf8.RuneSelf { 24 if b >= ' ' && b != '"' && b != '\\' { 25 i++ 26 continue 27 } 28 if start < i { 29 buf = append(buf, s[start:i]...) 30 } 31 switch b { 32 case '\\', '"': 33 buf = append(buf, '\\', b) 34 case '\n': 35 buf = append(buf, '\\', 'n') 36 case '\r': 37 buf = append(buf, '\\', 'r') 38 case '\t': 39 buf = append(buf, '\\', 't') 40 default: 41 // This encodes bytes < 0x20 except for \t, \n and \r. 42 // If escapeHTML is set, it also escapes <, >, and & 43 // because they can lead to security holes when 44 // user-controlled strings are rendered into JSON 45 // and served to some browsers. 46 buf = append(buf, '\\', 'u', '0', '0', hexAlphabet[b>>4], hexAlphabet[b&0xF]) 47 } 48 i++ 49 start = i 50 continue 51 } 52 c, size := utf8.DecodeRuneInString(s[i:]) 53 if c == utf8.RuneError && size == 1 { 54 if start < i { 55 buf = append(buf, s[start:i]...) 56 } 57 buf = append(buf, `\ufffd`...) 58 i += size 59 start = i 60 continue 61 } 62 i += size 63 } 64 if start < len(s) { 65 buf = append(buf, s[start:]...) 66 } 67 return buf 68 }