From 83629ab6f24ee1a8991dae2b8a55d24c93832ad5 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 10 Nov 2020 09:52:34 -0700 Subject: [PATCH 01/25] Update packages to net5 --- DvdLib/DvdLib.csproj | 2 +- Emby.Dlna/Emby.Dlna.csproj | 2 +- Emby.Drawing/Emby.Drawing.csproj | 2 +- Emby.Naming/Emby.Naming.csproj | 2 +- Emby.Notifications/Emby.Notifications.csproj | 2 +- Emby.Photos/Emby.Photos.csproj | 2 +- .../Emby.Server.Implementations.csproj | 12 ++++++------ Jellyfin.Api/Jellyfin.Api.csproj | 6 +++--- Jellyfin.Data/Jellyfin.Data.csproj | 6 +++--- Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj | 2 +- .../Jellyfin.Server.Implementations.csproj | 8 ++++---- Jellyfin.Server/Jellyfin.Server.csproj | 10 +++++----- MediaBrowser.Common/MediaBrowser.Common.csproj | 6 +++--- .../MediaBrowser.Controller.csproj | 6 +++--- .../MediaBrowser.LocalMetadata.csproj | 2 +- .../MediaBrowser.MediaEncoding.csproj | 4 ++-- MediaBrowser.Model/Extensions/StringHelper.cs | 6 ------ MediaBrowser.Model/MediaBrowser.Model.csproj | 8 ++++---- MediaBrowser.Providers/MediaBrowser.Providers.csproj | 8 ++++---- .../MediaBrowser.XbmcMetadata.csproj | 2 +- RSSDP/RSSDP.csproj | 2 +- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 6 +++--- .../Jellyfin.Common.Tests.csproj | 2 +- .../Jellyfin.Controller.Tests.csproj | 2 +- .../Jellyfin.MediaEncoding.Tests.csproj | 2 +- .../Jellyfin.Naming.Tests.csproj | 2 +- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 27 files changed, 55 insertions(+), 61 deletions(-) diff --git a/DvdLib/DvdLib.csproj b/DvdLib/DvdLib.csproj index 64d041cb05..7bbd9acf82 100644 --- a/DvdLib/DvdLib.csproj +++ b/DvdLib/DvdLib.csproj @@ -10,7 +10,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 6ed49944c0..bd30cc1e11 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -17,7 +17,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 092f8580a6..7d479a5c65 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj index 6857f9952c..80800840ee 100644 --- a/Emby.Naming/Emby.Naming.csproj +++ b/Emby.Naming/Emby.Naming.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Notifications/Emby.Notifications.csproj b/Emby.Notifications/Emby.Notifications.csproj index 1d430a5e58..16ee918c46 100644 --- a/Emby.Notifications/Emby.Notifications.csproj +++ b/Emby.Notifications/Emby.Notifications.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Photos/Emby.Photos.csproj b/Emby.Photos/Emby.Photos.csproj index dbe01257f4..62e33e6c44 100644 --- a/Emby.Photos/Emby.Photos.csproj +++ b/Emby.Photos/Emby.Photos.csproj @@ -19,7 +19,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index c762aa0b84..bcddea281c 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -32,13 +32,13 @@ - - - - + + + + - + @@ -49,7 +49,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index da0852cebc..2836f7b0ae 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 true true enable @@ -14,9 +14,9 @@ - + - + diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj index 5038988f96..9ae129d072 100644 --- a/Jellyfin.Data/Jellyfin.Data.csproj +++ b/Jellyfin.Data/Jellyfin.Data.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1 + net5.0 false true true @@ -41,8 +41,8 @@ - - + + diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj index c11ac5fb37..466a12e676 100644 --- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj +++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj index c52be3b8a9..e663798da0 100644 --- a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj +++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 false true true @@ -24,12 +24,12 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 3558f144cf..03d06fdff3 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -8,7 +8,7 @@ jellyfin Exe - netcoreapp3.1 + net5.0 false true true @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index e716a6610f..b67a549835 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -18,8 +18,8 @@ - - + + @@ -29,7 +29,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 4374317d67..9acc98dcec 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -14,8 +14,8 @@ - - + + @@ -29,7 +29,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 529e7065cd..3ce9ff4cc4 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -11,7 +11,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 6ead93e09b..7bb2a7d03f 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + net5.0 false true true @@ -25,7 +25,7 @@ - + diff --git a/MediaBrowser.Model/Extensions/StringHelper.cs b/MediaBrowser.Model/Extensions/StringHelper.cs index 8ffa3c4ba6..2d9a6c4dbc 100644 --- a/MediaBrowser.Model/Extensions/StringHelper.cs +++ b/MediaBrowser.Model/Extensions/StringHelper.cs @@ -22,11 +22,6 @@ namespace MediaBrowser.Model.Extensions return str; } -#if NETSTANDARD2_0 - char[] a = str.ToCharArray(); - a[0] = char.ToUpperInvariant(a[0]); - return new string(a); -#else return string.Create( str.Length, str, @@ -38,7 +33,6 @@ namespace MediaBrowser.Model.Extensions chars[i] = buf[i]; } }); -#endif } } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 253ee7e795..b86187f9be 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -14,7 +14,7 @@ - netstandard2.0;netstandard2.1 + net5.0 false true true @@ -32,11 +32,11 @@ - + - + - + diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 9465fe42c2..fd3f9f4c7e 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -16,9 +16,9 @@ - - - + + + @@ -26,7 +26,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj index 45fd9add92..87d1e9464c 100644 --- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj +++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj @@ -15,7 +15,7 @@ - netstandard2.1 + net5.0 false true true diff --git a/RSSDP/RSSDP.csproj b/RSSDP/RSSDP.csproj index 664663bd76..d0962e82c8 100644 --- a/RSSDP/RSSDP.csproj +++ b/RSSDP/RSSDP.csproj @@ -10,7 +10,7 @@ - netstandard2.1 + net5.0 false true diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index ce61f5684e..5bf322f071 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false true enable @@ -16,8 +16,8 @@ - - + + diff --git a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj index 67dc8286a3..e8eca67600 100644 --- a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj +++ b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false true enable diff --git a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj index 30e84842a0..6e3fac43d4 100644 --- a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj +++ b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false true enable diff --git a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj index 4fd0d53421..e88de38112 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj +++ b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false true enable diff --git a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj index 0d240fd65a..567cf34ef3 100644 --- a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj +++ b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false enable true diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index db1f2956ea..b960fda723 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -6,7 +6,7 @@ - netcoreapp3.1 + net5.0 false true enable From 9b7c5cddae73124fcb7b89cb033ac6ac817dcf75 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 10 Nov 2020 10:03:21 -0700 Subject: [PATCH 02/25] Update build ci, dockerfiles to .Net5.0 --- .ci/azure-pipelines-main.yml | 2 +- .ci/azure-pipelines.yml | 2 +- Dockerfile | 4 ++-- Dockerfile.arm | 4 ++-- Dockerfile.arm64 | 4 ++-- README.md | 2 +- deployment/Dockerfile.debian.amd64 | 3 ++- deployment/Dockerfile.debian.arm64 | 3 ++- deployment/Dockerfile.debian.armhf | 3 ++- deployment/Dockerfile.linux.amd64 | 3 ++- deployment/Dockerfile.macos | 3 ++- deployment/Dockerfile.portable | 3 ++- deployment/Dockerfile.ubuntu.amd64 | 3 ++- deployment/Dockerfile.ubuntu.arm64 | 3 ++- deployment/Dockerfile.ubuntu.armhf | 3 ++- deployment/Dockerfile.windows.amd64 | 3 ++- 16 files changed, 29 insertions(+), 19 deletions(-) diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml index 7617f0f5a2..95dd3ccac2 100644 --- a/.ci/azure-pipelines-main.yml +++ b/.ci/azure-pipelines-main.yml @@ -1,7 +1,7 @@ parameters: LinuxImage: 'ubuntu-latest' RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj' - DotNetSdkVersion: 3.1.100 + DotNetSdkVersion: 5.0.100 jobs: - job: Build diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 5b5a17dea2..ec4c254358 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -6,7 +6,7 @@ variables: - name: RestoreBuildProjects value: 'Jellyfin.Server/Jellyfin.Server.csproj' - name: DotNetSdkVersion - value: 3.1.100 + value: 5.0.100 pr: autoCancel: true diff --git a/Dockerfile b/Dockerfile index 69af9b77b5..639a1196c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG DOTNET_VERSION=3.1 +ARG DOTNET_VERSION=5.0 FROM node:alpine as web-builder ARG JELLYFIN_WEB_VERSION=master @@ -8,7 +8,7 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine- && yarn install \ && mv dist /dist -FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION}-buster as builder +FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-buster as builder WORKDIR /repo COPY . . ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 diff --git a/Dockerfile.arm b/Dockerfile.arm index efeed25dff..e0eaca0edd 100644 --- a/Dockerfile.arm +++ b/Dockerfile.arm @@ -2,7 +2,7 @@ ##################################### # Requires binfm_misc registration # https://github.com/multiarch/qemu-user-static#binfmt_misc-register -ARG DOTNET_VERSION=3.1 +ARG DOTNET_VERSION=5.0 FROM node:alpine as web-builder @@ -14,7 +14,7 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine- && mv dist /dist -FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder +FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder WORKDIR /repo COPY . . ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 1f2c2ec36d..db7de935cf 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -2,7 +2,7 @@ ##################################### # Requires binfm_misc registration # https://github.com/multiarch/qemu-user-static#binfmt_misc-register -ARG DOTNET_VERSION=3.1 +ARG DOTNET_VERSION=5.0 FROM node:alpine as web-builder @@ -14,7 +14,7 @@ RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine- && mv dist /dist -FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder +FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} as builder WORKDIR /repo COPY . . ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 diff --git a/README.md b/README.md index 435e709b33..1786ed8de5 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ These instructions will help you get set up with a local development environment ### Prerequisites -Before the project can be built, you must first install the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) on your system. +Before the project can be built, you must first install the [.NET 5.0 SDK](https://dotnet.microsoft.com/download) on your system. Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET Core development will work, but two options are recent versions of [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2017) and [Visual Studio Code](https://code.visualstudio.com/Download). diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index aaca8fe01e..6241aa1a7f 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index 594da04ceb..d09ba957e2 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index 3e6e2d0d70..dbffb8846c 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.linux.amd64 b/deployment/Dockerfile.linux.amd64 index f98881ebfe..e3faf43774 100644 --- a/deployment/Dockerfile.linux.amd64 +++ b/deployment/Dockerfile.linux.amd64 @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.macos b/deployment/Dockerfile.macos index ec9d2d8c77..b68c25a8ce 100644 --- a/deployment/Dockerfile.macos +++ b/deployment/Dockerfile.macos @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.portable b/deployment/Dockerfile.portable index 3523f8aceb..3a93b97261 100644 --- a/deployment/Dockerfile.portable +++ b/deployment/Dockerfile.portable @@ -15,7 +15,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index 0a365e1aee..bac6fadaf6 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index ab3ec9b9f8..dd042edbc2 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index fa41bdf48a..e5f669eff6 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -16,7 +16,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.windows.amd64 b/deployment/Dockerfile.windows.amd64 index 7216b2363b..5170b6895a 100644 --- a/deployment/Dockerfile.windows.amd64 +++ b/deployment/Dockerfile.windows.amd64 @@ -15,7 +15,8 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/fdd9ecec-56b4-40f4-b762-d7efe24fc3cd/ffef51844c92afa6714528e10609a30f/dotnet-sdk-3.1.403-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz + -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet From 38885ffd744e1b9d15fae80167ea67c94127acdd Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 08:31:02 -0700 Subject: [PATCH 03/25] Fix nullability errors in MediaBrowser.LocalMetadata --- MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs | 2 +- MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs | 2 +- MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index 914db53059..84c3ed8b0b 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -486,7 +486,7 @@ namespace MediaBrowser.LocalMetadata.Images return false; } - private FileSystemMetadata GetImage(IEnumerable files, string name) + private FileSystemMetadata? GetImage(IEnumerable files, string name) { return files.FirstOrDefault(i => !i.IsDirectory && string.Equals(name, _fileSystem.GetFileNameWithoutExtension(i), StringComparison.OrdinalIgnoreCase) && i.Length > 0); } diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index 4ac2498400..5d3ab30d39 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -683,7 +683,7 @@ namespace MediaBrowser.LocalMetadata.Parsers default: { string readerName = reader.Name; - if (_validProviderIds!.TryGetValue(readerName, out string providerIdValue)) + if (_validProviderIds!.TryGetValue(readerName, out string? providerIdValue)) { var id = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(id)) diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index 7a4823e1b8..11ad69d914 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -127,7 +127,13 @@ namespace MediaBrowser.LocalMetadata.Savers private void SaveToFile(Stream stream, string path) { - Directory.CreateDirectory(Path.GetDirectoryName(path)); + var directory = Path.GetDirectoryName(path); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + Directory.CreateDirectory(directory); // On Windows, savint the file will fail if the file is hidden or readonly FileSystem.SetAttributes(path, false, false); From 57b1e93411a19f1f6ea95131bdbeea4f9765df89 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 08:32:24 -0700 Subject: [PATCH 04/25] Fix nullability errors in Jellyfin.Server.Implementations --- .../Users/DefaultPasswordResetProvider.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index 6cb13cd23e..ced25524ee 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -54,12 +54,17 @@ namespace Jellyfin.Server.Implementations.Users var usersReset = new List(); foreach (var resetFile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{BaseResetFileName}*")) { - SerializablePasswordReset spr; + SerializablePasswordReset? spr; await using (var str = File.OpenRead(resetFile)) { spr = await JsonSerializer.DeserializeAsync(str).ConfigureAwait(false); } + if (spr == null) + { + throw new NullReferenceException(nameof(spr)); + } + if (spr.ExpirationDate < DateTime.UtcNow) { File.Delete(resetFile); From a02514a114dbca0b966578759fb347f8e6174c2b Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 08:34:34 -0700 Subject: [PATCH 05/25] Fix nullability errors in Jellyfin.Drawing.Skia --- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index 6a9dbdae42..ad066c524a 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -227,8 +227,13 @@ namespace Jellyfin.Drawing.Skia } var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path)); + var directory = Path.GetDirectoryName(tempPath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } - Directory.CreateDirectory(Path.GetDirectoryName(tempPath)); + Directory.CreateDirectory(directory); File.Copy(path, tempPath, true); return tempPath; @@ -493,7 +498,13 @@ namespace Jellyfin.Drawing.Skia // If all we're doing is resizing then we can stop now if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator) { - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + var outputDirectory = Path.GetDirectoryName(outputPath); + if (outputDirectory == null) + { + throw new NullReferenceException(nameof(outputDirectory)); + } + + Directory.CreateDirectory(outputDirectory); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels()); resizedBitmap.Encode(outputStream, skiaOutputFormat, quality); @@ -540,7 +551,13 @@ namespace Jellyfin.Drawing.Skia DrawIndicator(canvas, width, height, options); } - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + var directory = Path.GetDirectoryName(outputPath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + Directory.CreateDirectory(directory); using (var outputStream = new SKFileWStream(outputPath)) { using (var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels())) From f3e74cb42192142fee81a4042984f64480b39826 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 08:35:32 -0700 Subject: [PATCH 06/25] Fix nullability errors in Emby.Notifications --- Emby.Notifications/NotificationEntryPoint.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Emby.Notifications/NotificationEntryPoint.cs b/Emby.Notifications/NotificationEntryPoint.cs index 7116d52b11..7433d3c8ae 100644 --- a/Emby.Notifications/NotificationEntryPoint.cs +++ b/Emby.Notifications/NotificationEntryPoint.cs @@ -83,7 +83,7 @@ namespace Emby.Notifications return Task.CompletedTask; } - private async void OnAppHostHasPendingRestartChanged(object sender, EventArgs e) + private async void OnAppHostHasPendingRestartChanged(object? sender, EventArgs e) { var type = NotificationType.ServerRestartRequired.ToString(); @@ -99,7 +99,7 @@ namespace Emby.Notifications await SendNotification(notification, null).ConfigureAwait(false); } - private async void OnActivityManagerEntryCreated(object sender, GenericEventArgs e) + private async void OnActivityManagerEntryCreated(object? sender, GenericEventArgs e) { var entry = e.Argument; @@ -132,7 +132,7 @@ namespace Emby.Notifications return _config.GetConfiguration("notifications"); } - private async void OnAppHostHasUpdateAvailableChanged(object sender, EventArgs e) + private async void OnAppHostHasUpdateAvailableChanged(object? sender, EventArgs e) { if (!_appHost.HasUpdateAvailable) { @@ -151,7 +151,7 @@ namespace Emby.Notifications await SendNotification(notification, null).ConfigureAwait(false); } - private void OnLibraryManagerItemAdded(object sender, ItemChangeEventArgs e) + private void OnLibraryManagerItemAdded(object? sender, ItemChangeEventArgs e) { if (!FilterItem(e.Item)) { @@ -197,7 +197,7 @@ namespace Emby.Notifications return item.SourceType == SourceType.Library; } - private async void LibraryUpdateTimerCallback(object state) + private async void LibraryUpdateTimerCallback(object? state) { List items; From e82829c444a235d56aeafb60ad4424ee0d92b8b8 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:01:55 -0700 Subject: [PATCH 07/25] Fix nullability errors in MediaBrowser.MediaEncoding --- MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs index 21b5d0c5be..bc940d0b8d 100644 --- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs +++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs @@ -178,7 +178,7 @@ namespace MediaBrowser.MediaEncoding.Attachments process.Start(); - var ranToCompletion = await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false); + var ranToCompletion = await ProcessExtensions.WaitForExitAsync(process, cancellationToken).ConfigureAwait(false); if (!ranToCompletion) { From e8675a6c24ebb86ce4a48f208f439f42267bf8e6 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:03:44 -0700 Subject: [PATCH 08/25] Fix nullability errors in Jellyfin.Server --- Jellyfin.Server/Formatters/CssOutputFormatter.cs | 3 ++- Jellyfin.Server/Formatters/XmlOutputFormatter.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Server/Formatters/CssOutputFormatter.cs b/Jellyfin.Server/Formatters/CssOutputFormatter.cs index b3771b7fe6..e8dd48e4e6 100644 --- a/Jellyfin.Server/Formatters/CssOutputFormatter.cs +++ b/Jellyfin.Server/Formatters/CssOutputFormatter.cs @@ -30,7 +30,8 @@ namespace Jellyfin.Server.Formatters /// Write stream task. public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { - return context.HttpContext.Response.WriteAsync(context.Object?.ToString()); + var stringResponse = context.Object?.ToString(); + return stringResponse == null ? Task.CompletedTask : context.HttpContext.Response.WriteAsync(stringResponse); } } } diff --git a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs index 01d99d7c87..be0baea2d2 100644 --- a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs +++ b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs @@ -26,7 +26,8 @@ namespace Jellyfin.Server.Formatters /// public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { - return context.HttpContext.Response.WriteAsync(context.Object?.ToString()); + var stringResponse = context.Object?.ToString(); + return stringResponse == null ? Task.CompletedTask : context.HttpContext.Response.WriteAsync(stringResponse); } } } From 01355e049855a21b69e7e258599c3fa35965375a Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:04:31 -0700 Subject: [PATCH 09/25] Fix nullability errors in Jellyfin.Api (part 1) --- .../Controllers/DynamicHlsController.cs | 12 +++++++- .../Controllers/EnvironmentController.cs | 5 ++++ Jellyfin.Api/Controllers/GenresController.cs | 2 +- .../Controllers/HlsSegmentController.cs | 5 ++++ .../Controllers/ImageByNameController.cs | 2 +- Jellyfin.Api/Controllers/ImageController.cs | 3 +- .../Controllers/ItemLookupController.cs | 21 ++++++++++++-- Jellyfin.Api/Controllers/LibraryController.cs | 6 ++-- Jellyfin.Api/Controllers/LiveTvController.cs | 2 +- .../Controllers/MusicGenresController.cs | 4 +-- Jellyfin.Api/Controllers/PackageController.cs | 5 ++++ .../Controllers/RemoteImageController.cs | 28 +++++++++++++++---- Jellyfin.Api/Controllers/SearchController.cs | 2 +- .../Controllers/VideoHlsController.cs | 8 +++++- Jellyfin.Api/Helpers/AudioHelper.cs | 8 +++++- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 11 ++++++-- .../Helpers/FileStreamResponseHelpers.cs | 4 +-- Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs | 6 ++-- Jellyfin.Api/Helpers/HlsHelpers.cs | 4 +++ Jellyfin.Api/Helpers/ProgressiveFileCopier.cs | 5 ++++ Jellyfin.Api/Helpers/StreamingHelpers.cs | 4 +++ Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 26 +++++++++++------ .../Models/PlaybackDtos/TranscodingJobDto.cs | 4 +-- .../PlaybackDtos/TranscodingThrottler.cs | 2 +- .../ActivityLogWebSocketListener.cs | 2 +- .../ScheduledTasksWebSocketListener.cs | 6 ++-- .../SessionInfoWebSocketListener.cs | 14 +++++----- .../Subtitles/SubtitleEncoder.cs | 2 +- MediaBrowser.Model/Net/MimeTypes.cs | 6 ++-- 29 files changed, 155 insertions(+), 54 deletions(-) diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index e07690e110..b0d5a7cd84 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1347,7 +1347,13 @@ namespace Jellyfin.Api.Controllers var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty; - var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer); + var directory = Path.GetDirectoryName(outputPath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer); var segmentFormat = GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.'); if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)) @@ -1566,6 +1572,10 @@ namespace Jellyfin.Api.Controllers private string GetSegmentPath(StreamState state, string playlist, int index) { var folder = Path.GetDirectoryName(playlist); + if (folder == null) + { + throw new NullReferenceException(nameof(folder)); + } var filename = Path.GetFileNameWithoutExtension(playlist); diff --git a/Jellyfin.Api/Controllers/EnvironmentController.cs b/Jellyfin.Api/Controllers/EnvironmentController.cs index ce88b0b995..8de217bbfa 100644 --- a/Jellyfin.Api/Controllers/EnvironmentController.cs +++ b/Jellyfin.Api/Controllers/EnvironmentController.cs @@ -103,6 +103,11 @@ namespace Jellyfin.Api.Controllers if (validatePathDto.ValidateWritable) { + if (validatePathDto.Path == null) + { + throw new NullReferenceException(nameof(validatePathDto.Path)); + } + var file = Path.Combine(validatePathDto.Path, Guid.NewGuid().ToString()); try { diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs index f6e0772ec1..9c009d7847 100644 --- a/Jellyfin.Api/Controllers/GenresController.cs +++ b/Jellyfin.Api/Controllers/GenresController.cs @@ -177,7 +177,7 @@ namespace Jellyfin.Api.Controllers return _dtoService.GetBaseItemDto(item, dtoOptions); } - private T GetItemFromSlugName(ILibraryManager libraryManager, string name, DtoOptions dtoOptions) + private T? GetItemFromSlugName(ILibraryManager libraryManager, string name, DtoOptions dtoOptions) where T : BaseItem, new() { var result = libraryManager.GetItemList(new InternalItemsQuery diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs index 054e586ce3..2cee0e9ef2 100644 --- a/Jellyfin.Api/Controllers/HlsSegmentController.cs +++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs @@ -136,6 +136,11 @@ namespace Jellyfin.Api.Controllers string.Equals(Path.GetExtension(i), ".m3u8", StringComparison.OrdinalIgnoreCase) && i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1); + if (playlistPath == null) + { + throw new NullReferenceException(nameof(playlistPath)); + } + return GetFileResult(file, playlistPath); } diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs index 980c3273dd..198dbc51fc 100644 --- a/Jellyfin.Api/Controllers/ImageByNameController.cs +++ b/Jellyfin.Api/Controllers/ImageByNameController.cs @@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers /// Theme to search. /// File name to search for. /// A containing the image contents on success, or a if the image could not be found. - private ActionResult GetImageFile(string basePath, string? theme, string? name) + private ActionResult GetImageFile(string basePath, string theme, string? name) { var themeFolder = Path.Combine(basePath, theme); if (Directory.Exists(themeFolder)) diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index 4a67c1aede..76e53b9a53 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; +using System.Net.Mime; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Attributes; @@ -1268,7 +1269,7 @@ namespace Jellyfin.Api.Controllers Response.Headers.Add(key, value); } - Response.ContentType = imageContentType; + Response.ContentType = imageContentType ?? MediaTypeNames.Text.Plain; Response.Headers.Add(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture)); Response.Headers.Add(HeaderNames.Vary, HeaderNames.Accept); diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index ab73aa4286..b6cb797167 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -334,10 +334,21 @@ namespace Jellyfin.Api.Controllers private async Task DownloadImage(string providerName, string url, Guid urlHash, string pointerCachePath) { using var result = await _providerManager.GetSearchImage(providerName, url, CancellationToken.None).ConfigureAwait(false); + if (result.Content.Headers.ContentType?.MediaType == null) + { + throw new NullReferenceException(nameof(result.Content.Headers.ContentType)); + } + var ext = result.Content.Headers.ContentType.MediaType.Split('/')[^1]; var fullCachePath = GetFullCachePath(urlHash + "." + ext); - Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + var directory = Path.GetDirectoryName(fullCachePath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + Directory.CreateDirectory(directory); using (var stream = result.Content) { await using var fileStream = new FileStream( @@ -351,7 +362,13 @@ namespace Jellyfin.Api.Controllers await stream.CopyToAsync(fileStream).ConfigureAwait(false); } - Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); + if (pointerCacheDirectory == null) + { + throw new NullReferenceException(nameof(pointerCacheDirectory)); + } + + Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath).ConfigureAwait(false); } diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index 8a872ae133..60bbc5022a 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -455,7 +455,7 @@ namespace Jellyfin.Api.Controllers : null; var dtoOptions = new DtoOptions().AddClientFields(Request); - BaseItem parent = item.GetParent(); + BaseItem? parent = item.GetParent(); while (parent != null) { @@ -466,7 +466,7 @@ namespace Jellyfin.Api.Controllers baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, dtoOptions, user)); - parent = parent.GetParent(); + parent = parent?.GetParent(); } return baseItemDtos; @@ -854,7 +854,7 @@ namespace Jellyfin.Api.Controllers return _libraryManager.GetItemsResult(query).TotalRecordCount; } - private BaseItem TranslateParentItem(BaseItem item, User user) + private BaseItem? TranslateParentItem(BaseItem item, User user) { return item.GetParent() is AggregateFolder ? _libraryManager.GetUserRootFolder().GetChildren(user, true) diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 31253cbbcd..384a487055 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1078,7 +1078,7 @@ namespace Jellyfin.Api.Controllers var client = _httpClientFactory.CreateClient(NamedClient.Default); // https://json.schedulesdirect.org/20141201/available/countries // Can't dispose the response as it's required up the call chain. - var response = await client.GetAsync("https://json.schedulesdirect.org/20141201/available/countries") + var response = await client.GetAsync(new Uri("https://json.schedulesdirect.org/20141201/available/countries")) .ConfigureAwait(false); return File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), MediaTypeNames.Application.Json); diff --git a/Jellyfin.Api/Controllers/MusicGenresController.cs b/Jellyfin.Api/Controllers/MusicGenresController.cs index e434f190ac..989c383fdc 100644 --- a/Jellyfin.Api/Controllers/MusicGenresController.cs +++ b/Jellyfin.Api/Controllers/MusicGenresController.cs @@ -140,7 +140,7 @@ namespace Jellyfin.Api.Controllers { var dtoOptions = new DtoOptions().AddClientFields(Request); - MusicGenre item; + MusicGenre? item; if (genreName.IndexOf(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase) != -1) { @@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers return _dtoService.GetBaseItemDto(item, dtoOptions); } - private T GetItemFromSlugName(ILibraryManager libraryManager, string name, DtoOptions dtoOptions) + private T? GetItemFromSlugName(ILibraryManager libraryManager, string name, DtoOptions dtoOptions) where T : BaseItem, new() { var result = libraryManager.GetItemList(new InternalItemsQuery diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 1d9de14d2d..a104af4e63 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -54,6 +54,11 @@ namespace Jellyfin.Api.Controllers string.IsNullOrEmpty(assemblyGuid) ? default : Guid.Parse(assemblyGuid)) .FirstOrDefault(); + if (result == null) + { + return NotFound(); + } + return result; } diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index 5f095443b9..ad76b39847 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -157,9 +157,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] - public async Task GetRemoteImage([FromQuery, Required] string imageUrl) + public async Task GetRemoteImage([FromQuery, Required] Uri imageUrl) { - var urlHash = imageUrl.GetMD5(); + var urlHash = imageUrl.ToString().GetMD5(); var pointerCachePath = GetFullCachePath(urlHash.ToString()); string? contentPath = null; @@ -245,17 +245,35 @@ namespace Jellyfin.Api.Controllers /// The URL hash. /// The pointer cache path. /// Task. - private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath) + private async Task DownloadImage(Uri url, Guid urlHash, string pointerCachePath) { var httpClient = _httpClientFactory.CreateClient(NamedClient.Default); using var response = await httpClient.GetAsync(url).ConfigureAwait(false); + if (response.Content.Headers.ContentType?.MediaType == null) + { + throw new NullReferenceException(nameof(response.Content.Headers.ContentType)); + } + var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); var fullCachePath = GetFullCachePath(urlHash + "." + ext); - Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); + var fullCacheDirectory = Path.GetDirectoryName(fullCachePath); + if (fullCacheDirectory == null) + { + throw new NullReferenceException(nameof(fullCacheDirectory)); + } + + Directory.CreateDirectory(fullCacheDirectory); await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); - Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); + + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); + if (pointerCacheDirectory == null) + { + throw new NullReferenceException(nameof(pointerCacheDirectory)); + } + + Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) .ConfigureAwait(false); } diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 62c870cb1f..e75f0d06bb 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -260,7 +260,7 @@ namespace Jellyfin.Api.Controllers } } - private T GetParentWithImage(BaseItem item, ImageType type) + private T? GetParentWithImage(BaseItem item, ImageType type) where T : BaseItem { return item.GetParents().OfType().FirstOrDefault(i => i.HasImage(type)); diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index d7bcf79c1f..517239966f 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -361,7 +361,13 @@ namespace Jellyfin.Api.Controllers var threads = _encodingHelper.GetNumberOfThreads(state, _encodingOptions, videoCodec); var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions); var format = !string.IsNullOrWhiteSpace(state.Request.SegmentContainer) ? "." + state.Request.SegmentContainer : ".ts"; - var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format; + var directory = Path.GetDirectoryName(outputPath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format; var segmentFormat = format.TrimStart('.'); if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)) diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs index a3f2d88ce5..c6d577b193 100644 --- a/Jellyfin.Api/Helpers/AudioHelper.cs +++ b/Jellyfin.Api/Helpers/AudioHelper.cs @@ -1,4 +1,5 @@ -using System.Net.Http; +using System; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Models.StreamingDtos; @@ -98,6 +99,11 @@ namespace Jellyfin.Api.Helpers TranscodingJobType transcodingJobType, StreamingRequestDto streamingRequest) { + if (_httpContextAccessor.HttpContext == null) + { + throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext)); + } + bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head; var cancellationTokenSource = new CancellationTokenSource(); diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index ea012f8376..20bca731fd 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -113,7 +113,7 @@ namespace Jellyfin.Api.Helpers StreamingRequestDto streamingRequest, bool enableAdaptiveBitrateStreaming) { - var isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == WebRequestMethods.Http.Head; + var isHeadRequest = _httpContextAccessor.HttpContext?.Request.Method == WebRequestMethods.Http.Head; var cancellationTokenSource = new CancellationTokenSource(); return await GetMasterPlaylistInternal( streamingRequest, @@ -130,6 +130,11 @@ namespace Jellyfin.Api.Helpers TranscodingJobType transcodingJobType, CancellationTokenSource cancellationTokenSource) { + if (_httpContextAccessor.HttpContext == null) + { + throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext)); + } + using var state = await StreamingHelpers.GetStreamingState( streamingRequest, _httpContextAccessor.HttpContext.Request, @@ -487,14 +492,14 @@ namespace Jellyfin.Api.Helpers if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase)) { - string profile = state.GetRequestedProfiles("h264").FirstOrDefault(); + string? profile = state.GetRequestedProfiles("h264").FirstOrDefault(); return HlsCodecStringHelpers.GetH264String(profile, level); } if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)) { - string profile = state.GetRequestedProfiles("h265").FirstOrDefault(); + string? profile = state.GetRequestedProfiles("h265").FirstOrDefault(); return HlsCodecStringHelpers.GetH265String(profile, level); } diff --git a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs index 366301d3ee..20c94cddad 100644 --- a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs +++ b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs @@ -37,8 +37,8 @@ namespace Jellyfin.Api.Helpers } // Can't dispose the response as it's required up the call chain. - var response = await httpClient.GetAsync(state.MediaPath).ConfigureAwait(false); - var contentType = response.Content.Headers.ContentType.ToString(); + var response = await httpClient.GetAsync(new Uri(state.MediaPath)).ConfigureAwait(false); + var contentType = response.Content.Headers.ContentType?.ToString(); httpContext.Response.Headers[HeaderNames.AcceptRanges] = "none"; diff --git a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs index 95f1906ef0..1bd3d67ff2 100644 --- a/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs @@ -23,7 +23,7 @@ namespace Jellyfin.Api.Helpers /// /// AAC profile. /// AAC codec string. - public static string GetAACString(string profile) + public static string GetAACString(string? profile) { StringBuilder result = new StringBuilder("mp4a", 9); @@ -46,7 +46,7 @@ namespace Jellyfin.Api.Helpers /// H.264 profile. /// H.264 level. /// H.264 string. - public static string GetH264String(string profile, int level) + public static string GetH264String(string? profile, int level) { StringBuilder result = new StringBuilder("avc1", 11); @@ -80,7 +80,7 @@ namespace Jellyfin.Api.Helpers /// H.265 profile. /// H.265 level. /// H.265 string. - public static string GetH265String(string profile, int level) + public static string GetH265String(string? profile, int level) { // The h265 syntax is a bit of a mystery at the time this comment was written. // This is what I've found through various sources: diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs index 2424966973..16fbac7ae2 100644 --- a/Jellyfin.Api/Helpers/HlsHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsHelpers.cs @@ -45,6 +45,10 @@ namespace Jellyfin.Api.Helpers while (!reader.EndOfStream) { var line = await reader.ReadLineAsync().ConfigureAwait(false); + if (line == null) + { + throw new NullReferenceException(nameof(line)); + } if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) { diff --git a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs index e00ed33042..65c03c710b 100644 --- a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs +++ b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs @@ -90,6 +90,11 @@ namespace Jellyfin.Api.Helpers allowAsyncFileRead = true; } + if (_path == null) + { + throw new NullReferenceException(nameof(_path)); + } + await using var inputStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, fileOptions); var eofCount = 0; diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index f4ec29bdef..1d102071c2 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -83,6 +83,10 @@ namespace Jellyfin.Api.Helpers } streamingRequest.StreamOptions = ParseStreamOptions(httpRequest.Query); + if (httpRequest.Path.Value == null) + { + throw new NullReferenceException(nameof(httpRequest.Path)); + } var url = httpRequest.Path.Value.Split('.').Last(); diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 0db1fabffe..b72e33af38 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -102,7 +102,7 @@ namespace Jellyfin.Api.Helpers /// /// Playback session id. /// The transcoding job. - public TranscodingJobDto GetTranscodingJob(string playSessionId) + public TranscodingJobDto? GetTranscodingJob(string playSessionId) { lock (_activeTranscodingJobs) { @@ -116,7 +116,7 @@ namespace Jellyfin.Api.Helpers /// Path to the transcoding file. /// The . /// The transcoding job. - public TranscodingJobDto GetTranscodingJob(string path, TranscodingJobType type) + public TranscodingJobDto? GetTranscodingJob(string path, TranscodingJobType type) { lock (_activeTranscodingJobs) { @@ -193,9 +193,13 @@ namespace Jellyfin.Api.Helpers /// Called when [transcode kill timer stopped]. /// /// The state. - private async void OnTranscodeKillTimerStopped(object state) + private async void OnTranscodeKillTimerStopped(object? state) { - var job = (TranscodingJobDto)state; + var job = (TranscodingJobDto?)state; + if (job == null) + { + throw new NullReferenceException(nameof(job)); + } if (!job.HasExited && job.Type != TranscodingJobType.Progressive) { @@ -489,7 +493,13 @@ namespace Jellyfin.Api.Helpers CancellationTokenSource cancellationTokenSource, string? workingDirectory = null) { - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + var directory = Path.GetDirectoryName(outputPath); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + + Directory.CreateDirectory(directory); await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false); @@ -523,7 +533,7 @@ namespace Jellyfin.Api.Helpers RedirectStandardInput = true, FileName = _mediaEncoder.EncoderPath, Arguments = commandLineArguments, - WorkingDirectory = string.IsNullOrWhiteSpace(workingDirectory) ? null : workingDirectory, + WorkingDirectory = string.IsNullOrWhiteSpace(workingDirectory) ? string.Empty : workingDirectory, ErrorDialog = false }, EnableRaisingEvents = true @@ -827,7 +837,7 @@ namespace Jellyfin.Api.Helpers { lock (_transcodingLocks) { - if (!_transcodingLocks.TryGetValue(outputPath, out SemaphoreSlim result)) + if (!_transcodingLocks.TryGetValue(outputPath, out SemaphoreSlim? result)) { result = new SemaphoreSlim(1, 1); _transcodingLocks[outputPath] = result; @@ -837,7 +847,7 @@ namespace Jellyfin.Api.Helpers } } - private void OnPlaybackProgress(object sender, PlaybackProgressEventArgs e) + private void OnPlaybackProgress(object? sender, PlaybackProgressEventArgs e) { if (!string.IsNullOrWhiteSpace(e.PlaySessionId)) { diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs index b9507a4e50..9edc19bb6d 100644 --- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs +++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingJobDto.cs @@ -196,7 +196,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos /// Start kill timer. /// /// Callback action. - public void StartKillTimer(Action callback) + public void StartKillTimer(Action callback) { StartKillTimer(callback, PingTimeout); } @@ -206,7 +206,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos /// /// Callback action. /// Callback interval. - public void StartKillTimer(Action callback, int intervalMs) + public void StartKillTimer(Action callback, int intervalMs) { if (HasExited) { diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs index b5e42ea299..872a468245 100644 --- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs +++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs @@ -101,7 +101,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos return _config.GetConfiguration("encoding"); } - private async void TimerCallback(object state) + private async void TimerCallback(object? state) { if (_job.HasExited) { diff --git a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs index 77d55828d1..ce54651166 100644 --- a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs +++ b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs @@ -56,7 +56,7 @@ namespace Jellyfin.Api.WebSocketListeners base.Dispose(dispose); } - private void OnEntryCreated(object sender, GenericEventArgs e) + private void OnEntryCreated(object? sender, GenericEventArgs e) { SendData(true); } diff --git a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs index 80314b9236..94df23e569 100644 --- a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs +++ b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs @@ -64,19 +64,19 @@ namespace Jellyfin.Api.WebSocketListeners base.Dispose(dispose); } - private void OnTaskCompleted(object sender, TaskCompletionEventArgs e) + private void OnTaskCompleted(object? sender, TaskCompletionEventArgs e) { SendData(true); e.Task.TaskProgress -= OnTaskProgress; } - private void OnTaskExecuting(object sender, GenericEventArgs e) + private void OnTaskExecuting(object? sender, GenericEventArgs e) { SendData(true); e.Argument.TaskProgress += OnTaskProgress; } - private void OnTaskProgress(object sender, GenericEventArgs e) + private void OnTaskProgress(object? sender, GenericEventArgs e) { SendData(false); } diff --git a/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs index 1cf43a0053..d996ac69f9 100644 --- a/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs +++ b/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs @@ -66,37 +66,37 @@ namespace Jellyfin.Api.WebSocketListeners base.Dispose(dispose); } - private async void OnSessionManagerSessionActivity(object sender, SessionEventArgs e) + private async void OnSessionManagerSessionActivity(object? sender, SessionEventArgs e) { await SendData(false).ConfigureAwait(false); } - private async void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e) + private async void OnSessionManagerCapabilitiesChanged(object? sender, SessionEventArgs e) { await SendData(true).ConfigureAwait(false); } - private async void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e) + private async void OnSessionManagerPlaybackProgress(object? sender, PlaybackProgressEventArgs e) { await SendData(!e.IsAutomated).ConfigureAwait(false); } - private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e) + private async void OnSessionManagerPlaybackStopped(object? sender, PlaybackStopEventArgs e) { await SendData(true).ConfigureAwait(false); } - private async void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e) + private async void OnSessionManagerPlaybackStart(object? sender, PlaybackProgressEventArgs e) { await SendData(true).ConfigureAwait(false); } - private async void OnSessionManagerSessionEnded(object sender, SessionEventArgs e) + private async void OnSessionManagerSessionEnded(object? sender, SessionEventArgs e) { await SendData(true).ConfigureAwait(false); } - private async void OnSessionManagerSessionStarted(object sender, SessionEventArgs e) + private async void OnSessionManagerSessionStarted(object? sender, SessionEventArgs e) { await SendData(true).ConfigureAwait(false); } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 0a9958b9eb..8b3c6b2e63 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -758,7 +758,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles case MediaProtocol.Http: { using var response = await _httpClientFactory.CreateClient(NamedClient.Default) - .GetAsync(path, cancellationToken) + .GetAsync(new Uri(path), cancellationToken) .ConfigureAwait(false); return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); } diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index afe7351d32..55c0e6c9a6 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -210,9 +210,9 @@ namespace MediaBrowser.Model.Net return enableStreamDefault ? "application/octet-stream" : null; } - public static string? ToExtension(string mimeType) + public static string? ToExtension(string? mimeType) { - if (mimeType.Length == 0) + if (string.IsNullOrEmpty(mimeType)) { throw new ArgumentException("String can't be empty.", nameof(mimeType)); } @@ -220,7 +220,7 @@ namespace MediaBrowser.Model.Net // handle text/html; charset=UTF-8 mimeType = mimeType.Split(';')[0]; - if (_extensionLookup.TryGetValue(mimeType, out string result)) + if (_extensionLookup.TryGetValue(mimeType, out string? result)) { return result; } From 445eec7f5f8710179a425b3b6afa3d4d54ce03da Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:21:22 -0700 Subject: [PATCH 10/25] Fix nullability errors in Jellyfin.Api.Tests --- .../Auth/CustomAuthenticationHandlerTests.cs | 8 +++---- .../BrandingServiceTests.cs | 4 ++-- .../CommaDelimitedArrayModelBinderTests.cs | 24 +++++++++---------- tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs | 2 +- tests/Jellyfin.Api.Tests/TestHelpers.cs | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs index a46d94457f..90c4916668 100644 --- a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs @@ -81,7 +81,7 @@ namespace Jellyfin.Api.Tests.Auth var authenticateResult = await _sut.AuthenticateAsync(); Assert.False(authenticateResult.Succeeded); - Assert.Equal(errorMessage, authenticateResult.Failure.Message); + Assert.Equal(errorMessage, authenticateResult.Failure?.Message); } [Fact] @@ -100,7 +100,7 @@ namespace Jellyfin.Api.Tests.Auth var authorizationInfo = SetupUser(); var authenticateResult = await _sut.AuthenticateAsync(); - Assert.True(authenticateResult.Principal.HasClaim(ClaimTypes.Name, authorizationInfo.User.Username)); + Assert.True(authenticateResult.Principal?.HasClaim(ClaimTypes.Name, authorizationInfo.User.Username)); } [Theory] @@ -112,7 +112,7 @@ namespace Jellyfin.Api.Tests.Auth var authenticateResult = await _sut.AuthenticateAsync(); var expectedRole = authorizationInfo.User.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User; - Assert.True(authenticateResult.Principal.HasClaim(ClaimTypes.Role, expectedRole)); + Assert.True(authenticateResult.Principal?.HasClaim(ClaimTypes.Role, expectedRole)); } [Fact] @@ -121,7 +121,7 @@ namespace Jellyfin.Api.Tests.Auth SetupUser(); var authenticatedResult = await _sut.AuthenticateAsync(); - Assert.Equal(_scheme.Name, authenticatedResult.Ticket.AuthenticationScheme); + Assert.Equal(_scheme.Name, authenticatedResult.Ticket?.AuthenticationScheme); } private AuthorizationInfo SetupUser(bool isAdmin = false) diff --git a/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs b/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs index 6fc287420b..1cbe94c5b9 100644 --- a/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs +++ b/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs @@ -25,7 +25,7 @@ namespace Jellyfin.Api.Tests // Assert response.EnsureSuccessStatusCode(); - Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString()); + Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType?.ToString()); var responseBody = await response.Content.ReadAsStreamAsync(); _ = await JsonSerializer.DeserializeAsync(responseBody); } @@ -43,7 +43,7 @@ namespace Jellyfin.Api.Tests // Assert response.EnsureSuccessStatusCode(); - Assert.Equal("text/css; charset=utf-8", response.Content.Headers.ContentType.ToString()); + Assert.Equal("text/css; charset=utf-8", response.Content.Headers.ContentType?.ToString()); } } } diff --git a/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs b/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs index 89c7d62f79..6f3bd91329 100644 --- a/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs +++ b/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs @@ -17,7 +17,7 @@ namespace Jellyfin.Api.Tests.ModelBinders public async Task BindModelAsync_CorrectlyBindsValidCommaDelimitedStringArrayQuery() { var queryParamName = "test"; - var queryParamValues = new[] { "lol", "xd" }; + IReadOnlyList queryParamValues = new[] { "lol", "xd" }; var queryParamString = "lol,xd"; var queryParamType = typeof(string[]); @@ -35,14 +35,14 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((string[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object?.Result.Model, queryParamValues); } [Fact] public async Task BindModelAsync_CorrectlyBindsValidCommaDelimitedIntArrayQuery() { var queryParamName = "test"; - var queryParamValues = new[] { 42, 0 }; + IReadOnlyList queryParamValues = new[] { 42, 0 }; var queryParamString = "42,0"; var queryParamType = typeof(int[]); @@ -60,14 +60,14 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((int[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object.Result.Model, queryParamValues); } [Fact] public async Task BindModelAsync_CorrectlyBindsValidCommaDelimitedEnumArrayQuery() { var queryParamName = "test"; - var queryParamValues = new[] { TestType.How, TestType.Much }; + IReadOnlyList queryParamValues = new[] { TestType.How, TestType.Much }; var queryParamString = "How,Much"; var queryParamType = typeof(TestType[]); @@ -85,14 +85,14 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((TestType[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object.Result.Model, queryParamValues); } [Fact] public async Task BindModelAsync_CorrectlyBindsValidCommaDelimitedEnumArrayQueryWithDoubleCommas() { var queryParamName = "test"; - var queryParamValues = new[] { TestType.How, TestType.Much }; + IReadOnlyList queryParamValues = new[] { TestType.How, TestType.Much }; var queryParamString = "How,,Much"; var queryParamType = typeof(TestType[]); @@ -110,14 +110,14 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((TestType[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object.Result.Model, queryParamValues); } [Fact] public async Task BindModelAsync_CorrectlyBindsValidEnumArrayQuery() { var queryParamName = "test"; - var queryParamValues = new[] { TestType.How, TestType.Much }; + IReadOnlyList queryParamValues = new[] { TestType.How, TestType.Much }; var queryParamString1 = "How"; var queryParamString2 = "Much"; var queryParamType = typeof(TestType[]); @@ -140,14 +140,14 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((TestType[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object.Result.Model, queryParamValues); } [Fact] public async Task BindModelAsync_CorrectlyBindsEmptyEnumArrayQuery() { var queryParamName = "test"; - var queryParamValues = Array.Empty(); + IReadOnlyList queryParamValues = Array.Empty(); var queryParamType = typeof(TestType[]); var modelBinder = new CommaDelimitedArrayModelBinder(); @@ -168,7 +168,7 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Equal((TestType[])bindingContextMock.Object.Result.Model, queryParamValues); + Assert.Equal((IReadOnlyList?)bindingContextMock.Object.Result.Model, queryParamValues); } [Fact] diff --git a/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs b/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs index 3a85b55141..03ab56d1f4 100644 --- a/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs +++ b/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs @@ -30,7 +30,7 @@ namespace Jellyfin.Api.Tests // Assert response.EnsureSuccessStatusCode(); - Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString()); + Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType?.ToString()); // Write out for publishing var responseBody = await response.Content.ReadAsStringAsync(); diff --git a/tests/Jellyfin.Api.Tests/TestHelpers.cs b/tests/Jellyfin.Api.Tests/TestHelpers.cs index c4ce398859..f27cdf7b63 100644 --- a/tests/Jellyfin.Api.Tests/TestHelpers.cs +++ b/tests/Jellyfin.Api.Tests/TestHelpers.cs @@ -60,7 +60,7 @@ namespace Jellyfin.Api.Tests .Returns(user); httpContextAccessorMock - .Setup(h => h.HttpContext.Connection.RemoteIpAddress) + .Setup(h => h.HttpContext!.Connection.RemoteIpAddress) .Returns(new IPAddress(0)); return new ClaimsPrincipal(identity); From 6353cb507d591d5060c00d925f4e1ac6fc7a6916 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:21:28 -0700 Subject: [PATCH 11/25] Fix nullability errors in Jellyfin.Server --- Jellyfin.Server/Filters/FileResponseFilter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Server/Filters/FileResponseFilter.cs b/Jellyfin.Server/Filters/FileResponseFilter.cs index 8ea35c2818..7ad9466c17 100644 --- a/Jellyfin.Server/Filters/FileResponseFilter.cs +++ b/Jellyfin.Server/Filters/FileResponseFilter.cs @@ -26,22 +26,22 @@ namespace Jellyfin.Server.Filters if (attribute is ProducesFileAttribute producesFileAttribute) { // Get operation response values. - var (_, value) = operation.Responses + var response = operation.Responses .FirstOrDefault(o => o.Key.Equals(SuccessCode, StringComparison.Ordinal)); // Operation doesn't have a response. - if (value == null) + if (response.Value == null) { continue; } // Clear existing responses. - value.Content.Clear(); + response.Value.Content.Clear(); // Add all content-types as file. foreach (var contentType in producesFileAttribute.GetContentTypes()) { - value.Content.Add(contentType, _openApiMediaType); + response.Value.Content.Add(contentType, _openApiMediaType); } break; From d5e2369dd6ac308e518a5a36a744a1a2dac45f70 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:36:17 -0700 Subject: [PATCH 12/25] Fix nullability errors in MediaBrowser.Model --- MediaBrowser.Model/Entities/ProviderIdsExtensions.cs | 2 +- MediaBrowser.Model/Net/MimeTypes.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs index 9c11fe0ad2..1782b42e21 100644 --- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs +++ b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Model.Entities return null; } - instance.ProviderIds.TryGetValue(name, out string id); + instance.ProviderIds.TryGetValue(name, out string? id); return id; } diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 55c0e6c9a6..902db1e9e5 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -177,7 +177,7 @@ namespace MediaBrowser.Model.Net var ext = Path.GetExtension(path); - if (_mimeTypeLookup.TryGetValue(ext, out string result)) + if (_mimeTypeLookup.TryGetValue(ext, out string? result)) { return result; } From 7bf320922c095b67293c05b8d2e0ed79f1db78d7 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:41:18 -0700 Subject: [PATCH 13/25] Fix nullability errors in Emby.Server.Implementations --- .../AppBase/ConfigurationHelper.cs | 10 ++++++++-- .../Cryptography/CryptographyProvider.cs | 5 +++++ .../Session/WebSocketController.cs | 7 ++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 4c9ab33a7c..e19ce5edf8 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -35,7 +35,8 @@ namespace Emby.Server.Implementations.AppBase } catch (Exception) { - configuration = Activator.CreateInstance(type); + var instanceConfiguration = Activator.CreateInstance(type); + configuration = instanceConfiguration ?? throw new NullReferenceException(nameof(instanceConfiguration)); } using var stream = new MemoryStream(buffer?.Length ?? 0); @@ -48,8 +49,13 @@ namespace Emby.Server.Implementations.AppBase // If the file didn't exist before, or if something has changed, re-save if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer)) { - Directory.CreateDirectory(Path.GetDirectoryName(path)); + var directory = Path.GetDirectoryName(path); + if (directory == null) + { + throw new NullReferenceException(nameof(directory)); + } + Directory.CreateDirectory(directory); // Save it after load in case we got new items using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) { diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index fd302d1365..a48b6f3563 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -81,6 +81,11 @@ namespace Emby.Server.Implementations.Cryptography } using var h = HashAlgorithm.Create(hashMethod); + if (h == null) + { + throw new NullReferenceException(nameof(h)); + } + if (salt.Length == 0) { return h.ComputeHash(bytes); diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index b986ffa1cd..7559ccb782 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -55,8 +55,13 @@ namespace Emby.Server.Implementations.Session connection.Closed += OnConnectionClosed; } - private void OnConnectionClosed(object sender, EventArgs e) + private void OnConnectionClosed(object? sender, EventArgs e) { + if (sender == null) + { + throw new NullReferenceException(nameof(sender)); + } + var connection = (IWebSocketConnection)sender; _logger.LogDebug("Removing websocket from session {Session}", _session.Id); _sockets.Remove(connection); From 3c8800604e9e31688154dffcd161cc3bdbfc456a Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 09:48:26 -0700 Subject: [PATCH 14/25] Update test sdk --- .ci/azure-pipelines-abi.yml | 2 +- .ci/azure-pipelines-test.yml | 4 ++-- Jellyfin.Server/Properties/launchSettings.json | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.ci/azure-pipelines-abi.yml b/.ci/azure-pipelines-abi.yml index b558d2a6f0..14df7e7c8d 100644 --- a/.ci/azure-pipelines-abi.yml +++ b/.ci/azure-pipelines-abi.yml @@ -7,7 +7,7 @@ parameters: default: "ubuntu-latest" - name: DotNetSdkVersion type: string - default: 3.1.100 + default: 5.0.100 jobs: - job: CompatibilityCheck diff --git a/.ci/azure-pipelines-test.yml b/.ci/azure-pipelines-test.yml index 6a36698b56..4ceda978a6 100644 --- a/.ci/azure-pipelines-test.yml +++ b/.ci/azure-pipelines-test.yml @@ -10,7 +10,7 @@ parameters: default: "tests/**/*Tests.csproj" - name: DotNetSdkVersion type: string - default: 3.1.100 + default: 5.0.100 jobs: - job: Test @@ -94,5 +94,5 @@ jobs: displayName: 'Publish OpenAPI Artifact' condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) inputs: - targetPath: "tests/Jellyfin.Api.Tests/bin/Release/netcoreapp3.1/openapi.json" + targetPath: "tests/Jellyfin.Api.Tests/bin/Release/net5.0/openapi.json" artifactName: 'OpenAPI Spec' diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json index 20d432afc4..61a1723bd2 100644 --- a/Jellyfin.Server/Properties/launchSettings.json +++ b/Jellyfin.Server/Properties/launchSettings.json @@ -6,7 +6,8 @@ "applicationUrl": "http://localhost:8096", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "commandLineArgs": "--webdir C:\\Users\\Cody\\Code\\Jellyfin\\jellyfin-web\\dist" }, "Jellyfin.Server (nowebclient)": { "commandName": "Project", From 1acbceaade9339b48abfc7a276bb4eba68ec9d02 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 10:24:40 -0700 Subject: [PATCH 15/25] Disable warning on AD0001 --- Jellyfin.Api/Jellyfin.Api.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index 2836f7b0ae..da6e5fa2d4 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -10,6 +10,8 @@ true true enable + + AD0001 From ec5781504ea445f06554afa7853028bca9b75ec0 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 10:29:26 -0700 Subject: [PATCH 16/25] Disable warning on AD0001 --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index bcddea281c..f3052f5445 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -53,6 +53,8 @@ false true true + + AD0001 From e8b98265b0d0e66fe7ef6b8a0acb28725b86ebe6 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 10:40:09 -0700 Subject: [PATCH 17/25] Upgrade Jellyfin.Model.Tests to net5.0 --- tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj b/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj index e933851366..64d51e0638 100644 --- a/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj +++ b/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 false true enable From be312f992d92433e3e7619e264889d1a0afadf26 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 10:57:34 -0700 Subject: [PATCH 18/25] Update to net5 --- Jellyfin.Server/Properties/launchSettings.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json index 61a1723bd2..20d432afc4 100644 --- a/Jellyfin.Server/Properties/launchSettings.json +++ b/Jellyfin.Server/Properties/launchSettings.json @@ -6,8 +6,7 @@ "applicationUrl": "http://localhost:8096", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - }, - "commandLineArgs": "--webdir C:\\Users\\Cody\\Code\\Jellyfin\\jellyfin-web\\dist" + } }, "Jellyfin.Server (nowebclient)": { "commandName": "Project", From 5f52a58e785fa4ae06fa07a93b81c1e7547ac9f3 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 11:14:44 -0700 Subject: [PATCH 19/25] Convert NullReferenceException to ResourceNotFoundException --- Emby.Server.Implementations/AppBase/ConfigurationHelper.cs | 5 +++-- .../Cryptography/CryptographyProvider.cs | 3 ++- Emby.Server.Implementations/Session/WebSocketController.cs | 3 ++- Jellyfin.Api/Controllers/DynamicHlsController.cs | 5 +++-- Jellyfin.Api/Controllers/EnvironmentController.cs | 3 ++- Jellyfin.Api/Controllers/HlsSegmentController.cs | 3 ++- Jellyfin.Api/Controllers/ItemLookupController.cs | 6 +++--- Jellyfin.Api/Controllers/RemoteImageController.cs | 6 +++--- Jellyfin.Api/Controllers/VideoHlsController.cs | 3 ++- Jellyfin.Api/Helpers/AudioHelper.cs | 3 ++- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 2 +- Jellyfin.Api/Helpers/HlsHelpers.cs | 3 ++- Jellyfin.Api/Helpers/ProgressiveFileCopier.cs | 3 ++- Jellyfin.Api/Helpers/StreamingHelpers.cs | 2 +- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 5 +++-- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 7 ++++--- .../Users/DefaultPasswordResetProvider.cs | 2 +- MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 3 ++- 18 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index e19ce5edf8..8cca5cc779 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -3,6 +3,7 @@ using System; using System.IO; using System.Linq; +using MediaBrowser.Common.Extensions; using MediaBrowser.Model.Serialization; namespace Emby.Server.Implementations.AppBase @@ -36,7 +37,7 @@ namespace Emby.Server.Implementations.AppBase catch (Exception) { var instanceConfiguration = Activator.CreateInstance(type); - configuration = instanceConfiguration ?? throw new NullReferenceException(nameof(instanceConfiguration)); + configuration = instanceConfiguration ?? throw new ResourceNotFoundException(nameof(instanceConfiguration)); } using var stream = new MemoryStream(buffer?.Length ?? 0); @@ -52,7 +53,7 @@ namespace Emby.Server.Implementations.AppBase var directory = Path.GetDirectoryName(path); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index a48b6f3563..8d7f73b3cf 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Security.Cryptography; +using MediaBrowser.Common.Extensions; using MediaBrowser.Model.Cryptography; using static MediaBrowser.Common.Cryptography.Constants; @@ -83,7 +84,7 @@ namespace Emby.Server.Implementations.Cryptography using var h = HashAlgorithm.Create(hashMethod); if (h == null) { - throw new NullReferenceException(nameof(h)); + throw new ResourceNotFoundException(nameof(h)); } if (salt.Length == 0) diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index 7559ccb782..78f83e337f 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Net; @@ -59,7 +60,7 @@ namespace Emby.Server.Implementations.Session { if (sender == null) { - throw new NullReferenceException(nameof(sender)); + throw new ResourceNotFoundException(nameof(sender)); } var connection = (IWebSocketConnection)sender; diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index b0d5a7cd84..64bea999fa 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -14,6 +14,7 @@ using Jellyfin.Api.Helpers; using Jellyfin.Api.Models.PlaybackDtos; using Jellyfin.Api.Models.StreamingDtos; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; @@ -1350,7 +1351,7 @@ namespace Jellyfin.Api.Controllers var directory = Path.GetDirectoryName(outputPath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer); @@ -1574,7 +1575,7 @@ namespace Jellyfin.Api.Controllers var folder = Path.GetDirectoryName(playlist); if (folder == null) { - throw new NullReferenceException(nameof(folder)); + throw new ResourceNotFoundException(nameof(folder)); } var filename = Path.GetFileNameWithoutExtension(playlist); diff --git a/Jellyfin.Api/Controllers/EnvironmentController.cs b/Jellyfin.Api/Controllers/EnvironmentController.cs index 8de217bbfa..6dd5362547 100644 --- a/Jellyfin.Api/Controllers/EnvironmentController.cs +++ b/Jellyfin.Api/Controllers/EnvironmentController.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using Jellyfin.Api.Constants; using Jellyfin.Api.Models.EnvironmentDtos; +using MediaBrowser.Common.Extensions; using MediaBrowser.Model.IO; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -105,7 +106,7 @@ namespace Jellyfin.Api.Controllers { if (validatePathDto.Path == null) { - throw new NullReferenceException(nameof(validatePathDto.Path)); + throw new ResourceNotFoundException(nameof(validatePathDto.Path)); } var file = Path.Combine(validatePathDto.Path, Guid.NewGuid().ToString()); diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs index 2cee0e9ef2..fe1ffacb01 100644 --- a/Jellyfin.Api/Controllers/HlsSegmentController.cs +++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs @@ -8,6 +8,7 @@ using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; using Jellyfin.Api.Helpers; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.IO; @@ -138,7 +139,7 @@ namespace Jellyfin.Api.Controllers if (playlistPath == null) { - throw new NullReferenceException(nameof(playlistPath)); + throw new ResourceNotFoundException(nameof(playlistPath)); } return GetFileResult(file, playlistPath); diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index b6cb797167..b14840f80c 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -336,7 +336,7 @@ namespace Jellyfin.Api.Controllers using var result = await _providerManager.GetSearchImage(providerName, url, CancellationToken.None).ConfigureAwait(false); if (result.Content.Headers.ContentType?.MediaType == null) { - throw new NullReferenceException(nameof(result.Content.Headers.ContentType)); + throw new ResourceNotFoundException(nameof(result.Content.Headers.ContentType)); } var ext = result.Content.Headers.ContentType.MediaType.Split('/')[^1]; @@ -345,7 +345,7 @@ namespace Jellyfin.Api.Controllers var directory = Path.GetDirectoryName(fullCachePath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); @@ -365,7 +365,7 @@ namespace Jellyfin.Api.Controllers var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); if (pointerCacheDirectory == null) { - throw new NullReferenceException(nameof(pointerCacheDirectory)); + throw new ResourceNotFoundException(nameof(pointerCacheDirectory)); } Directory.CreateDirectory(pointerCacheDirectory); diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index ad76b39847..2566f574c4 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -251,7 +251,7 @@ namespace Jellyfin.Api.Controllers using var response = await httpClient.GetAsync(url).ConfigureAwait(false); if (response.Content.Headers.ContentType?.MediaType == null) { - throw new NullReferenceException(nameof(response.Content.Headers.ContentType)); + throw new ResourceNotFoundException(nameof(response.Content.Headers.ContentType)); } var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); @@ -260,7 +260,7 @@ namespace Jellyfin.Api.Controllers var fullCacheDirectory = Path.GetDirectoryName(fullCachePath); if (fullCacheDirectory == null) { - throw new NullReferenceException(nameof(fullCacheDirectory)); + throw new ResourceNotFoundException(nameof(fullCacheDirectory)); } Directory.CreateDirectory(fullCacheDirectory); @@ -270,7 +270,7 @@ namespace Jellyfin.Api.Controllers var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); if (pointerCacheDirectory == null) { - throw new NullReferenceException(nameof(pointerCacheDirectory)); + throw new ResourceNotFoundException(nameof(pointerCacheDirectory)); } Directory.CreateDirectory(pointerCacheDirectory); diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index 517239966f..c47876beba 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -11,6 +11,7 @@ using Jellyfin.Api.Helpers; using Jellyfin.Api.Models.PlaybackDtos; using Jellyfin.Api.Models.StreamingDtos; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; @@ -364,7 +365,7 @@ namespace Jellyfin.Api.Controllers var directory = Path.GetDirectoryName(outputPath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format; diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs index c6d577b193..21ec2d32f9 100644 --- a/Jellyfin.Api/Helpers/AudioHelper.cs +++ b/Jellyfin.Api/Helpers/AudioHelper.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Models.StreamingDtos; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; @@ -101,7 +102,7 @@ namespace Jellyfin.Api.Helpers { if (_httpContextAccessor.HttpContext == null) { - throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext)); + throw new ResourceNotFoundException(nameof(_httpContextAccessor.HttpContext)); } bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head; diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index 20bca731fd..e7fac50c64 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -132,7 +132,7 @@ namespace Jellyfin.Api.Helpers { if (_httpContextAccessor.HttpContext == null) { - throw new NullReferenceException(nameof(_httpContextAccessor.HttpContext)); + throw new ResourceNotFoundException(nameof(_httpContextAccessor.HttpContext)); } using var state = await StreamingHelpers.GetStreamingState( diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs index 16fbac7ae2..707d1cd104 100644 --- a/Jellyfin.Api/Helpers/HlsHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsHelpers.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; @@ -47,7 +48,7 @@ namespace Jellyfin.Api.Helpers var line = await reader.ReadLineAsync().ConfigureAwait(false); if (line == null) { - throw new NullReferenceException(nameof(line)); + throw new ResourceNotFoundException(nameof(line)); } if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) diff --git a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs index 65c03c710b..8bddf00d5f 100644 --- a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs +++ b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Models.PlaybackDtos; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Library; using MediaBrowser.Model.IO; @@ -92,7 +93,7 @@ namespace Jellyfin.Api.Helpers if (_path == null) { - throw new NullReferenceException(nameof(_path)); + throw new ResourceNotFoundException(nameof(_path)); } await using var inputStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, fileOptions); diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index 1d102071c2..04b1077277 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -85,7 +85,7 @@ namespace Jellyfin.Api.Helpers streamingRequest.StreamOptions = ParseStreamOptions(httpRequest.Query); if (httpRequest.Path.Value == null) { - throw new NullReferenceException(nameof(httpRequest.Path)); + throw new ResourceNotFoundException(nameof(httpRequest.Path)); } var url = httpRequest.Path.Value.Split('.').Last(); diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index b72e33af38..4ec0c576aa 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -12,6 +12,7 @@ using Jellyfin.Api.Models.PlaybackDtos; using Jellyfin.Api.Models.StreamingDtos; using Jellyfin.Data.Enums; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; @@ -198,7 +199,7 @@ namespace Jellyfin.Api.Helpers var job = (TranscodingJobDto?)state; if (job == null) { - throw new NullReferenceException(nameof(job)); + throw new ResourceNotFoundException(nameof(job)); } if (!job.HasExited && job.Type != TranscodingJobType.Progressive) @@ -496,7 +497,7 @@ namespace Jellyfin.Api.Helpers var directory = Path.GetDirectoryName(outputPath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index ad066c524a..1570d247b8 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using BlurHashSharp.SkiaSharp; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Drawing; @@ -230,7 +231,7 @@ namespace Jellyfin.Drawing.Skia var directory = Path.GetDirectoryName(tempPath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); @@ -501,7 +502,7 @@ namespace Jellyfin.Drawing.Skia var outputDirectory = Path.GetDirectoryName(outputPath); if (outputDirectory == null) { - throw new NullReferenceException(nameof(outputDirectory)); + throw new ResourceNotFoundException(nameof(outputDirectory)); } Directory.CreateDirectory(outputDirectory); @@ -554,7 +555,7 @@ namespace Jellyfin.Drawing.Skia var directory = Path.GetDirectoryName(outputPath); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index ced25524ee..465fb09cd8 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -62,7 +62,7 @@ namespace Jellyfin.Server.Implementations.Users if (spr == null) { - throw new NullReferenceException(nameof(spr)); + throw new ResourceNotFoundException(nameof(spr)); } if (spr.ExpirationDate < DateTime.UtcNow) diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index 11ad69d914..da04203e03 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Xml; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; @@ -130,7 +131,7 @@ namespace MediaBrowser.LocalMetadata.Savers var directory = Path.GetDirectoryName(path); if (directory == null) { - throw new NullReferenceException(nameof(directory)); + throw new ResourceNotFoundException(nameof(directory)); } Directory.CreateDirectory(directory); From 95ebb9a55ace6c544fa7fa15d0a255a5cee752a8 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 11:24:46 -0700 Subject: [PATCH 20/25] Use null coalescing when possible --- .../AppBase/ConfigurationHelper.cs | 6 +----- .../Cryptography/CryptographyProvider.cs | 7 +------ .../Session/WebSocketController.cs | 7 +------ .../Controllers/DynamicHlsController.cs | 13 ++---------- .../Controllers/HlsSegmentController.cs | 8 ++----- .../Controllers/ItemLookupController.cs | 13 ++---------- .../Controllers/RemoteImageController.cs | 14 ++----------- .../Controllers/VideoHlsController.cs | 7 +------ Jellyfin.Api/Helpers/HlsHelpers.cs | 7 ++----- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 14 ++----------- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 21 +++---------------- .../Users/DefaultPasswordResetProvider.cs | 8 ++----- .../Savers/BaseXmlSaver.cs | 7 +------ 13 files changed, 22 insertions(+), 110 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 8cca5cc779..b0a14f43d8 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -50,11 +50,7 @@ namespace Emby.Server.Implementations.AppBase // If the file didn't exist before, or if something has changed, re-save if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer)) { - var directory = Path.GetDirectoryName(path); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } + var directory = Path.GetDirectoryName(path) ?? throw new ResourceNotFoundException(nameof(path)); Directory.CreateDirectory(directory); // Save it after load in case we got new items diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index 8d7f73b3cf..42db183963 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -81,12 +81,7 @@ namespace Emby.Server.Implementations.Cryptography throw new CryptographicException($"Requested hash method is not supported: {hashMethod}"); } - using var h = HashAlgorithm.Create(hashMethod); - if (h == null) - { - throw new ResourceNotFoundException(nameof(h)); - } - + using var h = HashAlgorithm.Create(hashMethod) ?? throw new ResourceNotFoundException(nameof(hashMethod)); if (salt.Length == 0) { return h.ComputeHash(bytes); diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index 78f83e337f..5268ea1b93 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -58,12 +58,7 @@ namespace Emby.Server.Implementations.Session private void OnConnectionClosed(object? sender, EventArgs e) { - if (sender == null) - { - throw new ResourceNotFoundException(nameof(sender)); - } - - var connection = (IWebSocketConnection)sender; + var connection = sender as IWebSocketConnection ?? throw new ResourceNotFoundException(nameof(sender)); _logger.LogDebug("Removing websocket from session {Session}", _session.Id); _sockets.Remove(connection); connection.Closed -= OnConnectionClosed; diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 64bea999fa..783deebdce 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1348,11 +1348,7 @@ namespace Jellyfin.Api.Controllers var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty; - var directory = Path.GetDirectoryName(outputPath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } + var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer); @@ -1572,12 +1568,7 @@ namespace Jellyfin.Api.Controllers private string GetSegmentPath(StreamState state, string playlist, int index) { - var folder = Path.GetDirectoryName(playlist); - if (folder == null) - { - throw new ResourceNotFoundException(nameof(folder)); - } - + var folder = Path.GetDirectoryName(playlist) ?? throw new ResourceNotFoundException(nameof(playlist)); var filename = Path.GetFileNameWithoutExtension(playlist); return Path.Combine(folder, filename + index.ToString(CultureInfo.InvariantCulture) + GetSegmentFileExtension(state.Request.SegmentContainer)); diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs index fe1ffacb01..b9adcd3806 100644 --- a/Jellyfin.Api/Controllers/HlsSegmentController.cs +++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs @@ -135,12 +135,8 @@ namespace Jellyfin.Api.Controllers var playlistPath = _fileSystem.GetFilePaths(transcodeFolderPath) .FirstOrDefault(i => string.Equals(Path.GetExtension(i), ".m3u8", StringComparison.OrdinalIgnoreCase) - && i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1); - - if (playlistPath == null) - { - throw new ResourceNotFoundException(nameof(playlistPath)); - } + && i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1) + ?? throw new ResourceNotFoundException(nameof(transcodeFolderPath)); return GetFileResult(file, playlistPath); } diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index b14840f80c..a0d9bfb543 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -342,12 +342,7 @@ namespace Jellyfin.Api.Controllers var ext = result.Content.Headers.ContentType.MediaType.Split('/')[^1]; var fullCachePath = GetFullCachePath(urlHash + "." + ext); - var directory = Path.GetDirectoryName(fullCachePath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException(nameof(fullCachePath)); Directory.CreateDirectory(directory); using (var stream = result.Content) { @@ -362,11 +357,7 @@ namespace Jellyfin.Api.Controllers await stream.CopyToAsync(fileStream).ConfigureAwait(false); } - var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); - if (pointerCacheDirectory == null) - { - throw new ResourceNotFoundException(nameof(pointerCacheDirectory)); - } + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ResourceNotFoundException(nameof(pointerCachePath)); Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath).ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index 2566f574c4..b4a9e5582d 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -257,22 +257,12 @@ namespace Jellyfin.Api.Controllers var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); var fullCachePath = GetFullCachePath(urlHash + "." + ext); - var fullCacheDirectory = Path.GetDirectoryName(fullCachePath); - if (fullCacheDirectory == null) - { - throw new ResourceNotFoundException(nameof(fullCacheDirectory)); - } - + var fullCacheDirectory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException(nameof(fullCachePath)); Directory.CreateDirectory(fullCacheDirectory); await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); - var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath); - if (pointerCacheDirectory == null) - { - throw new ResourceNotFoundException(nameof(pointerCacheDirectory)); - } - + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ResourceNotFoundException(nameof(pointerCachePath)); Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) .ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index c47876beba..cc538f15e2 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -362,12 +362,7 @@ namespace Jellyfin.Api.Controllers var threads = _encodingHelper.GetNumberOfThreads(state, _encodingOptions, videoCodec); var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions); var format = !string.IsNullOrWhiteSpace(state.Request.SegmentContainer) ? "." + state.Request.SegmentContainer : ".ts"; - var directory = Path.GetDirectoryName(outputPath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format; var segmentFormat = format.TrimStart('.'); diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs index 707d1cd104..bcf0da319c 100644 --- a/Jellyfin.Api/Helpers/HlsHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsHelpers.cs @@ -45,11 +45,8 @@ namespace Jellyfin.Api.Helpers while (!reader.EndOfStream) { - var line = await reader.ReadLineAsync().ConfigureAwait(false); - if (line == null) - { - throw new ResourceNotFoundException(nameof(line)); - } + var line = await reader.ReadLineAsync().ConfigureAwait(false) + ?? throw new ResourceNotFoundException(nameof(reader)); if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) { diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 4ec0c576aa..8466241838 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -196,12 +196,7 @@ namespace Jellyfin.Api.Helpers /// The state. private async void OnTranscodeKillTimerStopped(object? state) { - var job = (TranscodingJobDto?)state; - if (job == null) - { - throw new ResourceNotFoundException(nameof(job)); - } - + var job = state as TranscodingJobDto ?? throw new ResourceNotFoundException(nameof(state)); if (!job.HasExited && job.Type != TranscodingJobType.Progressive) { var timeSinceLastPing = (DateTime.UtcNow - job.LastPingDate).TotalMilliseconds; @@ -494,12 +489,7 @@ namespace Jellyfin.Api.Helpers CancellationTokenSource cancellationTokenSource, string? workingDirectory = null) { - var directory = Path.GetDirectoryName(outputPath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); Directory.CreateDirectory(directory); await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false); diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index 1570d247b8..0c90d04a75 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -228,12 +228,7 @@ namespace Jellyfin.Drawing.Skia } var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path)); - var directory = Path.GetDirectoryName(tempPath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(tempPath) ?? throw new ResourceNotFoundException(nameof(tempPath)); Directory.CreateDirectory(directory); File.Copy(path, tempPath, true); @@ -499,12 +494,7 @@ namespace Jellyfin.Drawing.Skia // If all we're doing is resizing then we can stop now if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator) { - var outputDirectory = Path.GetDirectoryName(outputPath); - if (outputDirectory == null) - { - throw new ResourceNotFoundException(nameof(outputDirectory)); - } - + var outputDirectory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); Directory.CreateDirectory(outputDirectory); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels()); @@ -552,12 +542,7 @@ namespace Jellyfin.Drawing.Skia DrawIndicator(canvas, width, height, options); } - var directory = Path.GetDirectoryName(outputPath); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); Directory.CreateDirectory(directory); using (var outputStream = new SKFileWStream(outputPath)) { diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index 465fb09cd8..7f24904049 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -57,12 +57,8 @@ namespace Jellyfin.Server.Implementations.Users SerializablePasswordReset? spr; await using (var str = File.OpenRead(resetFile)) { - spr = await JsonSerializer.DeserializeAsync(str).ConfigureAwait(false); - } - - if (spr == null) - { - throw new ResourceNotFoundException(nameof(spr)); + spr = await JsonSerializer.DeserializeAsync(str).ConfigureAwait(false) + ?? throw new ResourceNotFoundException(nameof(spr)); } if (spr.ExpirationDate < DateTime.UtcNow) diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index da04203e03..2c9c9ccaa1 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -128,12 +128,7 @@ namespace MediaBrowser.LocalMetadata.Savers private void SaveToFile(Stream stream, string path) { - var directory = Path.GetDirectoryName(path); - if (directory == null) - { - throw new ResourceNotFoundException(nameof(directory)); - } - + var directory = Path.GetDirectoryName(path) ?? throw new ResourceNotFoundException(nameof(path)); Directory.CreateDirectory(directory); // On Windows, savint the file will fail if the file is hidden or readonly FileSystem.SetAttributes(path, false, false); From 24ac5cc353dd5b9930d43a5659d97037644fa58a Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 13 Nov 2020 13:18:31 -0700 Subject: [PATCH 21/25] Update Emby.Server.Implementations/AppBase/ConfigurationHelper.cs Co-authored-by: BaronGreenback --- Emby.Server.Implementations/AppBase/ConfigurationHelper.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index b0a14f43d8..6c425c7fb4 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -36,8 +36,7 @@ namespace Emby.Server.Implementations.AppBase } catch (Exception) { - var instanceConfiguration = Activator.CreateInstance(type); - configuration = instanceConfiguration ?? throw new ResourceNotFoundException(nameof(instanceConfiguration)); + configuration = Activator.CreateInstance(type) ?? throw new ResourceNotFoundException(nameof(type)); } using var stream = new MemoryStream(buffer?.Length ?? 0); From 73d2cb1c2a3a7cd1a30840a2b52921a3b81c6809 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 13 Nov 2020 18:04:06 -0700 Subject: [PATCH 22/25] Updated based on review feedback --- .../AppBase/ConfigurationHelper.cs | 4 ++-- .../Cryptography/CryptographyProvider.cs | 2 +- .../Session/WebSocketController.cs | 2 +- Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- Jellyfin.Api/Controllers/HlsSegmentController.cs | 2 +- Jellyfin.Api/Controllers/ItemLookupController.cs | 4 ++-- Jellyfin.Api/Controllers/RemoteImageController.cs | 4 ++-- Jellyfin.Api/Controllers/VideoHlsController.cs | 2 +- Jellyfin.Api/Helpers/HlsHelpers.cs | 9 ++++++--- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 4 ++-- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 6 +++--- .../Users/DefaultPasswordResetProvider.cs | 2 +- MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 2 +- 13 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 6c425c7fb4..77819c7649 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.AppBase } catch (Exception) { - configuration = Activator.CreateInstance(type) ?? throw new ResourceNotFoundException(nameof(type)); + configuration = Activator.CreateInstance(type) ?? throw new ArgumentException($"Provided path ({type}) is not valid.", nameof(type)); } using var stream = new MemoryStream(buffer?.Length ?? 0); @@ -49,7 +49,7 @@ namespace Emby.Server.Implementations.AppBase // If the file didn't exist before, or if something has changed, re-save if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer)) { - var directory = Path.GetDirectoryName(path) ?? throw new ResourceNotFoundException(nameof(path)); + var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path)); Directory.CreateDirectory(directory); // Save it after load in case we got new items diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index 42db183963..12a9e44e70 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -81,7 +81,7 @@ namespace Emby.Server.Implementations.Cryptography throw new CryptographicException($"Requested hash method is not supported: {hashMethod}"); } - using var h = HashAlgorithm.Create(hashMethod) ?? throw new ResourceNotFoundException(nameof(hashMethod)); + using var h = HashAlgorithm.Create(hashMethod) ?? throw new ResourceNotFoundException($"Unknown hash method: {hashMethod}."); if (salt.Length == 0) { return h.ComputeHash(bytes); diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index 5268ea1b93..f9c6a13c69 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.Session private void OnConnectionClosed(object? sender, EventArgs e) { - var connection = sender as IWebSocketConnection ?? throw new ResourceNotFoundException(nameof(sender)); + var connection = sender as IWebSocketConnection ?? throw new ArgumentException($"{nameof(sender)} is not of type {nameof(IWebSocketConnection)}", nameof(sender)); _logger.LogDebug("Removing websocket from session {Session}", _session.Id); _sockets.Remove(connection); connection.Closed -= OnConnectionClosed; diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 783deebdce..6e59da798c 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1348,7 +1348,7 @@ namespace Jellyfin.Api.Controllers var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty; - var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); + var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)); var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request.SegmentContainer); @@ -1568,7 +1568,7 @@ namespace Jellyfin.Api.Controllers private string GetSegmentPath(StreamState state, string playlist, int index) { - var folder = Path.GetDirectoryName(playlist) ?? throw new ResourceNotFoundException(nameof(playlist)); + var folder = Path.GetDirectoryName(playlist) ?? throw new ArgumentException($"Provided path ({playlist}) is not valid.", nameof(playlist)); var filename = Path.GetFileNameWithoutExtension(playlist); return Path.Combine(folder, filename + index.ToString(CultureInfo.InvariantCulture) + GetSegmentFileExtension(state.Request.SegmentContainer)); diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs index b9adcd3806..3b75e8d431 100644 --- a/Jellyfin.Api/Controllers/HlsSegmentController.cs +++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs @@ -136,7 +136,7 @@ namespace Jellyfin.Api.Controllers .FirstOrDefault(i => string.Equals(Path.GetExtension(i), ".m3u8", StringComparison.OrdinalIgnoreCase) && i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1) - ?? throw new ResourceNotFoundException(nameof(transcodeFolderPath)); + ?? throw new ResourceNotFoundException($"Provided path ({transcodeFolderPath}) is not valid."); return GetFileResult(file, playlistPath); } diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index a0d9bfb543..a7c1a63882 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -342,7 +342,7 @@ namespace Jellyfin.Api.Controllers var ext = result.Content.Headers.ContentType.MediaType.Split('/')[^1]; var fullCachePath = GetFullCachePath(urlHash + "." + ext); - var directory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException(nameof(fullCachePath)); + var directory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException($"Provided path ({fullCachePath}) is not valid."); Directory.CreateDirectory(directory); using (var stream = result.Content) { @@ -357,7 +357,7 @@ namespace Jellyfin.Api.Controllers await stream.CopyToAsync(fileStream).ConfigureAwait(false); } - var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ResourceNotFoundException(nameof(pointerCachePath)); + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ArgumentException($"Provided path ({pointerCachePath}) is not valid.", nameof(pointerCachePath)); Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath).ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index b4a9e5582d..c2bfab175a 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -257,12 +257,12 @@ namespace Jellyfin.Api.Controllers var ext = response.Content.Headers.ContentType.MediaType.Split('/').Last(); var fullCachePath = GetFullCachePath(urlHash + "." + ext); - var fullCacheDirectory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException(nameof(fullCachePath)); + var fullCacheDirectory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException($"Provided path ({fullCachePath}) is not valid."); Directory.CreateDirectory(fullCacheDirectory); await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); - var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ResourceNotFoundException(nameof(pointerCachePath)); + var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ArgumentException($"Provided path ({pointerCachePath}) is not valid.", nameof(pointerCachePath)); Directory.CreateDirectory(pointerCacheDirectory); await System.IO.File.WriteAllTextAsync(pointerCachePath, fullCachePath, CancellationToken.None) .ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index cc538f15e2..389dc8a088 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -362,7 +362,7 @@ namespace Jellyfin.Api.Controllers var threads = _encodingHelper.GetNumberOfThreads(state, _encodingOptions, videoCodec); var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions); var format = !string.IsNullOrWhiteSpace(state.Request.SegmentContainer) ? "." + state.Request.SegmentContainer : ".ts"; - var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); + var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)); var outputTsArg = Path.Combine(directory, Path.GetFileNameWithoutExtension(outputPath)) + "%d" + format; var segmentFormat = format.TrimStart('.'); diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs index bcf0da319c..7fd784806e 100644 --- a/Jellyfin.Api/Helpers/HlsHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsHelpers.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.Extensions; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; @@ -45,8 +44,12 @@ namespace Jellyfin.Api.Helpers while (!reader.EndOfStream) { - var line = await reader.ReadLineAsync().ConfigureAwait(false) - ?? throw new ResourceNotFoundException(nameof(reader)); + var line = await reader.ReadLineAsync().ConfigureAwait(false); + if (line == null) + { + // Nothing currently in buffer. + continue; + } if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) { diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 8466241838..168dc27a83 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -196,7 +196,7 @@ namespace Jellyfin.Api.Helpers /// The state. private async void OnTranscodeKillTimerStopped(object? state) { - var job = state as TranscodingJobDto ?? throw new ResourceNotFoundException(nameof(state)); + var job = state as TranscodingJobDto ?? throw new ArgumentException($"{nameof(state)} is not of type {nameof(TranscodingJobDto)}", nameof(state)); if (!job.HasExited && job.Type != TranscodingJobType.Progressive) { var timeSinceLastPing = (DateTime.UtcNow - job.LastPingDate).TotalMilliseconds; @@ -489,7 +489,7 @@ namespace Jellyfin.Api.Helpers CancellationTokenSource cancellationTokenSource, string? workingDirectory = null) { - var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); + var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)); Directory.CreateDirectory(directory); await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false); diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index 0c90d04a75..ee60748c71 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -228,7 +228,7 @@ namespace Jellyfin.Drawing.Skia } var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path)); - var directory = Path.GetDirectoryName(tempPath) ?? throw new ResourceNotFoundException(nameof(tempPath)); + var directory = Path.GetDirectoryName(tempPath) ?? throw new ResourceNotFoundException($"Provided path ({tempPath}) is not valid."); Directory.CreateDirectory(directory); File.Copy(path, tempPath, true); @@ -494,7 +494,7 @@ namespace Jellyfin.Drawing.Skia // If all we're doing is resizing then we can stop now if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator) { - var outputDirectory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); + var outputDirectory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)); Directory.CreateDirectory(outputDirectory); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels()); @@ -542,7 +542,7 @@ namespace Jellyfin.Drawing.Skia DrawIndicator(canvas, width, height, options); } - var directory = Path.GetDirectoryName(outputPath) ?? throw new ResourceNotFoundException(nameof(outputPath)); + var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)); Directory.CreateDirectory(directory); using (var outputStream = new SKFileWStream(outputPath)) { diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index 7f24904049..e71d419e0c 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -58,7 +58,7 @@ namespace Jellyfin.Server.Implementations.Users await using (var str = File.OpenRead(resetFile)) { spr = await JsonSerializer.DeserializeAsync(str).ConfigureAwait(false) - ?? throw new ResourceNotFoundException(nameof(spr)); + ?? throw new ResourceNotFoundException($"Provided path ({resetFile}) is not valid."); } if (spr.ExpirationDate < DateTime.UtcNow) diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index 2c9c9ccaa1..396206658d 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -128,7 +128,7 @@ namespace MediaBrowser.LocalMetadata.Savers private void SaveToFile(Stream stream, string path) { - var directory = Path.GetDirectoryName(path) ?? throw new ResourceNotFoundException(nameof(path)); + var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path)); Directory.CreateDirectory(directory); // On Windows, savint the file will fail if the file is hidden or readonly FileSystem.SetAttributes(path, false, false); From 843847fc9311ecd04d262d8b04698d88d6332efc Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 14 Nov 2020 09:16:08 -0700 Subject: [PATCH 23/25] Remove extraneous newline --- deployment/Dockerfile.debian.amd64 | 3 +-- deployment/Dockerfile.debian.arm64 | 3 +-- deployment/Dockerfile.debian.armhf | 3 +-- deployment/Dockerfile.linux.amd64 | 3 +-- deployment/Dockerfile.macos | 3 +-- deployment/Dockerfile.portable | 3 +-- deployment/Dockerfile.ubuntu.amd64 | 3 +-- deployment/Dockerfile.ubuntu.arm64 | 3 +-- deployment/Dockerfile.ubuntu.armhf | 3 +-- deployment/Dockerfile.windows.amd64 | 3 +-- 10 files changed, 10 insertions(+), 20 deletions(-) diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index 6241aa1a7f..1f28748b2f 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index d09ba957e2..9bd51ad8c3 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index dbffb8846c..fe54e5b47e 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.linux.amd64 b/deployment/Dockerfile.linux.amd64 index e3faf43774..4d00bc4997 100644 --- a/deployment/Dockerfile.linux.amd64 +++ b/deployment/Dockerfile.linux.amd64 @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.macos b/deployment/Dockerfile.macos index b68c25a8ce..85f3fc6424 100644 --- a/deployment/Dockerfile.macos +++ b/deployment/Dockerfile.macos @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.portable b/deployment/Dockerfile.portable index 3a93b97261..3253d2141a 100644 --- a/deployment/Dockerfile.portable +++ b/deployment/Dockerfile.portable @@ -15,8 +15,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index bac6fadaf6..d4fa596a3b 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index dd042edbc2..5fd19a2fc5 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index e5f669eff6..d73ea92fbd 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -16,8 +16,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.windows.amd64 b/deployment/Dockerfile.windows.amd64 index 5170b6895a..0c99f6954d 100644 --- a/deployment/Dockerfile.windows.amd64 +++ b/deployment/Dockerfile.windows.amd64 @@ -15,8 +15,7 @@ RUN apt-get update \ # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz - -O dotnet-sdk.tar.gz \ +RUN wget https://download.visualstudio.microsoft.com/download/pr/820db713-c9a5-466e-b72a-16f2f5ed00e2/628aa2a75f6aa270e77f4a83b3742fb8/dotnet-sdk-5.0.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet From 3f313206c606662d2b5bcfa2c2a99a5c218f5ff2 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 15 Nov 2020 11:35:36 -0700 Subject: [PATCH 24/25] Suggestions from review --- Jellyfin.Api/Helpers/HlsHelpers.cs | 2 +- .../Users/DefaultPasswordResetProvider.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs index 7fd784806e..45ce905668 100644 --- a/Jellyfin.Api/Helpers/HlsHelpers.cs +++ b/Jellyfin.Api/Helpers/HlsHelpers.cs @@ -48,7 +48,7 @@ namespace Jellyfin.Api.Helpers if (line == null) { // Nothing currently in buffer. - continue; + break; } if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index e71d419e0c..334f27f859 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -54,7 +54,7 @@ namespace Jellyfin.Server.Implementations.Users var usersReset = new List(); foreach (var resetFile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{BaseResetFileName}*")) { - SerializablePasswordReset? spr; + SerializablePasswordReset spr; await using (var str = File.OpenRead(resetFile)) { spr = await JsonSerializer.DeserializeAsync(str).ConfigureAwait(false) From 056c44010b437b0f718cb10b1ed66a7f38d61874 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 15 Nov 2020 12:19:07 -0700 Subject: [PATCH 25/25] Fix tests --- .../ModelBinders/CommaDelimitedArrayModelBinderTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs b/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs index 94f2800d46..3ae6ae5bdd 100644 --- a/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs +++ b/tests/Jellyfin.Api.Tests/ModelBinders/CommaDelimitedArrayModelBinderTests.cs @@ -177,7 +177,7 @@ namespace Jellyfin.Api.Tests.ModelBinders { var queryParamName = "test"; var queryParamString = "🔥,😢"; - var queryParamType = typeof(TestType[]); + var queryParamType = typeof(IReadOnlyList); var modelBinder = new CommaDelimitedArrayModelBinder(new NullLogger()); var valueProvider = new QueryStringValueProvider( @@ -192,7 +192,7 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Empty((TestType[])bindingContextMock.Object.Result.Model); + Assert.Empty((IReadOnlyList?)bindingContextMock.Object.Result.Model); } [Fact] @@ -201,7 +201,7 @@ namespace Jellyfin.Api.Tests.ModelBinders var queryParamName = "test"; var queryParamString1 = "How"; var queryParamString2 = "😱"; - var queryParamType = typeof(TestType[]); + var queryParamType = typeof(IReadOnlyList); var modelBinder = new CommaDelimitedArrayModelBinder(new NullLogger()); @@ -220,7 +220,7 @@ namespace Jellyfin.Api.Tests.ModelBinders await modelBinder.BindModelAsync(bindingContextMock.Object); Assert.True(bindingContextMock.Object.Result.IsModelSet); - Assert.Single((TestType[])bindingContextMock.Object.Result.Model); + Assert.Single((IReadOnlyList?)bindingContextMock.Object.Result.Model); } } }