20250420
This commit is contained in:
108
anbs_cpfn/Extensions/FormFileExtension.cs
Normal file
108
anbs_cpfn/Extensions/FormFileExtension.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ImageMagick;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
using static System.Text.RegularExpressions.Regex;
|
||||
|
||||
namespace anbs_cp.ForNet.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Расширение интерфейса IFormFile
|
||||
/// </summary>
|
||||
public static class FormFileExtension
|
||||
{
|
||||
#region Константы
|
||||
/// <summary>
|
||||
/// Минимальный размер изображения (в байтах)
|
||||
/// </summary>
|
||||
private const int ImageMinimumBytes = 512;
|
||||
|
||||
/// <summary>
|
||||
/// Список поддерживаемых Mime-типов
|
||||
/// </summary>
|
||||
private static readonly List<string> AllowedMimeTypes =
|
||||
["image/jpg", "image/jpeg", "image/pjpeg", "image/gif", "image/x-png", "image/png"];
|
||||
|
||||
/// <summary>
|
||||
/// Список поддерживаемых расширений файлов
|
||||
/// </summary>
|
||||
private static readonly List<string> AllowedExtensions = [".jpg", ".png", ".gif", ".jpeg"];
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Получение содержимого файла
|
||||
/// </summary>
|
||||
/// <param name="file">Файл из формы</param>
|
||||
/// <returns>Содержимое файла</returns>
|
||||
public static byte[] GetFileContent (this IFormFile file)
|
||||
{
|
||||
// Читаем содержимое файла
|
||||
using BinaryReader binaryReader = new(file.OpenReadStream());
|
||||
|
||||
// Создаю контент изображения
|
||||
byte[] content = binaryReader.ReadBytes((int)file.Length);
|
||||
|
||||
// Вывожу результат
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка, является ли файл изображением
|
||||
/// </summary>
|
||||
/// <param name="postedFile">Файл из формы</param>
|
||||
/// <returns>Является ли файл изображением</returns>
|
||||
public static bool IsImage (this IFormFile postedFile)
|
||||
{
|
||||
// Проверяю Mime-тип
|
||||
if (!AllowedMimeTypes.Contains(postedFile.ContentType.ToLower()))
|
||||
return false;
|
||||
|
||||
// Проверяю расширение
|
||||
if (!AllowedExtensions.Contains(Path.GetExtension(postedFile.FileName).ToLower()))
|
||||
return false;
|
||||
|
||||
// Пытаюсь прочитать файл и проверить первые байты
|
||||
try
|
||||
{
|
||||
if (!postedFile.OpenReadStream().CanRead)
|
||||
return false;
|
||||
|
||||
// Проверяю, не меньше ли размер изображения установленного предела
|
||||
if (postedFile.Length < ImageMinimumBytes)
|
||||
return false;
|
||||
|
||||
byte[] buffer = new byte[ImageMinimumBytes];
|
||||
int _ = postedFile.OpenReadStream().Read(buffer, 0, ImageMinimumBytes);
|
||||
string content = System.Text.Encoding.UTF8.GetString(buffer);
|
||||
if (IsMatch(content,
|
||||
@"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
|
||||
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
|
||||
return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// - если .NET выдаст исключение, то можно предположить, что это недопустимое изображение
|
||||
return false;
|
||||
}
|
||||
|
||||
// Попробую создать экземпляр MagickImageCollection,
|
||||
try
|
||||
{
|
||||
using MagickImageCollection images = new(postedFile.OpenReadStream());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// - если .NET выдаст исключение, то можно предположить, что это недопустимое изображение
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
postedFile.OpenReadStream().Position = 0;
|
||||
}
|
||||
|
||||
// Возвращаю, что это изображение
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user