UTF-7 代码路径已过时
UTF-7 编码在应用程序中不再广泛使用,并且许多规范现在在交换中禁止其使用。 它偶尔还会在不期望遇到 UTF-7 编码数据的应用程序中用作攻击途径。 Microsoft 警告不要使用 System.Text.UTF7Encoding,因为它不提供错误检测。
因此,Encoding.UTF7 属性和 UTF7Encoding 构造函数现已过时。 此外,Encoding.GetEncoding 和 Encoding.GetEncodings 不再允许你指定 UTF-7
。
更改描述
以前,你可以使用 Encoding.GetEncoding API 创建 UTF-7 编码的实例。 例如:
Encoding enc1 = Encoding.GetEncoding("utf-7"); // By name.
Encoding enc2 = Encoding.GetEncoding(65000); // By code page.
此外,表示 UTF-7 编码的实例是由 Encoding.GetEncodings() 方法枚举的,该方法枚举在系统上注册的所有 Encoding 实例。
从 .NET 5 开始,Encoding.UTF7 属性和 UTF7Encoding 构造函数已过时并生成警告 SYSLIB0001
。 但是,若要减少在使用 UTF7Encoding 类时调用方收到的警告数,则 UTF7Encoding 类型本身不会标记为已过时。
// The next line generates warning SYSLIB0001.
UTF7Encoding enc = new UTF7Encoding();
// The next line does not generate a warning.
byte[] bytes = enc.GetBytes("Hello world!");
此外,Encoding.GetEncoding 方法将编码名称 utf-7
和代码页 65000
视为 unknown
。 将编码视为 unknown
会使方法引发 ArgumentException。
// Throws ArgumentException, same as calling Encoding.GetEncoding("unknown").
Encoding enc = Encoding.GetEncoding("utf-7");
最后,Encoding.GetEncodings() 方法不会将 UTF-7 编码包括在它返回的 EncodingInfo 数组中。 已排除编码,因为无法对其进行实例化。
foreach (EncodingInfo encInfo in Encoding.GetEncodings())
{
// The next line would throw if GetEncodings included UTF-7.
Encoding enc = Encoding.GetEncoding(encInfo.Name);
}
更改原因
许多应用程序使用由不受信任的源提供的编码名称值调用 Encoding.GetEncoding("encoding-name")
。 例如,Web 客户端或服务器可能采用 Content-Type
标头的 charset
部分,并且不进行验证将值直接传递给 Encoding.GetEncoding
。 这可能会使恶意终结点指定 Content-Type: ...; charset=utf-7
,而这可能会导致接收应用程序出现异常行为。
此外,禁用 UTF-7 代码路径可以优化编译器(如 Blazor 使用的编译器),以便从生成的应用程序中完全删除这些代码路径。 因此,已编译的应用程序会更有效地运行,且占用更少的磁盘空间。
引入的版本
5.0
建议操作
在大多数情况下,你不必执行任何操作。 但是,对于以前激活了与 UTF-7 相关的代码路径的应用,请考虑下面的指南。
如果你的应用使用不受信任的源提供的未知编码名称调用 Encoding.GetEncoding:
请改为将编码名称与可配置的允许列表进行比较。 可配置的允许列表至少应包含行业标准的“utf-8”。 根据你的客户端和法规要求,你可能还需要允许特定于区域的编码,如“GB18030”。
如果未执行允许列表,Encoding.GetEncoding 将返回内置于系统中或通过自定义 EncodingProvider 注册的任何 Encoding。 审核你服务的要求以验证这是否是所需的行为。 除非你的应用程序重新启用本文后面所述的兼容性开关,否则默认情况下将继续禁用 UTF-7。
如果在你自己的协议或文件格式中使用的是 Encoding.UTF7 或 UTF7Encoding:
切换到使用 Encoding.UTF8 或 UTF8Encoding。 UTF-8 是一种行业标准,并且受到语言、操作系统和运行时的广泛支持。 使用 UTF-8 简化了代码的将来维护,并使其与生态系统的其余部分更具互操作性。
如果要将 Encoding 实例与 Encoding.UTF7 进行比较:
可转为考虑针对众所周知的 UTF-7 代码页(即
65000
)执行检查。 通过与代码页进行比较,可以避免出现警告,还可以处理一些边缘情况,例如,如果有人调用new UTF7Encoding()
或子类化类型。void DoSomething(Encoding enc) { // Don't perform the check this way. // It produces a warning and misses some edge cases. if (enc == Encoding.UTF7) { // Encoding is UTF-7. } // Instead, perform the check this way. if (enc != null && enc.CodePage == 65000) { // Encoding is UTF-7. } }
如果必须使用 Encoding.UTF7 或 UTF7Encoding:
可以在代码中或在项目的 .csproj 文件中禁止显示
SYSLIB0001
警告。#pragma warning disable SYSLIB0001 // Disable the warning. Encoding enc = Encoding.UTF7; #pragma warning restore SYSLIB0001 // Re-enable the warning.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <!-- NoWarn below suppresses SYSLIB0001 project-wide --> <NoWarn>$(NoWarn);SYSLIB0001</NoWarn> </PropertyGroup> </Project>
注意
禁止显示
SYSLIB0001
只会禁用 Encoding.UTF7 和 UTF7Encoding 过时警告。 不会禁用任何其他警告,也不会更改 API 的行为,如 Encoding.GetEncoding。如果必须支持
Encoding.GetEncoding("utf-7", ...)
:可以通过兼容性开关重新启用对此项的支持。 可以在应用程序的 .csproj 文件或运行时配置文件中指定此兼容性开关,如以下示例中所示。
在应用程序的 .csproj 文件中:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <!-- Re-enable support for UTF-7 --> <EnableUnsafeUTF7Encoding>true</EnableUnsafeUTF7Encoding> </PropertyGroup> </Project>
在应用程序的 runtimeconfig.template.json 文件中:
{ "configProperties": { "System.Text.Encoding.EnableUnsafeUTF7Encoding": true } }
提示
如果重新启用对 UTF-7 的支持,则应对调用 Encoding.GetEncoding 的代码执行安全检查。
受影响的 API
- System.Text.Encoding.UTF7
- UTF7Encoding()
- UTF7Encoding(Boolean)
- System.Text.Encoding.GetEncoding(Int32)
- System.Text.Encoding.GetEncoding(String)
- System.Text.Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback)
- System.Text.Encoding.GetEncoding(String, EncoderFallback, DecoderFallback)
- System.Text.Encoding.GetEncodings()