comparison cutils/util/walk.py @ 281:16507317e834

treesum: FIX: Also do not allow CR and/or LF and/or backslashes in strictly FS encoded names
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 23 Feb 2025 12:37:34 +0100
parents f3e0b479928c
children d507ae4943d5
comparison
equal deleted inserted replaced
280:f3e0b479928c 281:16507317e834
79 79
80 @property 80 @property
81 def fsname(self): 81 def fsname(self):
82 """The name as bytes for the filesystem. 82 """The name as bytes for the filesystem.
83 83
84 Also do not allow CR of LF in the name.
85
84 :rtype: bytes or None 86 :rtype: bytes or None
85 87
86 """ 88 """
87 if PY2: 89 if PY2:
88 if isinstance(self._name, bytes): 90 if isinstance(self._name, bytes):
89 return self._name 91 s = self._name
90 try: 92 try:
91 return self._name.encode(_FSENCODING, "strict") 93 s = self._name.encode(_FSENCODING, "strict")
92 except UnicodeError: 94 except UnicodeError:
93 return None 95 return None
94 else: 96 else:
95 return os.fsencode(self._name) 97 s = os.fsencode(self._name)
98 if (b'\n' in s) or (b'\r' in s) or (b'\\' in s):
99 return None
100 return s
96 101
97 @property 102 @property
98 def alt_fsname(self): 103 def alt_fsname(self):
99 """Alternative and "escaped" filesystem name -- always bytes. 104 """Alternative and "escaped" filesystem name -- always bytes.
100 105
107 112
108 @property 113 @property
109 def fspath(self): 114 def fspath(self):
110 """Always bytes. 115 """Always bytes.
111 116
117 Also do not allow CR of LF in the path.
118
112 :rtype: bytes or None 119 :rtype: bytes or None
113 120
114 """ 121 """
115 if PY2: 122 if PY2:
116 if isinstance(self._path, bytes): 123 if isinstance(self._path, bytes):
117 return self._path 124 p = self._path
118 try: 125 try:
119 return self._path.encode(_FSENCODING, "strict") 126 p = self._path.encode(_FSENCODING, "strict")
120 except UnicodeError: 127 except UnicodeError:
121 return None 128 return None
122 else: 129 else:
123 return os.fsencode(self._path) 130 p = os.fsencode(self._path)
131 if (b'\n' in p) or (b'\r' in p) or (b'\\' in p):
132 return None
133 return p
124 134
125 @property 135 @property
126 def alt_fspath(self): 136 def alt_fspath(self):
127 """Alternative and "escaped" filesystem path -- always bytes. 137 """Alternative and "escaped" filesystem path -- always bytes.
128 138
133 143
134 @staticmethod 144 @staticmethod
135 def alt_fs(what): 145 def alt_fs(what):
136 if PY2: 146 if PY2:
137 if isinstance(what, bytes): 147 if isinstance(what, bytes):
138 return what 148 s = what
139 return what.encode(_FSENCODING, "backslashreplace") 149 else:
140 else: 150 #
141 return os.fsencode(what) 151 # Prevent double encoding ...
152 # ... and hope that the current FS encoding is compatible
153 # with it
154 #
155 s = what.replace(u'\\', u"\\x5c")
156 s = s.encode(_FSENCODING, "backslashreplace")
157 return s.replace(b'\n', b"\\x0a").replace(b'\r', b"\\x0d")
158 else:
159 s = os.fsencode(what)
160 return (s.replace(b'\\', b"\\x5c")
161 .replace(b'\n', b"\\x0a")
162 .replace(b'\r', b"\\x0d"))
142 163
143 @property 164 @property
144 def uname(self): 165 def uname(self):
145 """Always "real", strictly encoded Unicode or `None` if this is not 166 """Always "real", strictly encoded Unicode or `None` if this is not
146 possible. 167 possible.