github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/snap/squashfs/stat_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017-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 squashfs_test 21 22 import ( 23 "fmt" 24 "math" 25 "os" 26 "time" 27 28 . "gopkg.in/check.v1" 29 30 "github.com/snapcore/snapd/snap/squashfs" 31 ) 32 33 func (s *SquashfsTestSuite) TestStatBadNodes(c *C) { 34 badlines := map[string][]string{ 35 "node": { 36 // size, but device 37 "brwxrwxr-x u/u 53595 2017-12-08 11:19 .", 38 "crwxrwxr-x u/u 53595 2017-12-08 11:19 .", 39 // node info is noise 40 "brwxrwxr-x u/u noise 2017-12-08 11:19 .", 41 "crwxrwxr-x u/u noise 2017-12-08 11:19 .", 42 // major is noise 43 "brwxrwxr-x u/u noise, 1 2017-12-08 11:19 .", 44 "crwxrwxr-x u/u noise, 1 2017-12-08 11:19 .", 45 // minor is noise 46 "brwxrwxr-x u/u 1, noise 2017-12-08 11:19 .", 47 "crwxrwxr-x u/u 1, noise 2017-12-08 11:19 .", 48 }, 49 "size": { 50 // size is noise 51 "drwxrwxr-x u/g noise 2017-12-08 11:19 .", 52 "drwxrwxr-x u/g 1noise 2017-12-08 11:19 .", 53 // size too big 54 "drwxrwxr-x u/g 36893488147419103232 2017-12-08 11:19 .", 55 }, 56 "line": { 57 // shorter than the minimum: 58 "-rw-r--r-- too/short 20 2017-12-08 11:19 ./", 59 // truncated: 60 "drwxrwxr-x", 61 "drwxrwxr-x ", 62 "drwxrwxr-x u/u", 63 "drwxrwxr-x u/g ", 64 "drwxrwxr-x u/g 53595", 65 "drwxrwxr-x u/g 53595 ", 66 "drwxrwxr-x u/g 53595 2017-12-08 11:19", 67 "drwxrwxr-x u/g 53595 2017-12-08 11:19 ", 68 69 // mode keeps on going 70 "drwxrwxr-xr-x u/g 53595 2017-12-08 11:19 .", 71 72 // spurious padding: 73 "drwxrwxr-x u/u 53595 2017-12-08 11:19 .", 74 75 // missing size 76 "drwxrwxr-x u/u 2017-12-08 11:19 ", 77 // everything is size 78 "drwxrwxr-x u/u 111111111111111111111111111111111111", 79 }, 80 "mode": { 81 // zombie file type? 82 "zrwxrwxr-x u/g 53595 2017-12-08 11:19 .", 83 // strange permissions 84 "dbwxrwxr-x u/g 53595 2017-12-08 11:19 .", 85 "drbxrwxr-x u/g 53595 2017-12-08 11:19 .", 86 "drwbrwxr-x u/g 53595 2017-12-08 11:19 .", 87 "drwxbwxr-x u/g 53595 2017-12-08 11:19 .", 88 "drwxrbxr-x u/g 53595 2017-12-08 11:19 .", 89 "drwxrwbr-x u/g 53595 2017-12-08 11:19 .", 90 "drwxrwxb-x u/g 53595 2017-12-08 11:19 .", 91 "drwxrwxrbx u/g 53595 2017-12-08 11:19 .", 92 "drwxrwxr-b u/g 53595 2017-12-08 11:19 .", 93 }, 94 "owner": { 95 "-rw-r--r-- some.user.with.a.much.too.long.name/some.group.with.a.much.too.long.name 20 2017-12-08 11:19 ./foo", 96 "-rw-r--r-- nogroup/ 20 2017-12-08 11:19 ./foo", 97 "-rw-r--r-- noslash 20 2017-12-08 11:19 ./foo", 98 "-rw-r--r-- this.line.finishes.before.finishing.owner", 99 }, 100 "time": { 101 // time is bonkers: 102 "drwxrwxr-x u/u 53595 2017-bonkers-what .", 103 }, 104 "path": { 105 // path doesn't start with "." 106 "drwxrwxr-x u/g 53595 2017-12-08 11:19 foo", 107 }, 108 } 109 for kind, lines := range badlines { 110 for _, line := range lines { 111 com := Commentf("%q (expected bad %s)", line, kind) 112 st, err := squashfs.FromRaw([]byte(line)) 113 c.Assert(err, NotNil, com) 114 c.Check(st, IsNil, com) 115 c.Check(err, ErrorMatches, fmt.Sprintf("cannot parse %s: .*", kind)) 116 } 117 } 118 } 119 120 func (s *SquashfsTestSuite) TestStatUserGroup(c *C) { 121 usergroups := [][2]string{ 122 {"u", "g"}, 123 {"user", "group"}, 124 {"some.user.with.a.veery.long.name", "group"}, 125 {"user", "some.group.with.a.very.long.name"}, 126 {"some.user.with.a.veery.long.name", "some.group.with.a.very.long.name"}, 127 } 128 for _, ug := range usergroups { 129 user, group := ug[0], ug[1] 130 raw := []byte(fmt.Sprintf("-rw-r--r-- %s/%s 20 2017-12-08 11:19 ./foo", user, group)) 131 132 com := Commentf("%q", raw) 133 c.Assert(len(user) <= 32, Equals, true, com) 134 c.Assert(len(group) <= 32, Equals, true, com) 135 136 st, err := squashfs.FromRaw(raw) 137 c.Assert(err, IsNil, com) 138 c.Check(st.Mode(), Equals, os.FileMode(0644), com) 139 c.Check(st.Path(), Equals, "/foo", com) 140 c.Check(st.User(), Equals, user, com) 141 c.Check(st.Group(), Equals, group, com) 142 c.Check(st.Size(), Equals, int64(20), com) 143 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 8, 11, 19, 0, 0, time.UTC), com) 144 } 145 } 146 147 func (s *SquashfsTestSuite) TestStatPath(c *C) { 148 paths := [][]byte{ 149 []byte("hello"), 150 []byte(" this is/ a path/(somehow)"), 151 {239, 191, 190}, 152 {0355, 0240, 0200, 0355, 0260, 0200}, 153 } 154 for _, path := range paths { 155 raw := []byte(fmt.Sprintf("-rw-r--r-- user/group 20 2017-12-08 11:19 ./%s", path)) 156 157 com := Commentf("%q", raw) 158 st, err := squashfs.FromRaw(raw) 159 c.Assert(err, IsNil, com) 160 c.Check(st.Mode(), Equals, os.FileMode(0644), com) 161 c.Check(st.Path(), Equals, fmt.Sprintf("/%s", path), com) 162 c.Check(st.User(), Equals, "user", com) 163 c.Check(st.Group(), Equals, "group", com) 164 c.Check(st.Size(), Equals, int64(20), com) 165 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 8, 11, 19, 0, 0, time.UTC), com) 166 } 167 } 168 169 func (s *SquashfsTestSuite) TestStatBlock(c *C) { 170 line := "brw-rw---- root/disk 7, 0 2017-12-05 10:29 ./dev/loop0" 171 st, err := squashfs.FromRaw([]byte(line)) 172 c.Assert(err, IsNil) 173 c.Check(st.Mode(), Equals, os.FileMode(0660|os.ModeDevice)) 174 c.Check(st.Path(), Equals, "/dev/loop0") 175 c.Check(st.User(), Equals, "root") 176 c.Check(st.Group(), Equals, "disk") 177 c.Check(st.Size(), Equals, int64(0)) 178 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 5, 10, 29, 0, 0, time.UTC)) 179 // note the major and minor numbers are ignored (for now) 180 } 181 182 func (s *SquashfsTestSuite) TestStatCharacter(c *C) { 183 line := "crw-rw---- root/audio 14, 3 2017-12-05 10:29 ./dev/dsp" 184 st, err := squashfs.FromRaw([]byte(line)) 185 c.Assert(err, IsNil) 186 c.Check(st.Mode(), Equals, os.FileMode(0660|os.ModeCharDevice)) 187 c.Check(st.Path(), Equals, "/dev/dsp") 188 c.Check(st.User(), Equals, "root") 189 c.Check(st.Group(), Equals, "audio") 190 c.Check(st.Size(), Equals, int64(0)) 191 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 5, 10, 29, 0, 0, time.UTC)) 192 // note the major and minor numbers are ignored (for now) 193 } 194 195 func (s *SquashfsTestSuite) TestStatSymlink(c *C) { 196 line := "lrwxrwxrwx root/root 4 2017-12-05 10:29 ./var/run -> /run" 197 st, err := squashfs.FromRaw([]byte(line)) 198 c.Assert(err, IsNil) 199 c.Check(st.Mode(), Equals, os.FileMode(0777|os.ModeSymlink)) 200 c.Check(st.Path(), Equals, "/var/run") 201 c.Check(st.User(), Equals, "root") 202 c.Check(st.Group(), Equals, "root") 203 c.Check(st.Size(), Equals, int64(4)) 204 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 5, 10, 29, 0, 0, time.UTC)) 205 } 206 207 func (s *SquashfsTestSuite) TestStatNamedPipe(c *C) { 208 line := "prw-rw-r-- john/john 0 2018-01-09 10:24 ./afifo" 209 st, err := squashfs.FromRaw([]byte(line)) 210 c.Assert(err, IsNil) 211 c.Check(st.Mode(), Equals, os.FileMode(0664|os.ModeNamedPipe)) 212 c.Check(st.Path(), Equals, "/afifo") 213 c.Check(st.User(), Equals, "john") 214 c.Check(st.Group(), Equals, "john") 215 c.Check(st.Size(), Equals, int64(0)) 216 c.Check(st.ModTime(), Equals, time.Date(2018, 1, 9, 10, 24, 0, 0, time.UTC)) 217 } 218 219 func (s *SquashfsTestSuite) TestStatSocket(c *C) { 220 line := "srwxrwxr-x john/john 0 2018-01-09 10:24 ./asock" 221 st, err := squashfs.FromRaw([]byte(line)) 222 c.Assert(err, IsNil) 223 c.Check(st.Mode(), Equals, os.FileMode(0775|os.ModeSocket)) 224 c.Check(st.Path(), Equals, "/asock") 225 c.Check(st.User(), Equals, "john") 226 c.Check(st.Group(), Equals, "john") 227 c.Check(st.Size(), Equals, int64(0)) 228 c.Check(st.ModTime(), Equals, time.Date(2018, 1, 9, 10, 24, 0, 0, time.UTC)) 229 } 230 231 func (s *SquashfsTestSuite) TestStatLength(c *C) { 232 ns := []int64{ 233 0, 234 1024, 235 math.MaxInt32, 236 math.MaxInt64, 237 } 238 for _, n := range ns { 239 raw := []byte(fmt.Sprintf("-rw-r--r-- user/group %16d 2017-12-08 11:19 ./some filename", n)) 240 241 com := Commentf("%q", raw) 242 st, err := squashfs.FromRaw(raw) 243 c.Assert(err, IsNil, com) 244 c.Check(st.Mode(), Equals, os.FileMode(0644), com) 245 c.Check(st.Path(), Equals, "/some filename", com) 246 c.Check(st.User(), Equals, "user", com) 247 c.Check(st.Group(), Equals, "group", com) 248 c.Check(st.Size(), Equals, n, com) 249 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 8, 11, 19, 0, 0, time.UTC), com) 250 } 251 } 252 253 func (s *SquashfsTestSuite) TestStatModeBits(c *C) { 254 for i := os.FileMode(0); i <= 0777; i++ { 255 raw := []byte(fmt.Sprintf("%s user/group 53595 2017-12-08 11:19 ./yadda", i)) 256 257 com := Commentf("%q vs %o", raw, i) 258 st, err := squashfs.FromRaw(raw) 259 c.Assert(err, IsNil, com) 260 c.Check(st.Mode(), Equals, i, com) 261 c.Check(st.Path(), Equals, "/yadda", com) 262 c.Check(st.User(), Equals, "user", com) 263 c.Check(st.Group(), Equals, "group", com) 264 c.Check(st.Size(), Equals, int64(53595), com) 265 c.Check(st.ModTime(), Equals, time.Date(2017, 12, 8, 11, 19, 0, 0, time.UTC), com) 266 267 jRaw := make([]byte, len(raw)) 268 269 for j := 01000 + i; j <= 07777; j += 01000 { 270 // this silliness only needed because os.FileMode's String() throws away sticky/setuid/setgid bits 271 copy(jRaw, raw) 272 if j&01000 != 0 { 273 if j&0001 != 0 { 274 jRaw[9] = 't' 275 } else { 276 jRaw[9] = 'T' 277 } 278 } 279 if j&02000 != 0 { 280 if j&0010 != 0 { 281 jRaw[6] = 's' 282 } else { 283 jRaw[6] = 'S' 284 } 285 } 286 if j&04000 != 0 { 287 if j&0100 != 0 { 288 jRaw[3] = 's' 289 } else { 290 jRaw[3] = 'S' 291 } 292 } 293 com := Commentf("%q vs %o", jRaw, j) 294 st, err := squashfs.FromRaw(jRaw) 295 c.Assert(err, IsNil, com) 296 c.Check(st.Mode(), Equals, j, com) 297 } 298 } 299 }