diff --git a/src/Cli/dotnet/Commands/CliCommandStrings.resx b/src/Cli/dotnet/Commands/CliCommandStrings.resx
index 495d18fbb4c1..74001a13dfe9 100644
--- a/src/Cli/dotnet/Commands/CliCommandStrings.resx
+++ b/src/Cli/dotnet/Commands/CliCommandStrings.resx
@@ -1620,6 +1620,9 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Duplicate directives are not supported: {0}
{0} is the directive type and name.
+
+ Directives currently cannot contain double quotes (").
+
Cannot specify option '{0}' when also using '-' to read the file from standard input.
{0} is an option name like '--no-build'.
diff --git a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs
index 794b7f77974e..6b99feedd1ab 100644
--- a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs
+++ b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs
@@ -1505,8 +1505,15 @@ public static ImmutableArray FindDirectives(SourceFile sourceFi
Diagnostics = diagnostics,
SourceFile = sourceFile,
DirectiveKind = name.ToString(),
- DirectiveText = value.ToString()
+ DirectiveText = value.ToString(),
};
+
+ // Block quotes now so we can later support quoted values without a breaking change. https://github.com/dotnet/sdk/issues/49367
+ if (value.Contains('"'))
+ {
+ diagnostics.AddError(sourceFile, context.Info.Span, CliCommandStrings.QuoteInDirective);
+ }
+
if (CSharpDirective.Parse(context) is { } directive)
{
// If the directive is already present, report an error.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
index 103346abd196..10a84c76b1a2 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
Ve výchozím nastavení je publikována aplikace závislá na architektuře.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Vypne buildovací server Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
index b0152c1b2ddc..70630b7a74bb 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
Standardmäßig wird eine Framework-abhängige Anwendung veröffentlicht.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Hiermit wird der Razor-Buildserver heruntergefahren.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
index 2a3a8fb5d834..84d3025e048f 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
El valor predeterminado es publicar una aplicación dependiente del marco.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Apaga el servidor de compilación de Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
index c3159e8182ce..3b1487a77047 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
La valeur par défaut est de publier une application dépendante du framework.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Arrêtez le serveur de builds Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
index dc7d41f3f845..fffbb67c75e9 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
Per impostazione predefinita, viene generato un pacchetto dipendente dal framework.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Arresta il server di compilazione di Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
index 7f103c9c4105..4a9b4564cd88 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
既定では、フレームワークに依存したアプリケーションが公開されます。
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Razor ビルド サーバーをシャットダウンします。
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
index bc39df5fe54a..d7a462877fb5 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
기본값은 프레임워크 종속 애플리케이션을 게시하는 것입니다.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Razor 빌드 서버를 종료합니다.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
index 3e345a828e15..455c06c0f7da 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
Domyślnie publikowana jest aplikacja zależna od struktury.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Zamknij serwer kompilacji Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
index 86b8b6c89f48..f999a934e37d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
O padrão é publicar uma aplicação dependente de framework.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Desligar o servidor de build do Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
index 8831a34832c0..adae2e4b3b1d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
По умолчанию публикация выполняется в приложение, зависимое от платформы.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Завершает работу сервера сборки Razor.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
index aebfc0f66817..4e19bf47de42 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
Varsayılan durum, çerçeveye bağımlı bir uygulama yayımlamaktır.
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
Razor derleme sunucusunu kapatır.
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
index 19e35a25e314..85e43f3d5086 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
默认情况下发布依赖于框架的应用程序。
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
关闭 Razor 生成服务器。
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
index 10e1068997b1..7023d8771c09 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
@@ -2572,6 +2572,11 @@ The default is to publish a framework-dependent application.
預設為發佈與 Framework 相依的應用程式。
+
+ Directives currently cannot contain double quotes (").
+ Directives currently cannot contain double quotes (").
+
+
Shut down the Razor build server.
關閉 Razor 組建伺服器。
diff --git a/test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs b/test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs
index cb7fd4331429..90763462aeb4 100644
--- a/test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs
+++ b/test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Collections.Immutable;
using System.Security;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis.Text;
@@ -1168,10 +1169,10 @@ public void Directives_InvalidPropertyName()
{
VerifyConversionThrows(
inputCSharp: """
- #:property Name"=Value
+ #:property 123Name=Value
""",
expectedWildcardPattern: RunFileTests.DirectiveError("/app/Program.cs", 1, CliCommandStrings.PropertyDirectiveInvalidName, """
- The '"' character, hexadecimal value 0x22, cannot be included in a name.
+ Name cannot begin with the '1' character, hexadecimal value 0x31.
"""));
}
@@ -1198,11 +1199,14 @@ public void Directives_Escaping()
VerifyConversion(
inputCSharp: """
#:property Prop=
- #:sdk @="<>test
- #:package @="<>test
+ #:sdk @="<>te'st
+ #:package @="<>te'st
+ #:property Pro'p=Single'
+ #:property Prop2=\"Value\"
+ #:property Prop3='Value'
""",
expectedProject: $"""
-
+
Exe
@@ -1212,16 +1216,29 @@ public void Directives_Escaping()
true
true
<test">
+ \"Value\"
+ 'Value'
-
+
""",
- expectedCSharp: "");
+ expectedCSharp: """
+ #:property Pro'p=Single'
+
+ """,
+ expectedErrors:
+ [
+ (1, CliCommandStrings.QuoteInDirective),
+ (2, CliCommandStrings.QuoteInDirective),
+ (3, CliCommandStrings.QuoteInDirective),
+ (4, string.Format(CliCommandStrings.PropertyDirectiveInvalidName, "The ''' character, hexadecimal value 0x27, cannot be included in a name.")),
+ (5, CliCommandStrings.QuoteInDirective),
+ ]);
}
[Fact]
@@ -1257,7 +1274,11 @@ public void Directives_Whitespace()
# ! /test
#! /program x
# :property Name=Value
- """);
+ """,
+ expectedErrors:
+ [
+ (3, CliCommandStrings.QuoteInDirective),
+ ]);
}
[Fact]
@@ -1548,10 +1569,15 @@ public void Directives_VersionedSdkFirst()
""");
}
- private static void Convert(string inputCSharp, out string actualProject, out string? actualCSharp, bool force, string? filePath)
+ private const string programPath = "/app/Program.cs";
+
+ private static void Convert(string inputCSharp, out string actualProject, out string? actualCSharp, bool force, string? filePath,
+ bool collectDiagnostics, out ImmutableArray.Builder? actualDiagnostics)
{
- var sourceFile = new SourceFile(filePath ?? "/app/Program.cs", SourceText.From(inputCSharp, Encoding.UTF8));
- var directives = VirtualProjectBuildingCommand.FindDirectives(sourceFile, reportAllErrors: !force, DiagnosticBag.ThrowOnFirst());
+ var sourceFile = new SourceFile(filePath ?? programPath, SourceText.From(inputCSharp, Encoding.UTF8));
+ actualDiagnostics = null;
+ var diagnosticBag = collectDiagnostics ? DiagnosticBag.Collect(out actualDiagnostics) : DiagnosticBag.ThrowOnFirst();
+ var directives = VirtualProjectBuildingCommand.FindDirectives(sourceFile, reportAllErrors: !force, diagnosticBag);
var projectWriter = new StringWriter();
VirtualProjectBuildingCommand.WriteProjectFile(projectWriter, directives, isVirtualProject: false);
actualProject = projectWriter.ToString();
@@ -1561,25 +1587,43 @@ private static void Convert(string inputCSharp, out string actualProject, out st
///
/// means the conversion should not touch the C# content.
///
- private static void VerifyConversion(string inputCSharp, string expectedProject, string? expectedCSharp, bool force = false, string? filePath = null)
+ private static void VerifyConversion(string inputCSharp, string expectedProject, string? expectedCSharp, bool force = false, string? filePath = null,
+ IEnumerable<(int LineNumber, string Message)>? expectedErrors = null)
{
- Convert(inputCSharp, out var actualProject, out var actualCSharp, force: force, filePath: filePath);
+ Convert(inputCSharp, out var actualProject, out var actualCSharp, force: force, filePath: filePath,
+ collectDiagnostics: expectedErrors != null, out var actualDiagnostics);
actualProject.Should().Be(expectedProject);
actualCSharp.Should().Be(expectedCSharp);
+ VerifyErrors(actualDiagnostics, expectedErrors);
}
private static void VerifyConversionThrows(string inputCSharp, string expectedWildcardPattern)
{
- var convert = () => Convert(inputCSharp, out _, out _, force: false, filePath: null);
+ var convert = () => Convert(inputCSharp, out _, out _, force: false, filePath: null, collectDiagnostics: false, out _);
convert.Should().Throw().WithMessage(expectedWildcardPattern);
}
private static void VerifyDirectiveConversionErrors(string inputCSharp, IEnumerable<(int LineNumber, string Message)> expectedErrors)
{
- var programPath = "/app/Program.cs";
var sourceFile = new SourceFile(programPath, SourceText.From(inputCSharp, Encoding.UTF8));
VirtualProjectBuildingCommand.FindDirectives(sourceFile, reportAllErrors: true, DiagnosticBag.Collect(out var diagnostics));
- Assert.All(diagnostics, d => { Assert.Equal(programPath, d.Location.Path); });
- diagnostics.Select(d => (d.Location.Span.Start.Line + 1, d.Message)).Should().BeEquivalentTo(expectedErrors);
+ VerifyErrors(diagnostics, expectedErrors);
+ }
+
+ private static void VerifyErrors(ImmutableArray.Builder? actual, IEnumerable<(int LineNumber, string Message)>? expected)
+ {
+ if (actual is null)
+ {
+ Assert.Null(expected);
+ }
+ else if (expected is null)
+ {
+ Assert.Null(actual);
+ }
+ else
+ {
+ Assert.All(actual, d => { Assert.Equal(programPath, d.Location.Path); });
+ actual.Select(d => (d.Location.Span.Start.Line + 1, d.Message)).Should().BeEquivalentTo(expected);
+ }
}
}