aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Lehnen <admin@nlehnen.de>2026-07-04 23:55:31 +0200
committerNils Lehnen <admin@nlehnen.de>2026-07-04 23:55:31 +0200
commitf8ffccae7fa65a27324667ccd156ca71fbfc89cd (patch)
treef3c82f7ee3338956476fdab79111aab18e44cc3d
parente2eaacd239e2ddf9ee93df7fcb63934d4fdfb2ac (diff)
Use InvariantCulture when parsing machine-generated dates
DateTime.TryParse without an IFormatProvider falls back to the current thread culture, so the same string can parse differently (or fail) depending on the server's locale. None of these call sites deal with user-entered text - they parse dates that come from filenames, an HTTP header, ffprobe metadata and values the app itself wrote to the auth database - so InvariantCulture is the correct provider everywhere here. Fixes the S6580 / CA1305 warnings on these call sites. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--Emby.Naming/TV/EpisodePathParser.cs2
-rw-r--r--Jellyfin.Api/Controllers/ImageController.cs2
-rw-r--r--Jellyfin.Server/Migrations/Routines/20250420140000_MigrateAuthenticationDb.cs5
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs2
-rw-r--r--MediaBrowser.Providers/Books/OpenPackagingFormat/OpfReader.cs2
5 files changed, 7 insertions, 6 deletions
diff --git a/Emby.Naming/TV/EpisodePathParser.cs b/Emby.Naming/TV/EpisodePathParser.cs
index 8cd5a126e0..0c737964b4 100644
--- a/Emby.Naming/TV/EpisodePathParser.cs
+++ b/Emby.Naming/TV/EpisodePathParser.cs
@@ -125,7 +125,7 @@ namespace Emby.Naming.TV
result.Success = true;
}
}
- else if (DateTime.TryParse(match.Groups[0].ValueSpan, out date))
+ else if (DateTime.TryParse(match.Groups[0].ValueSpan, CultureInfo.InvariantCulture, out date))
{
result.Year = date.Year;
result.Month = date.Month;
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index ae792142b4..52d8b4dad1 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -2049,7 +2049,7 @@ public class ImageController : BaseJellyfinApiController
}
// Check If-Modified-Since header for time-based validation
- if (DateTime.TryParse(Request.Headers[HeaderNames.IfModifiedSince], out var ifModifiedSinceHeader))
+ if (DateTime.TryParse(Request.Headers[HeaderNames.IfModifiedSince], CultureInfo.InvariantCulture, out var ifModifiedSinceHeader))
{
// Return 304 if the image has not been modified since the client's cached version
if (dateImageModified <= ifModifiedSinceHeader)
diff --git a/Jellyfin.Server/Migrations/Routines/20250420140000_MigrateAuthenticationDb.cs b/Jellyfin.Server/Migrations/Routines/20250420140000_MigrateAuthenticationDb.cs
index 0de775e03a..cbdc6efb44 100644
--- a/Jellyfin.Server/Migrations/Routines/20250420140000_MigrateAuthenticationDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/20250420140000_MigrateAuthenticationDb.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using Emby.Server.Implementations.Data;
using Jellyfin.Database.Implementations;
@@ -79,9 +80,9 @@ namespace Jellyfin.Server.Migrations.Routines
foreach (var row in authenticatedDevices)
{
var dateCreatedStr = row.GetString(9);
- _ = DateTime.TryParse(dateCreatedStr, out var dateCreated);
+ _ = DateTime.TryParse(dateCreatedStr, CultureInfo.InvariantCulture, out var dateCreated);
var dateLastActivityStr = row.GetString(10);
- _ = DateTime.TryParse(dateLastActivityStr, out var dateLastActivity);
+ _ = DateTime.TryParse(dateLastActivityStr, CultureInfo.InvariantCulture, out var dateLastActivity);
if (row.IsDBNull(6))
{
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 0fe9db8a67..203e565ac7 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -1641,7 +1641,7 @@ namespace MediaBrowser.MediaEncoding.Probing
// Credit to MCEBuddy: https://mcebuddy2x.codeplex.com/
// DateTime is reported along with timezone info (typically Z i.e. UTC hence assume None)
- if (tags.TryGetValue("WM/MediaOriginalBroadcastDateTime", out var premiereDateString) && DateTime.TryParse(year, null, DateTimeStyles.AdjustToUniversal, out var parsedDate))
+ if (tags.TryGetValue("WM/MediaOriginalBroadcastDateTime", out var premiereDateString) && DateTime.TryParse(year, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out var parsedDate))
{
video.PremiereDate = parsedDate;
}
diff --git a/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfReader.cs b/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfReader.cs
index 15ea2ce5ab..b4e3fd3089 100644
--- a/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfReader.cs
+++ b/MediaBrowser.Providers/Books/OpenPackagingFormat/OpfReader.cs
@@ -125,7 +125,7 @@ namespace MediaBrowser.Providers.Books.OpenPackagingFormat
ReadStringInto("//dc:date", date =>
{
- if (DateTime.TryParse(date, out var dateValue))
+ if (DateTime.TryParse(date, CultureInfo.InvariantCulture, out var dateValue))
{
book.PremiereDate = dateValue.Date;
book.ProductionYear = dateValue.Date.Year;