C++ 创建一个安全的转义路径基/文件名,检查是否安全

C++ 创建一个安全的转义路径基/文件名,检查是否安全,c++,windows,linux,boost,filesystems,C++,Windows,Linux,Boost,Filesystems,我想知道是否有一种通用的方法来生成可移植的文件系统安全文件名。也就是说,我有一个用户输入的字符串,并希望生成一个名称与他们选择的名称非常相似的文件。结果名称不得包含任何路径引用或其他特殊文件系统特殊名称或标记 目前,我只是用其他字符或空字符串替换一堆已知的坏字符。例如,给定名称ABC/DEF*:A Company?我将生成字符串ABC-DEF-A Company。我对替换字符的选择完全是任意的,因为我不知道通用转义符号 因此,我的相关问题是: 是否有一种方法(可能在boost文件系统中)可以告诉

我想知道是否有一种通用的方法来生成可移植的文件系统安全文件名。也就是说,我有一个用户输入的字符串,并希望生成一个名称与他们选择的名称非常相似的文件。结果名称不得包含任何路径引用或其他特殊文件系统特殊名称或标记

目前,我只是用其他字符或空字符串替换一堆已知的坏字符。例如,给定名称
ABC/DEF*:A Company?
我将生成字符串
ABC-DEF-A Company
。我对替换字符的选择完全是任意的,因为我不知道通用转义符号

因此,我的相关问题是:

  • 是否有一种方法(可能在boost文件系统中)可以告诉我该名称是否严格引用了一个没有路径的文件
  • 是否有一个函数告诉我该名称作为文件使用是否“安全”(对于某些文件系统,这可能是1的附加检查)
  • 是否有函数将字符串转换为合理的安全名称

  • 附加注释

    对于#1,我想将boost path::filename()与原始对象进行比较,如果它们相同,那么我就有一个文件。不过,这仍然允许使用诸如“..”和“.”之类的内容,但如果有一个很好的解决方案来解决#2,这可能没什么问题

    理论上,我必须提供一个文件所在的目录,因为不同的文件系统可能有不同的要求。但操作系统的全局解决方案也可以

    我已经有了一个函数,它只是替换了一些常见的不安全字符


    通用文件对话框不能用于进行过滤,因为界面可能并不总是允许使用它们,而且在某些情况下,用户并不直接知道与文件的关系(但是高级用户会知道)。

    可移植性如何?许多系统对长度有限制,有些 也许现在还可以。名字之间的伪装是一个问题吗?一些 系统区分案例,其他系统则不区分。最后的
    .xxx
    怎么样? 对于某些系统来说,它是重要的,对于其他系统来说,它只是文本

    忽略长度,最安全的方法是采取相反的方法: 创建一组已知的安全字符,并转换 那是一个特定的角色。ASCII字母数字和
    '
    似乎 非常安全,您(今天)可能对
    '-'
    没问题,但我怀疑 这个列表更进一步。这取决于你用这些做什么 名称,您可能希望将它们强制为单个大小写,大写或小写 较低。

    根据,唯一的可移植文件名是那些仅包含
    A–Za–z0–9.\u-
    且最大长度为14个字符的文件名

    这就是说,一种更实际的方法是假设现代文件系统可以处理更长的文件名,并简单地用
    \uuu
    替换所有未明确标记为“安全”的字符。有时,这些字符不是替换为
    ,而是采用十六进制编码,如URL:
    sample%20file.txt
    。例如,应用程序使用这个


    至于实现,它就像
    s/[^A-Za-z0-9.-]/\uz/

    一样简单,我希望“方法”是可移植的,而不是结果名称。也就是说,允许的名称集可能因操作系统而异,甚至因文件系统而异。POSIX可移植名称的限制太大了。这些名称可能很长,并且包含unicode字符——我知道我的大多数目标平台都支持这一点。只替换字符的问题是,它不排除文件系统可能具有的任何特殊名称。@edA-qa-mort-ora-y:允许“fs允许的任何内容”的问题是1)Unix文件系统实际上允许除
    /
    \0
    之外的所有内容,2)当用户试图将生成的文件复制到另一个文件系统时,会收到恼人的错误消息,例如,复制到U盘上(这里有自己的经验:()。因此,最好在许多文件系统中使用文件名附近的保险箱。