github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/jsonutil/safejson/safejson_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package safejson_test 21 22 import ( 23 "encoding/json" 24 "testing" 25 26 "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/jsonutil/safejson" 29 ) 30 31 func Test(t *testing.T) { check.TestingT(t) } 32 33 type escapeSuite struct{} 34 35 var _ = check.Suite(escapeSuite{}) 36 37 var table = map[string]string{ 38 "null": "", 39 `"hello"`: "hello", 40 `"árbol"`: "árbol", 41 `"\u0020"`: " ", 42 `"\uD83D\uDE00"`: "😀", 43 `"a\b\r\tb"`: "ab", 44 `"\\\""`: `\"`, 45 // escape sequences (NOTE just the control char is stripped) 46 `"\u001b[3mhello\u001b[m"`: "[3mhello[m", 47 `"a\u0080z"`: "az", 48 "\"a\u0080z\"": "az", 49 "\"a\u007fz\"": "az", 50 "\"a\u009fz\"": "az", 51 // replacement char 52 `"a\uFFFDb"`: "ab", 53 // private unicode chars 54 `"a\uE000b"`: "ab", 55 `"a\uDB80\uDC00b"`: "ab", 56 } 57 58 func (escapeSuite) TestStrings(c *check.C) { 59 var u safejson.String 60 for j, s := range table { 61 comm := check.Commentf(j) 62 c.Assert(json.Unmarshal([]byte(j), &u), check.IsNil, comm) 63 c.Check(u.Clean(), check.Equals, s, comm) 64 65 c.Assert(u.UnmarshalJSON([]byte(j)), check.IsNil, comm) 66 c.Check(u.Clean(), check.Equals, s, comm) 67 } 68 } 69 70 func (escapeSuite) TestBadStrings(c *check.C) { 71 var u1 safejson.String 72 73 cc0 := make([][]byte, 0x20) 74 for i := range cc0 { 75 cc0[i] = []byte{'"', byte(i), '"'} 76 } 77 badesc := make([][]byte, 0, 0x7f-0x21-9) 78 for c := byte('!'); c <= '~'; c++ { 79 switch c { 80 case '"', '\\', '/', 'b', 'f', 'n', 'r', 't', 'u': 81 continue 82 default: 83 badesc = append(badesc, []byte{'"', '\\', c, '"'}) 84 } 85 } 86 87 table := map[string][][]byte{ 88 // these are from json itself (so we're not checking them): 89 "invalid character '.+' in string literal": cc0, 90 "invalid character '.+' in string escape code": badesc, 91 `invalid character '.+' in \\u .*`: {[]byte(`"\u02"`), []byte(`"\u02zz"`)}, 92 "invalid character '\"' after top-level value": {[]byte(`"""`)}, 93 "unexpected end of JSON input": {[]byte(`"\"`)}, 94 } 95 96 for e, js := range table { 97 for _, j := range js { 98 comm := check.Commentf("%q", j) 99 c.Check(json.Unmarshal(j, &u1), check.ErrorMatches, e, comm) 100 } 101 } 102 103 table = map[string][][]byte{ 104 // these are from our lib 105 `missing string delimiters.*`: {{}, {'"'}}, 106 `unexpected control character at 0 in "\\.+"`: cc0, 107 `unknown escape '.' at 1 of "\\."`: badesc, 108 `badly formed \\u escape.*`: { 109 []byte(`"\u02"`), []byte(`"\u02zz"`), []byte(`"a\u02xxz"`), 110 []byte(`"\uD83Da"`), []byte(`"\uD83Da\u20"`), []byte(`"\uD83Da\u20zzz"`), 111 }, 112 `unexpected unescaped quote at 0 in """`: {[]byte(`"""`)}, 113 `unexpected end of string \(trailing backslash\).*`: {[]byte(`"\"`)}, 114 } 115 116 for e, js := range table { 117 for _, j := range js { 118 comm := check.Commentf("%q", j) 119 c.Check(u1.UnmarshalJSON(j), check.ErrorMatches, e, comm) 120 } 121 } 122 } 123 124 func (escapeSuite) TestParagraph(c *check.C) { 125 var u safejson.Paragraph 126 for j1, v1 := range table { 127 for j2, v2 := range table { 128 if j2 == "null" && j1 != "null" { 129 continue 130 } 131 132 var j, s string 133 134 if j1 == "null" { 135 j = j2 136 s = v2 137 } else { 138 j = j1[:len(j1)-1] + "\\n" + j2[1:] 139 s = v1 + "\n" + v2 140 } 141 142 comm := check.Commentf(j) 143 c.Assert(json.Unmarshal([]byte(j), &u), check.IsNil, comm) 144 c.Check(u.Clean(), check.Equals, s, comm) 145 } 146 } 147 148 }