aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-01-05 15:13:37 -0800
committerRob Mensching <rob@firegiant.com>2021-01-05 23:18:34 -0800
commit0d1851c79901ba6ddbba9bb63f758760fe5be994 (patch)
tree2ccb45459fe4290e9c3fb4ad698c20f9cd55203d
parentb00c72ed0ef19d2e46f60361fa06821b0bd5ec94 (diff)
downloadwix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.gz
wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.tar.bz2
wix-0d1851c79901ba6ddbba9bb63f758760fe5be994.zip
Fix handling of duplicate directories
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs16
-rw-r--r--src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs12
-rw-r--r--src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs6
-rw-r--r--src/WixToolset.Core/Link/ResolveReferencesCommand.cs4
-rw-r--r--src/WixToolset.Core/Linker.cs5
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs39
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs25
7 files changed, 92 insertions, 15 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs
index 4597639b..ee3bcc91 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/AddRequiredStandardDirectories.cs
@@ -27,7 +27,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
27 public void Execute() 27 public void Execute()
28 { 28 {
29 var directories = this.Section.Symbols.OfType<DirectorySymbol>().ToList(); 29 var directories = this.Section.Symbols.OfType<DirectorySymbol>().ToList();
30 var directoriesById = directories.ToDictionary(d => d.Id.Id); 30 var directoryIds = new SortedSet<string>(directories.Select(d => d.Id.Id));
31 31
32 foreach (var directory in directories) 32 foreach (var directory in directories)
33 { 33 {
@@ -42,20 +42,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind
42 } 42 }
43 else 43 else
44 { 44 {
45 this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, directory.SourceLineNumbers); 45 this.EnsureStandardDirectoryAdded(directoryIds, parentDirectoryId, directory.SourceLineNumbers);
46 } 46 }
47 } 47 }
48 48
49 if (!directoriesById.ContainsKey("TARGETDIR") && WindowsInstallerStandard.TryGetStandardDirectory("TARGETDIR", out var targetDir)) 49 if (!directoryIds.Contains("TARGETDIR") && WindowsInstallerStandard.TryGetStandardDirectory("TARGETDIR", out var targetDir))
50 { 50 {
51 directoriesById.Add(targetDir.Id.Id, targetDir); 51 directoryIds.Add(targetDir.Id.Id);
52 this.Section.AddSymbol(targetDir); 52 this.Section.AddSymbol(targetDir);
53 } 53 }
54 } 54 }
55 55
56 private void EnsureStandardDirectoryAdded(Dictionary<string, DirectorySymbol> directoriesById, string directoryId, SourceLineNumber sourceLineNumbers) 56 private void EnsureStandardDirectoryAdded(ISet<string> directoryIds, string directoryId, SourceLineNumber sourceLineNumbers)
57 { 57 {
58 if (!directoriesById.ContainsKey(directoryId) && WindowsInstallerStandard.TryGetStandardDirectory(directoryId, out var standardDirectory)) 58 if (!directoryIds.Contains(directoryId) && WindowsInstallerStandard.TryGetStandardDirectory(directoryId, out var standardDirectory))
59 { 59 {
60 var parentDirectoryId = this.GetStandardDirectoryParent(directoryId); 60 var parentDirectoryId = this.GetStandardDirectoryParent(directoryId);
61 61
@@ -65,12 +65,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
65 ParentDirectoryRef = parentDirectoryId, 65 ParentDirectoryRef = parentDirectoryId,
66 }; 66 };
67 67
68 directoriesById.Add(directory.Id.Id, directory); 68 directoryIds.Add(directory.Id.Id);
69 this.Section.AddSymbol(directory); 69 this.Section.AddSymbol(directory);
70 70
71 if (!String.IsNullOrEmpty(parentDirectoryId)) 71 if (!String.IsNullOrEmpty(parentDirectoryId))
72 { 72 {
73 this.EnsureStandardDirectoryAdded(directoriesById, parentDirectoryId, sourceLineNumbers); 73 this.EnsureStandardDirectoryAdded(directoryIds, parentDirectoryId, sourceLineNumbers);
74 } 74 }
75 } 75 }
76 } 76 }
diff --git a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
index 1c2ca8eb..a4b2bee3 100644
--- a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
+++ b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
@@ -38,10 +38,17 @@ namespace WixToolset.Core.Link
38 /// </summary> 38 /// </summary>
39 public IEnumerable<SymbolWithSection> PossibleConflicts { get; private set; } 39 public IEnumerable<SymbolWithSection> PossibleConflicts { get; private set; }
40 40
41 /// <summary>
42 /// Gets the collection of redundant symbols that should not be included
43 /// in the final output.
44 /// </summary>
45 public ISet<IntermediateSymbol> RedundantSymbols { get; private set; }
46
41 public void Execute() 47 public void Execute()
42 { 48 {
43 var symbolsByName = new Dictionary<string, SymbolWithSection>(); 49 var symbolsByName = new Dictionary<string, SymbolWithSection>();
44 var possibleConflicts = new HashSet<SymbolWithSection>(); 50 var possibleConflicts = new HashSet<SymbolWithSection>();
51 var redundantSymbols = new HashSet<IntermediateSymbol>();
45 52
46 if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType)) 53 if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType))
47 { 54 {
@@ -91,13 +98,13 @@ namespace WixToolset.Core.Link
91 // Ensure identical symbol's symbol is marked redundant to ensure (should the symbol be 98 // Ensure identical symbol's symbol is marked redundant to ensure (should the symbol be
92 // referenced into the final output) it will not add duplicate primary keys during 99 // referenced into the final output) it will not add duplicate primary keys during
93 // the .IDT importing. 100 // the .IDT importing.
94 //symbol.Row.Redundant = true; - TODO: remove this
95 existingSymbol.AddRedundant(symbolWithSection); 101 existingSymbol.AddRedundant(symbolWithSection);
102 redundantSymbols.Add(symbolWithSection.Symbol);
96 } 103 }
97 else 104 else
98 { 105 {
99 existingSymbol.AddPossibleConflict(symbolWithSection); 106 existingSymbol.AddPossibleConflict(symbolWithSection);
100 possibleConflicts.Add(existingSymbol); 107 possibleConflicts.Add(symbolWithSection);
101 } 108 }
102 } 109 }
103 } 110 }
@@ -105,6 +112,7 @@ namespace WixToolset.Core.Link
105 112
106 this.SymbolsByName = symbolsByName; 113 this.SymbolsByName = symbolsByName;
107 this.PossibleConflicts = possibleConflicts; 114 this.PossibleConflicts = possibleConflicts;
115 this.RedundantSymbols = redundantSymbols;
108 } 116 }
109 } 117 }
110} 118}
diff --git a/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs b/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs
index db53f1ce..cbf48abe 100644
--- a/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs
+++ b/src/WixToolset.Core/Link/IntermediateSymbolExtensions.cs
@@ -1,4 +1,4 @@
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. 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 2
3namespace WixToolset.Core.Link 3namespace WixToolset.Core.Link
4{ 4{
@@ -9,10 +9,10 @@ namespace WixToolset.Core.Link
9 public static bool IsIdentical(this IntermediateSymbol first, IntermediateSymbol second) 9 public static bool IsIdentical(this IntermediateSymbol first, IntermediateSymbol second)
10 { 10 {
11 var identical = (first.Definition.Type == second.Definition.Type && 11 var identical = (first.Definition.Type == second.Definition.Type &&
12 first.Definition.Name == second.Definition.Name && 12 (first.Definition.Type != SymbolDefinitionType.MustBeFromAnExtension || first.Definition.Name == second.Definition.Name) &&
13 first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length); 13 first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length);
14 14
15 for (int i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i) 15 for (var i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i)
16 { 16 {
17 var firstField = first[i]; 17 var firstField = first[i];
18 var secondField = second[i]; 18 var secondField = second[i];
diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
index 90b61e8b..2bdd5646 100644
--- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
+++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
@@ -170,9 +170,9 @@ namespace WixToolset.Core.Link
170 case AccessModifier.Public: 170 case AccessModifier.Public:
171 return true; 171 return true;
172 case AccessModifier.Internal: 172 case AccessModifier.Internal:
173 return symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId) || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId.Equals(referencingSection.LibraryId)); 173 return symbolWithSection.Section.CompilationId == referencingSection.CompilationId || (null != symbolWithSection.Section.LibraryId && symbolWithSection.Section.LibraryId == referencingSection.LibraryId);
174 case AccessModifier.Protected: 174 case AccessModifier.Protected:
175 return symbolWithSection.Section.CompilationId.Equals(referencingSection.CompilationId); 175 return symbolWithSection.Section.CompilationId == referencingSection.CompilationId;
176 case AccessModifier.Private: 176 case AccessModifier.Private:
177 return referencingSection == symbolWithSection.Section; 177 return referencingSection == symbolWithSection.Section;
178 default: 178 default:
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs
index e9f9554c..431ba4c7 100644
--- a/src/WixToolset.Core/Linker.cs
+++ b/src/WixToolset.Core/Linker.cs
@@ -226,6 +226,11 @@ namespace WixToolset.Core
226 226
227 foreach (var symbol in section.Symbols) 227 foreach (var symbol in section.Symbols)
228 { 228 {
229 if (find.RedundantSymbols.Contains(symbol))
230 {
231 continue;
232 }
233
229 var copySymbol = true; // by default, copy symbols. 234 var copySymbol = true; // by default, copy symbols.
230 235
231 // handle special tables 236 // handle special tables
diff --git a/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs b/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs
index 83f2f2bb..2d6e4802 100644
--- a/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs
@@ -85,5 +85,44 @@ namespace WixToolsetTest.CoreIntegration
85 }, dirSymbols.Select(d => d.Id.Id).ToArray()); 85 }, dirSymbols.Select(d => d.Id.Id).ToArray());
86 } 86 }
87 } 87 }
88
89 [Fact]
90 public void CanGetDuplicateDir()
91 {
92 var folder = TestData.Get(@"TestData");
93
94 using (var fs = new DisposableFileSystem())
95 {
96 var baseFolder = fs.GetFolder();
97 var intermediateFolder = Path.Combine(baseFolder, "obj");
98 var msiPath = Path.Combine(baseFolder, @"bin\test.msi");
99
100 var result = WixRunner.Execute(new[]
101 {
102 "build",
103 "-arch", "x64",
104 Path.Combine(folder, "DuplicateDir", "DuplicateDir.wxs"),
105 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
106 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
107 "-intermediateFolder", intermediateFolder,
108 "-o", msiPath
109 });
110
111 result.AssertSuccess();
112
113 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
114 var section = intermediate.Sections.Single();
115
116 var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList();
117 Assert.Equal(new[]
118 {
119 "dirZsSsu81KcG46xXTwc4mTSZO5Zx4",
120 "INSTALLFOLDER",
121 "ProgramFiles6432Folder",
122 "ProgramFiles64Folder",
123 "TARGETDIR"
124 }, dirSymbols.Select(d => d.Id.Id).ToArray());
125 }
126 }
88 } 127 }
89} 128}
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs
new file mode 100644
index 00000000..ffee969d
--- /dev/null
+++ b/src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs
@@ -0,0 +1,25 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <ComponentGroup Id="ProductComponents">
5 <ComponentGroupRef Id="GroupA" />
6 <ComponentGroupRef Id="GroupB" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <ComponentGroup Id="GroupA" Directory="INSTALLFOLDER:\dupe">
12 <Component>
13 <File Name="a.txt" Source="test.txt" />
14 </Component>
15 </ComponentGroup>
16 </Fragment>
17
18 <Fragment>
19 <ComponentGroup Id="GroupB" Directory="INSTALLFOLDER:\dupe">
20 <Component>
21 <File Name="b.txt" Source="test.txt" />
22 </Component>
23 </ComponentGroup>
24 </Fragment>
25</Wix>