xfs: validate unicode filesystem labels
[xfstests-dev.git] / tests / xfs / 504
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright (c) 2019, Oracle and/or its affiliates.  All Rights Reserved.
4 #
5 # FS QA Test No. 504
6 #
7 # Create a directory with multiple filenames that all appear the same
8 # (in unicode, anyway) but point to different inodes.  In theory all
9 # Linux filesystems should allow this (filenames are a sequence of
10 # arbitrary bytes) even if the user implications are horrifying.
11 #
12 seq=`basename "$0"`
13 seqres="$RESULT_DIR/$seq"
14 echo "QA output created by $seq"
15
16 here=`pwd`
17 tmp=/tmp/$$
18 status=1    # failure is the default!
19 trap "_cleanup; exit \$status" 0 1 2 3 15
20
21 _cleanup()
22 {
23         cd /
24         rm -f $tmp.*
25 }
26
27 # get standard environment, filters and checks
28 . ./common/rc
29 . ./common/filter
30
31 _supported_os Linux
32 _supported_fs xfs
33 _require_scratch_nocheck
34 _require_xfs_io_command 'label'
35
36 echo "Silence is golden."
37
38 want_scrub=
39 _check_xfs_scrub_does_unicode "$SCRATCH_MNT" "$SCRATCH_DEV" && want_scrub=yes
40
41 filter_scrub() {
42         grep 'Unicode' | sed -e 's/^.*Duplicate/Duplicate/g'
43 }
44
45 maybe_scrub() {
46         test "$want_scrub" = "yes" || return
47
48         output="$(LC_ALL="C.UTF-8" ${XFS_SCRUB_PROG} -v -n "${SCRATCH_MNT}" 2>&1)"
49         echo "xfs_scrub output:" >> $seqres.full
50         echo "$output" >> $seqres.full
51         echo "$output" >> $tmp.scrub
52 }
53
54 testlabel() {
55         local label="$(echo -e "$1")"
56         local expected_label="label = \"$label\""
57
58         echo "Formatting label '$1'." >> $seqres.full
59         # First, let's see if we can recover the label when we set it
60         # with mkfs.
61         _scratch_mkfs -L "$label" >> $seqres.full 2>&1
62         _scratch_mount >> $seqres.full 2>&1
63         blkid -s LABEL $SCRATCH_DEV | _filter_scratch | sed -e "s/ $//g" >> $seqres.full
64         blkid -d -s LABEL $SCRATCH_DEV | _filter_scratch | sed -e "s/ $//g" >> $seqres.full
65
66         # Did it actually stick?
67         local actual_label="$($XFS_IO_PROG -c label $SCRATCH_MNT)"
68         echo "$actual_label" >> $seqres.full
69
70         if [ "${actual_label}" != "${expected_label}" ]; then
71                 echo "Saw '${expected_label}', expected '${actual_label}'."
72         fi
73         maybe_scrub
74         _scratch_unmount
75
76         # Now let's try setting the label online to see what happens.
77         echo "Setting label '$1'." >> $seqres.full
78         _scratch_mkfs >> $seqres.full 2>&1
79         _scratch_mount >> $seqres.full 2>&1
80         $XFS_IO_PROG -c "label -s $label" $SCRATCH_MNT >> $seqres.full
81         blkid -s LABEL $SCRATCH_DEV | _filter_scratch | sed -e "s/ $//g" >> $seqres.full
82         blkid -d -s LABEL $SCRATCH_DEV | _filter_scratch | sed -e "s/ $//g" >> $seqres.full
83         _scratch_cycle_mount
84
85         # Did it actually stick?
86         local actual_label="$($XFS_IO_PROG -c label $SCRATCH_MNT)"
87         echo "$actual_label" >> $seqres.full
88
89         if [ "${actual_label}" != "${expected_label}" ]; then
90                 echo "Saw '${expected_label}'; expected '${actual_label}'."
91         fi
92         maybe_scrub
93         _scratch_unmount
94 }
95
96 # Simple test
97 testlabel "simple"
98
99 # Two different renderings of the same label
100 testlabel "caf\xc3\xa9.fs"
101 testlabel "cafe\xcc\x81.fs"
102
103 # Arabic code point can expand into a muuuch longer series
104 testlabel "xfs_\xef\xb7\xba.fs"
105
106 # Fake slash?
107 testlabel "urk\xc0\xafmoo"
108
109 # Emoji: octopus butterfly owl giraffe
110 testlabel "\xf0\x9f\xa6\x91\xf0\x9f\xa6\x8b\xf0\x9f\xa6\x89"
111
112 # unicode rtl widgets too...
113 testlabel "mo\xe2\x80\xaegnp.txt"
114 testlabel "motxt.png"
115
116 # mixed-script confusables
117 testlabel "mixed_t\xce\xbfp"
118 testlabel "mixed_top"
119
120 # single-script spoofing
121 testlabel "a\xe2\x80\x90b.fs"
122 testlabel "a-b.fs"
123
124 testlabel "dz_dze.fs"
125 testlabel "dz_\xca\xa3e.fs"
126
127 # symbols
128 testlabel "_Rs.fs"
129 testlabel "_\xe2\x82\xa8.fs"
130
131 # zero width joiners
132 testlabel "moocow.fs"
133 testlabel "moo\xe2\x80\x8dcow.fs"
134
135 # combining marks
136 testlabel "\xe1\x80\x9c\xe1\x80\xad\xe1\x80\xaf.fs"
137 testlabel "\xe1\x80\x9c\xe1\x80\xaf\xe1\x80\xad.fs"
138
139 # fake dotdot entry
140 testlabel ".\xe2\x80\x8d"
141 testlabel "..\xe2\x80\x8d"
142
143 # Did scrub choke on anything?
144 if [ "$want_scrub" = "yes" ]; then
145         grep -q "^Warning.*gnp.txt.*suspicious text direction" $tmp.scrub || \
146                 echo "No complaints about direction overrides?"
147         grep -q "^Warning.*control characters" $tmp.scrub || \
148                 echo "No complaints about control characters?"
149 fi
150
151 # success, all done
152 status=0
153 exit