This commit is contained in:
2025-05-05 14:45:58 +03:00
parent 0fb4058186
commit 90dd893f3e
43 changed files with 2501 additions and 63 deletions

View 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;
}
}