Enhance JWT signing key validation and improve FfmpegBumperRenderer label handling: add checks for signing key length and placeholder values in DependencyInjection, and refactor label processing to read from files in FfmpegBumperRenderer. Update MediaProcessingBackgroundService to ensure slot release on claim failure.
build / backend (push) Successful in 2m24s
build / frontend (push) Successful in 54s
tests / backend-tests (push) Successful in 2m40s

This commit is contained in:
Leonid Pershin
2026-07-25 21:07:38 +03:00
parent 5bc6e144d2
commit 53e0eeb776
4 changed files with 158 additions and 10 deletions
@@ -44,9 +44,40 @@ public sealed class FfmpegBumperRenderer(
await File.WriteAllTextAsync(nowFile, line1, new UTF8Encoding(false), cancellationToken);
await File.WriteAllTextAsync(nextFile, line2, new UTF8Encoding(false), cancellationToken);
// Подписи «Сейчас/Далее» тоже пользователь-редактируемы (валидатор ограничивает только длину),
// поэтому их так же читаем через textfile=, а не подставляем в text= инлайн: иначе запятая/`;`/`[`/`]`
// в подписи ломают (или инъектируют звенья в) цепочку -filter_complex. Нужны лишь в режиме
// «Сейчас/Далее» (не FreeText), где рисуются подписи.
var nowLabelFile = Path.Combine(assetDir, "nowlabel.txt");
var nextLabelFile = Path.Combine(assetDir, "nextlabel.txt");
if (!spec.FreeText)
{
await File.WriteAllTextAsync(
nowLabelFile,
spec.NowLabel,
new UTF8Encoding(false),
cancellationToken
);
await File.WriteAllTextAsync(
nextLabelFile,
spec.NextLabel,
new UTF8Encoding(false),
cancellationToken
);
}
try
{
var args = BuildArgs(assetDir, seg, target, nowFile, nextFile, spec);
var args = BuildArgs(
assetDir,
seg,
target,
nowFile,
nextFile,
nowLabelFile,
nextLabelFile,
spec
);
var result = await ProcessRunner.RunAsync(
_media.FfmpegPath,
args,
@@ -83,6 +114,8 @@ public sealed class FfmpegBumperRenderer(
{
TryDelete(nowFile);
TryDelete(nextFile);
TryDelete(nowLabelFile);
TryDelete(nextLabelFile);
}
}
@@ -92,6 +125,8 @@ public sealed class FfmpegBumperRenderer(
int target,
string nowFile,
string nextFile,
string nowLabelFile,
string nextLabelFile,
BumperRenderSpec spec
)
{
@@ -186,7 +221,7 @@ public sealed class FfmpegBumperRenderer(
vchain
.Append(',')
.Append(
DrawLabel(font, spec.NowLabel, spec.AccentColor, labelSize, nowLabelY, 0.2)
DrawLabel(font, nowLabelFile, spec.AccentColor, labelSize, nowLabelY, 0.2)
);
vchain
.Append(',')
@@ -194,7 +229,7 @@ public sealed class FfmpegBumperRenderer(
vchain
.Append(',')
.Append(
DrawLabel(font, spec.NextLabel, spec.AccentColor, labelSize, nextLabelY, 1.0)
DrawLabel(font, nextLabelFile, spec.AccentColor, labelSize, nextLabelY, 1.0)
);
vchain
.Append(',')
@@ -284,13 +319,15 @@ public sealed class FfmpegBumperRenderer(
private static string DrawLabel(
string font,
string text,
string textFile,
string color,
int size,
int y,
double fadeStart
) =>
$"drawtext=fontfile={font}:text={EscapeText(text)}:expansion=none"
// Подпись читается из файла (textfile=) с expansion=none — произвольные символы подписи
// не могут сломать/инъектировать цепочку filter_complex (см. запись файлов в RenderAsync).
$"drawtext=fontfile={font}:textfile={EscapePath(textFile)}:expansion=none"
+ $":fontcolor={color}:fontsize={size}:x=(w-text_w)/2:y={y}"
+ ":shadowcolor=black@0.6:shadowx=1:shadowy=1"
+ $":alpha='{FadeExpr(fadeStart)}'";
@@ -302,10 +339,6 @@ public sealed class FfmpegBumperRenderer(
/// двоеточие экранируется). На Linux (контейнере) — фактически no-op.</summary>
private static string EscapePath(string path) => path.Replace('\\', '/').Replace(":", "\\:");
/// <summary>Экранирование литерального текста подписи внутри значения опции drawtext.</summary>
private static string EscapeText(string text) =>
text.Replace("\\", "\\\\").Replace(":", "\\:").Replace("'", "\\'");
private static string Fmt(double value) =>
value.ToString("0.###", CultureInfo.InvariantCulture);