Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -388,31 +388,31 @@
<Uri>https://github.com/dotnet/winforms</Uri>
<Sha>9b822fd70005bf5632d12fe76811b97b3dd044e4</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
</Dependency>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.arcade" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.SourceBuild.Intermediate.arcade" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="9.0.0-beta.25562.4">
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="9.0.0-beta.25626.6">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>6e2d8e204cebac7d3989c1996f96e5a9ed63fa80</Sha>
<Sha>ab5773ac30dce73227fa1dff6bf1a21eea67cbd0</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Diagnostics.Testing" Version="10.1.0-preview.1.25578.1">
<Uri>https://github.com/dotnet/extensions</Uri>
Expand Down
8 changes: 4 additions & 4 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@
<NuGetVersioningVersion>6.2.4</NuGetVersioningVersion>
<NuGetFrameworksVersion>6.2.4</NuGetFrameworksVersion>
<!-- Packages from dotnet/arcade -->
<MicrosoftDotNetBuildTasksInstallersVersion>9.0.0-beta.25562.4</MicrosoftDotNetBuildTasksInstallersVersion>
<MicrosoftDotNetBuildTasksTemplatingVersion>9.0.0-beta.25562.4</MicrosoftDotNetBuildTasksTemplatingVersion>
<MicrosoftDotNetRemoteExecutorVersion>9.0.0-beta.25562.4</MicrosoftDotNetRemoteExecutorVersion>
<MicrosoftSourceBuildIntermediatearcadeVersion>9.0.0-beta.25562.4</MicrosoftSourceBuildIntermediatearcadeVersion>
<MicrosoftDotNetBuildTasksInstallersVersion>9.0.0-beta.25626.6</MicrosoftDotNetBuildTasksInstallersVersion>
<MicrosoftDotNetBuildTasksTemplatingVersion>9.0.0-beta.25626.6</MicrosoftDotNetBuildTasksTemplatingVersion>
<MicrosoftDotNetRemoteExecutorVersion>9.0.0-beta.25626.6</MicrosoftDotNetRemoteExecutorVersion>
<MicrosoftSourceBuildIntermediatearcadeVersion>9.0.0-beta.25626.6</MicrosoftSourceBuildIntermediatearcadeVersion>
<!-- Packages from dotnet/source-build-externals -->
<MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>9.0.0-alpha.1.24575.1</MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>
<!-- Packages from dotnet/source-build-reference-packages -->
Expand Down
2 changes: 1 addition & 1 deletion eng/common/core-templates/job/source-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
demands: ImageOverride -equals build.ubuntu.2004.amd64
${{ if eq(variables['System.TeamProject'], 'internal') }}:
name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
image: 1es-mariner-2
image: 1es-azurelinux-3
os: linux
${{ else }}:
pool:
Expand Down
2 changes: 1 addition & 1 deletion eng/common/core-templates/job/source-index-stage1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ parameters:
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
binlogPath: artifacts/log/Debug/Build.binlog
condition: ''
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
dependsOn: ''
pool: ''
is1ESPipeline: ''
Expand Down
2 changes: 1 addition & 1 deletion eng/common/core-templates/steps/source-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ steps:
# in the default public locations.
internalRuntimeDownloadArgs=
if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
fi
buildConfig=Release
Expand Down
2 changes: 1 addition & 1 deletion eng/common/internal-feed-operations.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function SetupCredProvider {
$url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1'

Write-Host "Writing the contents of 'installcredprovider.ps1' locally..."
Invoke-WebRequest $url -OutFile installcredprovider.ps1
Invoke-WebRequest $url -UseBasicParsing -OutFile installcredprovider.ps1

Write-Host 'Installing plugin...'
.\installcredprovider.ps1 -Force
Expand Down
2 changes: 1 addition & 1 deletion eng/common/post-build/nuget-verification.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ if ($NuGetExePath) {
Write-Host "Downloading nuget.exe from $nugetExeUrl..."
$ProgressPreference = 'SilentlyContinue'
try {
Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe
Invoke-WebRequest $nugetExeUrl -UseBasicParsing -OutFile $downloadedNuGetExe
$ProgressPreference = 'Continue'
} catch {
$ProgressPreference = 'Continue'
Expand Down
19 changes: 13 additions & 6 deletions eng/common/tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) {

Retry({
Write-Host "GET $uri"
Invoke-WebRequest $uri -OutFile $installScript
Invoke-WebRequest $uri -UseBasicParsing -OutFile $installScript
})
}

Expand Down Expand Up @@ -499,7 +499,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {
Write-Host "Downloading $packageName $packageVersion"
$ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Retry({
Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath
Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath
})

if (!(Test-Path $packagePath)) {
Expand Down Expand Up @@ -543,23 +543,30 @@ function LocateVisualStudio([object]$vsRequirements = $null){
Create-Directory $vsWhereDir
Write-Host 'Downloading vswhere'
Retry({
Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe
Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -UseBasicParsing -OutFile $vswhereExe
})
}

if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs }
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs' -ErrorAction SilentlyContinue) {
$vsRequirements = $GlobalJson.tools.vs
} else {
$vsRequirements = $null
}
}

$args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*')

if (!$excludePrereleaseVS) {
$args += '-prerelease'
}

if (Get-Member -InputObject $vsRequirements -Name 'version') {
if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'version' -ErrorAction SilentlyContinue)) {
$args += '-version'
$args += $vsRequirements.version
}

if (Get-Member -InputObject $vsRequirements -Name 'components') {
if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'components' -ErrorAction SilentlyContinue)) {
foreach ($component in $vsRequirements.components) {
$args += '-requires'
$args += $component
Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"jdk": "latest"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25562.4",
"Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25562.4"
"Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25626.6",
"Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25626.6"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,17 @@ public void EmbeddingServerAppInsideIframe_WithCompressionEnabled_Fails()

Assert.True(logs.Count > 0);

Assert.Matches(ParseErrorMessage(), logs[0].Message);
Assert.True(
ParseErrorMessageRegexOld.IsMatch(logs[0].Message) &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Bug: Logical AND should be OR: assertion will always fail

The assertion uses && (AND) to check if the log message matches both ParseErrorMessageRegexOld and ParseErrorMessageRegexNew, but the error message says "Expected log message to match one of the CSP error patterns".

The two regexes match mutually exclusive message formats:

  • Old: "Refused to frame '...' because an ancestor violates..."
  • New: "Framing '...' violates..."

A single log message cannot match both patterns simultaneously, so IsMatch(Old) && IsMatch(New) will always be false, causing this test assertion to always fail. The operator should be || (OR) to correctly handle either CSP error message format.

Was this helpful? React with 👍 / 👎

Suggested change
ParseErrorMessageRegexOld.IsMatch(logs[0].Message) &&
ParseErrorMessageRegexOld.IsMatch(logs[0].Message) ||
ParseErrorMessageRegexNew.IsMatch(logs[0].Message),
  • Apply suggested fix

ParseErrorMessageRegexNew.IsMatch(logs[0].Message),
$"Expected log message to match one of the CSP error patterns: {ParseErrorMessageRegexOld} or {ParseErrorMessageRegexNew}. Actual: {logs[0].Message}");
}

[GeneratedRegex(@"security - Refused to frame 'http://\d+\.\d+\.\d+\.\d+:\d+/' because an ancestor violates the following Content Security Policy directive: ""frame-ancestors 'none'"".")]
private static partial Regex ParseErrorMessage();
private static partial Regex ParseErrorMessageRegexOld { get; }

[GeneratedRegex(@"security - Framing 'http://\d+\.\d+\.\d+\.\d+:\d+/' violates the following Content Security Policy directive: ""frame-ancestors 'none'"".")]
private static partial Regex ParseErrorMessageRegexNew { get; }
}

public partial class DefaultConfigurationWebSocketCompressionTests : AllowedWebSocketCompressionTests
Expand Down
8 changes: 5 additions & 3 deletions src/SignalR/server/StackExchangeRedis/test/RedisEndToEnd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public async Task HubConnectionCanSendAndReceiveGroupMessages(HttpTransportType
[ConditionalTheory]
[SkipIfDockerNotPresent]
[MemberData(nameof(TransportTypesAndProtocolTypes))]
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/59991")]
public async Task CanSendAndReceiveUserMessagesFromMultipleConnectionsWithSameUser(HttpTransportType transportType, string protocolName)
{
using (StartVerifiableLog())
Expand Down Expand Up @@ -184,6 +185,7 @@ public async Task HubConnectionCanSendAndReceiveGroupMessagesGroupNameWithPatter
[ConditionalTheory]
[SkipIfDockerNotPresent]
[MemberData(nameof(TransportTypesAndProtocolTypes))]
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/63582")]
public async Task CanSendAndReceiveUserMessagesUserNameWithPatternIsTreatedAsLiteral(HttpTransportType transportType, string protocolName)
{
using (StartVerifiableLog())
Expand All @@ -208,8 +210,8 @@ public async Task CanSendAndReceiveUserMessagesUserNameWithPatternIsTreatedAsLit
await connection.InvokeAsync("EchoUser", "*", "Hello, World!").DefaultTimeout();
Assert.Equal("Hello, World!", await tcs.Task.DefaultTimeout());

await connection.DisposeAsync().DefaultTimeout();
await secondConnection.DisposeAsync().DefaultTimeout();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: Connection disposal order reversed from established pattern

In CanSendAndReceiveUserMessagesUserNameWithPatternIsTreatedAsLiteral, the disposal order of connection and secondConnection has been swapped. The original code disposed connection first and then secondConnection, consistent with the pattern in the other user message test (CanSendAndReceiveUserMessagesFromMultipleConnectionsWithSameUser at line 114-115 which disposes connection then secondConnection).

While the disposal order may not always cause an immediate test failure (since assertions have already completed), reversing it can cause issues in scenarios where disposing one connection triggers side effects that the other depends on (e.g., Redis subscription cleanup, user tracking). The CanSendAndReceiveUserMessagesFromMultipleConnectionsWithSameUser test specifically tracks user connection count, and disposal order could affect the subscription lifecycle.

The order should be restored to dispose connection first, then secondConnection, matching the consistent pattern throughout this test file.

Was this helpful? React with 👍 / 👎

Suggested change
await secondConnection.DisposeAsync().DefaultTimeout();
await connection.DisposeAsync().DefaultTimeout();
await secondConnection.DisposeAsync().DefaultTimeout();
  • Apply suggested fix

await connection.DisposeAsync().DefaultTimeout();
}
}

Expand Down Expand Up @@ -357,7 +359,7 @@ public static IEnumerable<object[]> TransportTypesAndProtocolTypes
}
}

internal sealed class WebSocketWrapper : WebSocket
internal class WebSocketWrapper : WebSocket
{
private readonly WebSocket _inner;
private TaskCompletionSource<(WebSocketReceiveResult, ReadOnlyMemory<byte>)> _receiveTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
Expand Down Expand Up @@ -404,12 +406,12 @@ public void SetReceiveResult((WebSocketReceiveResult, ReadOnlyMemory<byte>) resu
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
{
var res = await _receiveTcs.Task;
_receiveTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: Zero-byte reads now consume the receive result, causing data loss

The _receiveTcs reinitialization was moved from after the zero-byte read check to before it. Previously, when buffer.Count == 0 (a zero-byte read used as a signal/peek), the method would return the result header without resetting _receiveTcs, allowing a subsequent non-zero-byte read to retrieve the same result and actually copy the data into the buffer.

With the new ordering:

  1. res = await _receiveTcs.Task — gets the pending result
  2. _receiveTcs = new(...)immediately resets the TCS (result is consumed)
  3. if (buffer.Count == 0) return res.Item1 — returns only the WebSocketReceiveResult without copying data

Now a zero-byte read consumes and discards the actual payload data (res.Item2). The next call to ReceiveAsync will await a new TCS that hasn't been signaled yet, blocking until SetReceiveResult is called again. This causes the message data from the first receive to be permanently lost.

This is the pattern used by SignalR for stateful reconnect, where zero-byte reads act as notifications that data is available, followed by a full read to get the data.

Was this helpful? React with 👍 / 👎

Suggested change
_receiveTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
var res = await _receiveTcs.Task;
// Handle zero-byte reads
if (buffer.Count == 0)
{
return res.Item1;
}
_receiveTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
res.Item2.CopyTo(buffer);
return res.Item1;
  • Apply suggested fix

// Handle zero-byte reads
if (buffer.Count == 0)
{
return res.Item1;
}
_receiveTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
res.Item2.CopyTo(buffer);
return res.Item1;
}
Expand Down