From df6a1eaeab73894552141a19fd5705b2b140bb66 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Thu, 7 Mar 2024 22:21:24 -0800 Subject: [PATCH 01/10] Properly quote sc.exe create's binPath argument If the binPath isn't quoted, sc.exe will first look for a file at C:\Program. Starting that will yield CreateProcess error 193 (aka invalid Win32 program). By properly quoting the binPath, we guarantee that the correct file will be loaded. --- GVFS/GVFS.Installers/Setup.iss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GVFS/GVFS.Installers/Setup.iss b/GVFS/GVFS.Installers/Setup.iss index ca93ac914..109f4f45b 100644 --- a/GVFS/GVFS.Installers/Setup.iss +++ b/GVFS/GVFS.Installers/Setup.iss @@ -221,8 +221,12 @@ begin WizardForm.StatusLabel.Caption := 'Installing GVFS.Service.'; WizardForm.ProgressGauge.Style := npbstMarquee; + // Spaces after the equal signs are REQUIRED. + // https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create#remarks try - if Exec(ExpandConstant('{sys}\SC.EXE'), ExpandConstant('create GVFS.Service binPath="{app}\GVFS.Service.exe" start=auto'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then + // We must add additional quotes to the binPath to ensure that they survive argument parsing. + // Without quotes, sc.exe will try to start a file located at C:\Program if it exists. + if Exec(ExpandConstant('{sys}\SC.EXE'), ExpandConstant('create GVFS.Service binPath= "\"{app}\GVFS.Service.exe\"" start= auto'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then begin if Exec(ExpandConstant('{sys}\SC.EXE'), 'failure GVFS.Service reset= 30 actions= restart/10/restart/5000//1', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin From 129575397b7beb1df9625c1ed9d0c94cdd151edf Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 21 Aug 2024 11:26:45 +0200 Subject: [PATCH 02/10] Update the InnoSetup dependency to a newer version The primary reason is that Component Detection (https://github.com/microsoft/component-detection) pointed out that the version we used is missing legal information. As of https://github.com/clearlydefined/curated-data/pull/23677, version 6.2.1 of this package has a documented license. Therefore, this issue should be hereby resolved. Besides, it's always good to stay up to date with dependencies. Signed-off-by: Johannes Schindelin --- GVFS/GVFS.Installers/GVFS.Installers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GVFS/GVFS.Installers/GVFS.Installers.csproj b/GVFS/GVFS.Installers/GVFS.Installers.csproj index 1f5b692d1..44c166d56 100644 --- a/GVFS/GVFS.Installers/GVFS.Installers.csproj +++ b/GVFS/GVFS.Installers/GVFS.Installers.csproj @@ -12,7 +12,7 @@ - + From b121af90e45c57f67eb3ae2f4b0d005705290b0d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 21 Aug 2024 11:44:03 +0200 Subject: [PATCH 03/10] Update the LibGit2Sharp dependency to a newer version The primary reason is that Component Detection (https://github.com/microsoft/component-detection) pointed out that the version we used is missing legal information. Noticing that https://www.nuget.org/packages/LibGit2Sharp.NativeBinaries/2.0.278/License shows only a link into the repository, but the full license is shown at https://www.nuget.org/packages/LibGit2Sharp.NativeBinaries/2.0.322/License this issue should be hereby resolved. Besides, it's always good to stay up to date with dependencies. Since libgit2 is very careful about backwards-compatibility (and therefore LibGit2Sharp, too), this update should not result in any change of behavior. Signed-off-by: Johannes Schindelin --- GVFS/GVFS.Common/GVFS.Common.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GVFS/GVFS.Common/GVFS.Common.csproj b/GVFS/GVFS.Common/GVFS.Common.csproj index e96c88ba7..e19e8ee2e 100644 --- a/GVFS/GVFS.Common/GVFS.Common.csproj +++ b/GVFS/GVFS.Common/GVFS.Common.csproj @@ -6,7 +6,7 @@ - + From 56f001a6e859e32dff9eb3d8a2634274f6fef491 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 21 Aug 2024 13:33:09 +0200 Subject: [PATCH 04/10] Update all remaining dependencies to their latest stable versions Now that we addressed the Component Detection issues, let's just go ahead and proactively update the remaining dependencies, too. Signed-off-by: Johannes Schindelin --- GVFS/FastFetch/FastFetch.csproj | 2 +- .../GVFS.FunctionalTests.LockHolder.csproj | 2 +- GVFS/GVFS.Mount/GVFS.Mount.csproj | 2 +- GVFS/GVFS/GVFS.csproj | 2 +- Version.props | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GVFS/FastFetch/FastFetch.csproj b/GVFS/FastFetch/FastFetch.csproj index 52bb94654..1a2bdaae9 100644 --- a/GVFS/FastFetch/FastFetch.csproj +++ b/GVFS/FastFetch/FastFetch.csproj @@ -12,7 +12,7 @@ - + diff --git a/GVFS/GVFS.FunctionalTests.LockHolder/GVFS.FunctionalTests.LockHolder.csproj b/GVFS/GVFS.FunctionalTests.LockHolder/GVFS.FunctionalTests.LockHolder.csproj index 9a1615fbf..290a12b46 100644 --- a/GVFS/GVFS.FunctionalTests.LockHolder/GVFS.FunctionalTests.LockHolder.csproj +++ b/GVFS/GVFS.FunctionalTests.LockHolder/GVFS.FunctionalTests.LockHolder.csproj @@ -6,7 +6,7 @@ - + diff --git a/GVFS/GVFS.Mount/GVFS.Mount.csproj b/GVFS/GVFS.Mount/GVFS.Mount.csproj index b770e6f99..6e41c0008 100644 --- a/GVFS/GVFS.Mount/GVFS.Mount.csproj +++ b/GVFS/GVFS.Mount/GVFS.Mount.csproj @@ -16,7 +16,7 @@ - + diff --git a/GVFS/GVFS/GVFS.csproj b/GVFS/GVFS/GVFS.csproj index 8c143ebbc..6d9d579f9 100644 --- a/GVFS/GVFS/GVFS.csproj +++ b/GVFS/GVFS/GVFS.csproj @@ -16,7 +16,7 @@ - + diff --git a/Version.props b/Version.props index 6ee26e84b..1547245ce 100644 --- a/Version.props +++ b/Version.props @@ -18,7 +18,7 @@ including taking version numbers 2.X.Y from upstream and updating .W if we have any hotfixes to microsoft/git. --> - 2.20211115.1 + 2.20220414.4 v2.31.0.vfs.0.1 From f45cf18bf8dd5ab70a625c6c660d36d08e8a4bf4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 24 Oct 2024 10:27:22 +0200 Subject: [PATCH 05/10] ci: update Actions to newer versions The v2 version of `upload-artifact`/`download-artifact` is no longer supported and stopped working. Let's update to v4, which _does_ work. Signed-off-by: Johannes Schindelin --- .github/workflows/build.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a30be0879..97859a15f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,25 +42,25 @@ jobs: run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts - name: Upload functional tests drop - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: FunctionalTests_${{ matrix.configuration }} path: artifacts\GVFS.FunctionalTests - name: Upload FastFetch drop - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: FastFetch_${{ matrix.configuration }} path: artifacts\FastFetch - name: Upload installers - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: Installers_${{ matrix.configuration }} path: artifacts\GVFS.Installers - name: Upload NuGet packages - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: NuGetPackages_${{ matrix.configuration }} path: artifacts\NuGetPackages @@ -76,13 +76,13 @@ jobs: steps: - name: Download installers - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: Installers_${{ matrix.configuration }} path: install - name: Download functional tests drop - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: FunctionalTests_${{ matrix.configuration }} path: ft @@ -101,7 +101,7 @@ jobs: - name: Upload installation logs if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: InstallationLogs_${{ matrix.configuration }} path: install\logs @@ -115,14 +115,14 @@ jobs: - name: Upload functional test results if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: FunctionalTests_Results_${{ matrix.configuration }} path: TestResult.xml - name: Upload Git trace2 output if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: GitTrace2_${{ matrix.configuration }} path: C:\temp\git-trace2.log From 1cefe5086c9b49eb5d54bcc8930dba622e7ae2a6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 24 Oct 2024 10:30:56 +0200 Subject: [PATCH 06/10] ci: ask Dependabot to take care of updating GitHub Actions Every once in a while, the GitHub Actions we use (such as `checkout`, `upload-artifact`, etc) require updates as the old versions stop working. Let's ask Dependabot to take care of this tedious task. Signed-off-by: Johannes Schindelin --- .github/dependabot.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..22d537640 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file +# especially +# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot#enabling-dependabot-version-updates-for-actions + +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" From 15d25e5c1c60a81728bf01f09f0ab1ccb570a449 Mon Sep 17 00:00:00 2001 From: Tyrie Vella Date: Fri, 18 Oct 2024 16:20:07 -0700 Subject: [PATCH 07/10] Handle nested failures in HttpRequestException `HttpClientHandler` will automatically resubmit an HTTP request that fails in certain circumstances. One such circumstance is when `UseDefaultCredentials` is set to `true``, alternative credentials were provided on the request, and the request failed with "401 Unauthorized", then it will resubmit using the default credentials. If an exception is thrown when getting the default credentials that exception is not handled, but is wrapped in `HttpRequestExceptio`n and thrown by `SendAsync` instead of returning the original response with the failing status code. See the following code snippet from `HttpWebRequest`: https://referencesource.microsoft.com/#System/net/System/Net/HttpWebRequest.cs,5535 When this happens in GVFS, the result is that GVFS does not recognize the failure as being authentication related, so it does not refresh the credential. Instead, it loops through all its retries, and eventually fails the request. This is typically visible to users as a file system exception (e.g. file not found) if the GVFS trigger was accessing a virtual file or other operation on an individual file, or various errors (including "this repository requires the GVFS protocol") for a `git pull`. The symptoms will continue for the user until they remount the GVFS enlistment, which forces GVFS to refresh its credential. This commit adds an exception handler for `HttpRequestException`` to `client.SendAsync`, which attempts to find the original failed response embedded in the inner exception properties. If it does so, it logs a warning and continues processing using the original failed response, which will trigger the logic for handling the various possible status codes. If it can't extract the original failed response, then it will let the exception bubble up. Signed-off-by: Tyrie Vella Signed-off-by: Johannes Schindelin --- GVFS/GVFS.Common/Http/HttpRequestor.cs | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/GVFS/GVFS.Common/Http/HttpRequestor.cs b/GVFS/GVFS.Common/Http/HttpRequestor.cs index 1f5271d67..ca850c9fb 100644 --- a/GVFS/GVFS.Common/Http/HttpRequestor.cs +++ b/GVFS/GVFS.Common/Http/HttpRequestor.cs @@ -134,6 +134,14 @@ protected GitEndPointResponseData SendRequest( { response = this.client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).GetAwaiter().GetResult(); } + catch (HttpRequestException httpRequestException) when (TryGetResponseMessageFromHttpRequestException(httpRequestException, request, out response)) + { + /* HttpClientHandler will automatically resubmit in certain circumstances, such as a 401 unauthorized response when UseDefaultCredentials + * is true but another credential was provided. This resubmit can throw (instead of returning a proper status code) in some case cases, such + * as when there is an exception loading the default credentials. + * If we can extract the original response message from the exception, we can continue and process the original failed status code. */ + Tracer.RelatedWarning(responseMetadata, $"An exception occurred while resubmitting the request, but the original response is available."); + } finally { responseWaitTime = requestStopwatch.Elapsed; @@ -278,5 +286,48 @@ private static string GetSingleHeaderOrEmpty(HttpHeaders headers, string headerN return string.Empty; } + + /// + /// This method is based on a private method System.Net.Http.HttpClientHandler.CreateResponseMessage + /// + private static bool TryGetResponseMessageFromHttpRequestException(HttpRequestException httpRequestException, HttpRequestMessage request, out HttpResponseMessage httpResponseMessage) + { + var webResponse = (httpRequestException?.InnerException as WebException)?.Response as HttpWebResponse; + if (webResponse == null) + { + httpResponseMessage = null; + return false; + } + + httpResponseMessage = new HttpResponseMessage(webResponse.StatusCode); + httpResponseMessage.ReasonPhrase = webResponse.StatusDescription; + httpResponseMessage.Version = webResponse.ProtocolVersion; + httpResponseMessage.RequestMessage = request; + httpResponseMessage.Content = new StreamContent(webResponse.GetResponseStream()); + request.RequestUri = webResponse.ResponseUri; + WebHeaderCollection rawHeaders = webResponse.Headers; + HttpContentHeaders responseContentHeaders = httpResponseMessage.Content.Headers; + HttpResponseHeaders responseHeaders = httpResponseMessage.Headers; + if (webResponse.ContentLength >= 0) + { + responseContentHeaders.ContentLength = webResponse.ContentLength; + } + + for (int i = 0; i < rawHeaders.Count; i++) + { + string key = rawHeaders.GetKey(i); + if (string.Compare(key, "Content-Length", StringComparison.OrdinalIgnoreCase) != 0) + { + string[] values = rawHeaders.GetValues(i); + if (!responseHeaders.TryAddWithoutValidation(key, values)) + { + bool flag = responseContentHeaders.TryAddWithoutValidation(key, values); + } + } + } + + return true; + + } } } From 21c39f747ad4062a87fe99abe315a50330701c96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:32:44 +0000 Subject: [PATCH 08/10] build(deps): bump actions/setup-dotnet from 1 to 4 Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 4. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v1...v4) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 97859a15f..f98400cd5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -22,7 +22,7 @@ jobs: path: src - name: Install .NET SDK - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: 5.0.201 From 21d27740b057bad3c66560f010de6c4c12033205 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:32:47 +0000 Subject: [PATCH 09/10] build(deps): bump actions/checkout from 2 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 97859a15f..ab869e700 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: src From 554e94b9390ef84e25dbef7d02f8774613d58a67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:32:49 +0000 Subject: [PATCH 10/10] build(deps): bump microsoft/setup-msbuild from 1.0.2 to 2.0.0 Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.0.2 to 2.0.0. - [Release notes](https://github.com/microsoft/setup-msbuild/releases) - [Changelog](https://github.com/microsoft/setup-msbuild/blob/main/building-release.md) - [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.0.2...v2.0.0) --- updated-dependencies: - dependency-name: microsoft/setup-msbuild dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 97859a15f..997cd6146 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -27,7 +27,7 @@ jobs: dotnet-version: 5.0.201 - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@v2.0.0 - name: Build VFS for Git shell: cmd