@joebigelow / wix-1 / commits / f99cd1b1

Support "==" as equality operator in preprocessor

Fixes 5880

Rob Mensching committed Mar 2, 2022 at 13:57 UTC f99cd1b1616909f0314504c9fdba836e162e1fa6
4 files changed +133 -3
src/wix/WixToolset.Core/Preprocessor.cs
+10 -3
@@ -185,6 +185,7 @@ namespace WixToolset.Core
185 }
186
187 if ("=" == operation ||
188 + "==" == operation ||
189 "!=" == operation ||
190 "<" == operation ||
191 "<=" == operation ||
@@ -885,6 +886,7 @@ namespace WixToolset.Core
886 // or end of string, whichever comes first
887 var space = expression.IndexOf(" ", StringComparison.Ordinal);
888 var equals = expression.IndexOf("=", StringComparison.Ordinal);
889 + var doubleEquals = expression.IndexOf("==", StringComparison.Ordinal);
890 var lessThan = expression.IndexOf("<", StringComparison.Ordinal);
891 var lessThanEquals = expression.IndexOf("<=", StringComparison.Ordinal);
892 var greaterThan = expression.IndexOf(">", StringComparison.Ordinal);
@@ -903,6 +905,11 @@ namespace WixToolset.Core
905 equals = Int32.MaxValue;
906 }
907
908 + if (doubleEquals == -1)
909 + {
910 + doubleEquals = Int32.MaxValue;
911 + }
912 +
913 if (lessThan == -1)
914 {
915 lessThan = Int32.MaxValue;
@@ -933,7 +940,7 @@ namespace WixToolset.Core
940 equalsNoCase = Int32.MaxValue;
941 }
942
936 - closingIndex = Math.Min(space, Math.Min(equals, Math.Min(lessThan, Math.Min(lessThanEquals, Math.Min(greaterThan, Math.Min(greaterThanEquals, Math.Min(equalsNoCase, notEquals)))))));
943 + closingIndex = Math.Min(space, Math.Min(equals, Math.Min(doubleEquals, Math.Min(lessThan, Math.Min(lessThanEquals, Math.Min(greaterThan, Math.Min(greaterThanEquals, Math.Min(equalsNoCase, notEquals))))))));
944
945 if (Int32.MaxValue == closingIndex)
946 {
@@ -944,7 +951,7 @@ namespace WixToolset.Core
951 if (0 == closingIndex)
952 {
953 // Length 2 operators
947 - if (closingIndex == lessThanEquals || closingIndex == greaterThanEquals || closingIndex == notEquals || closingIndex == equalsNoCase)
954 + if (closingIndex == doubleEquals || closingIndex == lessThanEquals || closingIndex == greaterThanEquals || closingIndex == notEquals || closingIndex == equalsNoCase)
955 {
956 closingIndex = 2;
957 }
@@ -1096,7 +1103,7 @@ namespace WixToolset.Core
1103 {
1104 leftValue = leftValue.Trim();
1105 rightValue = rightValue.Trim();
1099 - if ("=" == operation)
1106 + if ("=" == operation || "==" == operation)
1107 {
1108 if (leftValue == rightValue)
1109 {
src/wix/test/WixToolsetTest.Core/PreprocessorFixture.cs new
+79
@@ -0,0 +1,79 @@
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 +
3 +namespace WixToolsetTest.Core
4 +{
5 + using System;
6 + using System.IO;
7 + using System.Xml;
8 + using WixBuildTools.TestSupport;
9 + using WixToolset.Core;
10 + using WixToolset.Extensibility.Data;
11 + using WixToolset.Extensibility.Services;
12 + using Xunit;
13 +
14 + public class PreprocessorFixture
15 + {
16 + [Fact]
17 + public void CanPreprocessWithSingleEquals()
18 + {
19 + var input = String.Join(Environment.NewLine,
20 + "<Wix>",
21 + "<?define A=0?>",
22 + "<?if $(A)=\"0\" ?>",
23 + " <Package />",
24 + "<?endif?>",
25 + "</Wix>"
26 + );
27 + var expected = new[]
28 + {
29 + "<Wix>",
30 + " <Package />",
31 + "</Wix>"
32 + };
33 +
34 + var result = PreprocessFromString(input);
35 +
36 + var actual = result.Document.ToString().Split("\r\n");
37 + WixAssert.CompareLineByLine(expected, actual);
38 + }
39 +
40 + [Fact]
41 + public void CanPreprocessWithDoubleEquals()
42 + {
43 + var input = String.Join(Environment.NewLine,
44 + "<Wix>",
45 + "<?define A=0?>",
46 + "<?if $(A)==\"0\" ?>",
47 + " <Fragment />",
48 + "<?endif?>",
49 + "</Wix>"
50 + );
51 + var expected = new[]
52 + {
53 + "<Wix>",
54 + " <Fragment />",
55 + "</Wix>"
56 + };
57 +
58 + var result = PreprocessFromString(input);
59 +
60 + var actual = result.Document.ToString().Split("\r\n");
61 + WixAssert.CompareLineByLine(expected, actual);
62 + }
63 +
64 + private static IPreprocessResult PreprocessFromString(string xml)
65 + {
66 + using var stringReader = new StringReader(xml);
67 + using var xmlReader = XmlReader.Create(stringReader);
68 +
69 + var sp = WixToolsetServiceProviderFactory.CreateServiceProvider();
70 +
71 + var context = sp.GetService<IPreprocessContext>();
72 + context.SourcePath = @"path\provided\for\testing\purposes\only.wxs";
73 +
74 + var preprocessor = context.ServiceProvider.GetService<IPreprocessor>();
75 + var result = preprocessor.Preprocess(context, xmlReader);
76 + return result;
77 + }
78 + }
79 +}
src/wix/test/WixToolsetTest.Core/WixToolsetTest.Core.csproj new
+25
@@ -0,0 +1,25 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3 +
4 +<Project Sdk="Microsoft.NET.Sdk">
5 + <PropertyGroup>
6 + <TargetFramework>netcoreapp3.1</TargetFramework>
7 + <IsPackable>false</IsPackable>
8 + <DebugType>embedded</DebugType>
9 + <SignOutput>false</SignOutput>
10 + </PropertyGroup>
11 +
12 + <ItemGroup>
13 + <ProjectReference Include="..\..\WixToolset.Core\WixToolset.Core.csproj" />
14 + </ItemGroup>
15 +
16 + <ItemGroup>
17 + <PackageReference Include="WixBuildTools.TestSupport" />
18 + </ItemGroup>
19 +
20 + <ItemGroup>
21 + <PackageReference Include="Microsoft.NET.Test.Sdk" />
22 + <PackageReference Include="xunit" />
23 + <PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" />
24 + </ItemGroup>
25 +</Project>
src/wix/wix.sln
+19
@@ -52,6 +52,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.BuildTasks",
52 EndProject
53 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pack-wix", "pack-wix\pack-wix.csproj", "{CE489499-60E1-4883-B72A-CA8F95DBA073}"
54 EndProject
55 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Core", "test\WixToolsetTest.Core\WixToolsetTest.Core.csproj", "{392817AE-4493-4BED-A7FD-2399379E1B1C}"
56 +EndProject
57 Global
58 GlobalSection(SolutionConfigurationPlatforms) = preSolution
59 Debug|Any CPU = Debug|Any CPU
@@ -448,6 +450,22 @@ Global
450 {CE489499-60E1-4883-B72A-CA8F95DBA073}.Release|x64.Build.0 = Release|Any CPU
451 {CE489499-60E1-4883-B72A-CA8F95DBA073}.Release|x86.ActiveCfg = Release|Any CPU
452 {CE489499-60E1-4883-B72A-CA8F95DBA073}.Release|x86.Build.0 = Release|Any CPU
453 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
454 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
455 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|ARM64.ActiveCfg = Debug|Any CPU
456 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|ARM64.Build.0 = Debug|Any CPU
457 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|x64.ActiveCfg = Debug|Any CPU
458 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|x64.Build.0 = Debug|Any CPU
459 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|x86.ActiveCfg = Debug|Any CPU
460 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Debug|x86.Build.0 = Debug|Any CPU
461 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
462 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|Any CPU.Build.0 = Release|Any CPU
463 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|ARM64.ActiveCfg = Release|Any CPU
464 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|ARM64.Build.0 = Release|Any CPU
465 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|x64.ActiveCfg = Release|Any CPU
466 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|x64.Build.0 = Release|Any CPU
467 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|x86.ActiveCfg = Release|Any CPU
468 + {392817AE-4493-4BED-A7FD-2399379E1B1C}.Release|x86.Build.0 = Release|Any CPU
469 EndGlobalSection
470 GlobalSection(SolutionProperties) = preSolution
471 HideSolutionNode = FALSE
@@ -463,6 +481,7 @@ Global
481 {9D788104-2636-4E4C-891C-08FF05FEC31E} = {1284331E-BC6C-426D-AAAF-140C0174F875}
482 {93645356-5D5F-45DE-AC7F-252D35E1ACE5} = {1284331E-BC6C-426D-AAAF-140C0174F875}
483 {A05698E0-30D9-4B36-8F3B-585A99D67118} = {1284331E-BC6C-426D-AAAF-140C0174F875}
484 + {392817AE-4493-4BED-A7FD-2399379E1B1C} = {1284331E-BC6C-426D-AAAF-140C0174F875}
485 EndGlobalSection
486 GlobalSection(ExtensibilityGlobals) = postSolution
487 SolutionGuid = {BB8820D5-723D-426D-B4A0-4D221603C5FA}