Browse code

Merge pull request #38977 from thaJeztah/fix_parseinfofile_parsing

fix parseInfoFile does not handle spaces in filenames

Kirill Kolyshkin authored on 2019/04/03 01:29:15
Showing 2 changed files
... ...
@@ -7,16 +7,21 @@ import (
7 7
 	"os"
8 8
 	"strconv"
9 9
 	"strings"
10
+
11
+	"github.com/pkg/errors"
10 12
 )
11 13
 
12 14
 func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
13 15
 	s := bufio.NewScanner(r)
14 16
 	out := []*Info{}
17
+	var err error
15 18
 	for s.Scan() {
16
-		if err := s.Err(); err != nil {
19
+		if err = s.Err(); err != nil {
17 20
 			return nil, err
18 21
 		}
19 22
 		/*
23
+		   See http://man7.org/linux/man-pages/man5/proc.5.html
24
+
20 25
 		   36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
21 26
 		   (1)(2)(3)   (4)   (5)      (6)      (7)   (8) (9)   (10)         (11)
22 27
 
... ...
@@ -52,8 +57,15 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
52 52
 		p.Major, _ = strconv.Atoi(mm[0])
53 53
 		p.Minor, _ = strconv.Atoi(mm[1])
54 54
 
55
-		p.Root = fields[3]
56
-		p.Mountpoint = fields[4]
55
+		p.Root, err = strconv.Unquote(`"` + fields[3] + `"`)
56
+		if err != nil {
57
+			return nil, errors.Wrapf(err, "Parsing '%s' failed: unable to unquote root field", fields[3])
58
+		}
59
+
60
+		p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`)
61
+		if err != nil {
62
+			return nil, errors.Wrapf(err, "Parsing '%s' failed: unable to unquote mount point field", fields[4])
63
+		}
57 64
 		p.Opts = fields[5]
58 65
 
59 66
 		var skip, stop bool
... ...
@@ -422,6 +422,9 @@ const (
422 422
 286 15 0:3631 / /var/lib/docker/aufs/mnt/ff28c27d5f894363993622de26d5dd352dba072f219e4691d6498c19bbbc15a9 rw,relatime - aufs none rw,si=9b4a7642265b339c
423 423
 289 15 0:3634 / /var/lib/docker/aufs/mnt/aa128fe0e64fdede333aa48fd9de39530c91a9244a0f0649a3c411c61e372daa rw,relatime - aufs none rw,si=9b4a764012ada39c
424 424
 99 15 8:33 / /media/REMOVE\040ME rw,nosuid,nodev,relatime - fuseblk /dev/sdc1 rw,user_id=0,group_id=0,allow_other,blksize=4096`
425
+
426
+	mountInfoWithSpaces = `486 28 252:1 / /mnt/foo\040bar rw,relatime shared:243 - ext4 /dev/vda1 rw,data=ordered
427
+31 21 0:23 / /DATA/foo_bla_bla rw,relatime - cifs //foo/BLA\040BLA\040BLA/ rw,sec=ntlm,cache=loose,unc=\\foo\BLA BLA BLA,username=my_login,domain=mydomain.com,uid=12345678,forceuid,gid=12345678,forcegid,addr=10.1.30.10,file_mode=0755,dir_mode=0755,nounix,rsize=61440,wsize=65536,actimeo=1`
425 428
 )
426 429
 
427 430
 func TestParseFedoraMountinfo(t *testing.T) {
... ...
@@ -477,6 +480,51 @@ func TestParseFedoraMountinfoFields(t *testing.T) {
477 477
 	}
478 478
 }
479 479
 
480
+func TestParseMountinfoWithSpaces(t *testing.T) {
481
+	r := bytes.NewBuffer([]byte(mountInfoWithSpaces))
482
+	infos, err := parseInfoFile(r, nil)
483
+	if err != nil {
484
+		t.Fatal(err)
485
+	}
486
+	expected := []Info{
487
+		{
488
+			ID:         486,
489
+			Parent:     28,
490
+			Major:      252,
491
+			Minor:      1,
492
+			Root:       "/",
493
+			Mountpoint: "/mnt/foo bar",
494
+			Opts:       "rw,relatime",
495
+			Optional:   "shared:243",
496
+			Fstype:     "ext4",
497
+			Source:     "/dev/vda1",
498
+			VfsOpts:    "rw,data=ordered",
499
+		},
500
+		{
501
+			ID:         31,
502
+			Parent:     21,
503
+			Major:      0,
504
+			Minor:      23,
505
+			Root:       "/",
506
+			Mountpoint: "/DATA/foo_bla_bla",
507
+			Opts:       "rw,relatime",
508
+			Optional:   "",
509
+			Fstype:     "cifs",
510
+			Source:     `//foo/BLA\040BLA\040BLA/`,
511
+			VfsOpts:    `rw,sec=ntlm,cache=loose,unc=\\foo\BLA`,
512
+		},
513
+	}
514
+
515
+	if len(infos) != len(expected) {
516
+		t.Fatalf("expected %d entries, got %d", len(expected), len(infos))
517
+	}
518
+	for i, mi := range expected {
519
+		if *infos[i] != mi {
520
+			t.Fatalf("expected %#v, got %#v", mi, infos[i])
521
+		}
522
+	}
523
+}
524
+
480 525
 func TestParseMountinfoFilters(t *testing.T) {
481 526
 	r := bytes.NewReader([]byte(fedoraMountinfo))
482 527