Python如何解决secure_filename对中文不支持问题
时间:2022-01-13 09:41:55|栏目:Python代码|点击: 次
前言:最近使用到了secure_filename,然后悲剧的发现中文居然不展示出来,于是我慢慢的debug,终于找到问题了。
一、最近使用secure_filename发现的问题
文件名是中文版的,悲剧的是中文以及其他特殊字符会被省略。

二、后面找到了原因
原来secure_filename()函数只返回ASCII字符,非ASCII字符会被过滤掉。
三、解决方案
找到secure_filename(filename)函数,修改它的源代码。
secure_filename(filename)函数源代码:
def secure_filename(filename: str) -> str:
r"""Pass it a filename and it will return a secure version of it. This
filename can then safely be stored on a regular file system and passed
to :func:`os.path.join`. The filename returned is an ASCII only string
for maximum portability.
On windows systems the function also makes sure that the file is not
named after one of the special device files.
>>> secure_filename("My cool movie.mov")
'My_cool_movie.mov'
>>> secure_filename("../../../etc/passwd")
'etc_passwd'
>>> secure_filename('i contain cool \xfcml\xe4uts.txt')
'i_contain_cool_umlauts.txt'
The function might return an empty filename. It's your responsibility
to ensure that the filename is unique and that you abort or
generate a random filename if the function returned an empty one.
.. versionadded:: 0.5
:param filename: the filename to secure
"""
filename = unicodedata.normalize("NFKD", filename)
filename = filename.encode("ascii", "ignore").decode("ascii")
for sep in os.path.sep, os.path.altsep:
if sep:
filename = filename.replace(sep, " ")
filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip(
"._"
)
# on nt a couple of special files are present in each folder. We
# have to ensure that the target file is not such a filename. In
# this case we prepend an underline
if (
os.name == "nt"
and filename
and filename.split(".")[0].upper() in _windows_device_files
):
filename = f"_{filename}"
return filename
secure_filename(filename)函数修改后的代码:
def secure_filename(filename: str) -> str:
r"""Pass it a filename and it will return a secure version of it. This
filename can then safely be stored on a regular file system and passed
to :func:`os.path.join`. The filename returned is an ASCII only string
for maximum portability.
On windows systems the function also makes sure that the file is not
named after one of the special device files.
>>> secure_filename("My cool movie.mov")
'My_cool_movie.mov'
>>> secure_filename("../../../etc/passwd")
'etc_passwd'
>>> secure_filename('i contain cool \xfcml\xe4uts.txt')
'i_contain_cool_umlauts.txt'
The function might return an empty filename. It's your responsibility
to ensure that the filename is unique and that you abort or
generate a random filename if the function returned an empty one.
.. versionadded:: 0.5
:param filename: the filename to secure
"""
filename = unicodedata.normalize("NFKD", filename)
filename = filename.encode("utf8", "ignore").decode("utf8") # 编码格式改变
for sep in os.path.sep, os.path.altsep:
if sep:
filename = filename.replace(sep, " ")
_filename_ascii_add_strip_re = re.compile(r'[^A-Za-z0-9_\u4E00-\u9FBF\u3040-\u30FF\u31F0-\u31FF.-]')
filename = str(_filename_ascii_add_strip_re.sub('', '_'.join(filename.split()))).strip('._') # 添加新规则
# on nt a couple of special files are present in each folder. We
# have to ensure that the target file is not such a filename. In
# this case we prepend an underline
if (
os.name == "nt"
and filename
and filename.split(".")[0].upper() in _windows_device_files
):
filename = f"_{filename}"
return filename
四、效果展示
我们很清楚的看到了效果,目前是支持中文的

上一篇:在python中list作函数形参,防止被实参修改的实现方法
栏 目:Python代码
本文标题:Python如何解决secure_filename对中文不支持问题
本文地址:http://www.codeinn.net/misctech/190023.html






