Кодировка UTF-7 больше не используется широко в приложениях, и многие спецификации теперь запрещают использовать ее при обмене. Кроме того, иногда она служит вектором атаки в приложениях, которые не предусматривают получение данных в этой кодировке. Корпорация Майкрософт предостерегает от использования класса System.Text.UTF7Encoding, так как он не выполняет обнаружение ошибок.
Ранее экземпляр кодировки UTF-7 можно было создать с помощью API Encoding.GetEncoding. Например:
C#
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 не помечен как устаревший.
C#
// 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.
C#
// Throws ArgumentException, same as calling Encoding.GetEncoding("unknown").
Encoding enc = Encoding.GetEncoding("utf-7");
Наконец, метод Encoding.GetEncodings() не включает кодировку UTF-7 в возвращаемый массив EncodingInfo. Кодировка исключается, так как нельзя создать ее экземпляр.
C#
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") с именем кодировки, полученным от ненадежного источника. Например, веб-клиент или сервер может взять фрагмент charset из заголовка Content-Type и передать его значение непосредственно в Encoding.GetEncoding без проверки. Это позволяет вредоносной конечной точке указать Content-Type: ...; charset=utf-7, что может привести к сбою принимающего приложения.
Кроме того, отключение путей к коду в UTF-7 позволяет оптимизировать работу компиляторов, например используемых в Blazor. При этом такие пути к коду полностью удаляются из полученного приложения. В результате скомпилированные приложения работают более эффективно и занимают меньше места на диске.
Представленные версии
5,0
Рекомендуемое действие
В большинстве случаев никаких дополнительных действий от вас не требуется. Но если в приложении ранее были активированы пути к коду в UTF-7, воспользуйтесь приведенными ниже рекомендациями.
Если приложение вызывает метод Encoding.GetEncoding с неизвестными именами кодировки, полученными от ненадежного источника:
Вместо этого рекомендуется выполнять проверку имен кодировки по списку разрешенных. Этот настраиваемый список разрешенных кодировок должен по меньшей мере содержать стандартную отраслевую кодировку UTF-8. В зависимости от потребностей ваших клиентов и нормативных требований вам может также понадобится разрешить кодировки для определенных регионов, например GB18030.
Если вы не создадите список разрешенных кодировок, метод Encoding.GetEncoding будет возвращать все значения Encoding, которые встроены в систему или зарегистрированы с помощью настраиваемого класса EncodingProvider. Проверьте требования службы, чтобы убедиться, что такое поведение допустимо. По умолчанию кодировка UTF-7 остается отключенной, если только приложение не включит параметр совместимости, упомянутый далее в этой статье.
Перейдите на использование Encoding.UTF8 или UTF8Encoding. Кодировка UTF-8 является отраслевым стандартом, поддерживающим различные языки, операционные системы и среды выполнения. Использование UTF-8 упрощает дальнейшее обслуживание кода и улучшает его совместимость с остальной экосистемой.
Вместо этого рекомендуется выполнять проверку по кодовой странице UTF-7 — 65000. Сравнение с кодовой страницей позволяет избежать предупреждения, а также обрабатывать некоторые пограничные случаи, например, когда вызывается new UTF7Encoding() или создается подкласс типа.
C#
voidDoSomething(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.
}
}
При подавлении SYSLIB0001 отключаются только предупреждения о том, что Encoding.UTF7 и UTF7Encoding являются устаревшими. Это не отключает другие предупреждения и не меняет поведение API-интерфейсов, например Encoding.GetEncoding.
Если требуется поддержка Encoding.GetEncoding("utf-7", ...):
Вы можете повторно включить поддержку этой кодировки с помощью переключателя совместимости. Этот переключатель совместимости можно указать в файле .csproj приложения или файле конфигурации среды выполнения, как показано в следующих примерах.
В файле .csproj приложения:
XML
<ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net5.0</TargetFramework><!-- Re-enable support for UTF-7 --><EnableUnsafeUTF7Encoding>true</EnableUnsafeUTF7Encoding></PropertyGroup></Project>
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Присоединитесь к серии встреч для создания масштабируемых решений искусственного интеллекта на основе реальных вариантов использования с другими разработчиками и экспертами.