@joebigelow / wix / commits / f4242573

Re-resolve binary .wixlibs with defaulted embedded files

Fixes wixtoolset/issues#6376

Rob Mensching committed Mar 25, 2021 at 22:03 UTC f4242573301899109186cdff6694a289ee27d794
2 files changed +92 -75
src/WixToolset.Core/Bind/ResolveFieldsCommand.cs
+91 -74
@@ -82,8 +82,6 @@ namespace WixToolset.Core.Bind
82 }
83 }
84
85 - var isDefault = true;
86 -
85 // Check to make sure we're in a scenario where we can handle variable resolution.
86 if (null != delayedFields)
87 {
@@ -103,8 +101,6 @@ namespace WixToolset.Core.Bind
101 {
102 delayedFields.Add(new DelayedField(symbol, field));
103 }
106 -
107 - isDefault = resolution.IsDefault;
104 }
105 }
106 }
@@ -118,76 +114,7 @@ namespace WixToolset.Core.Bind
114 // Resolve file paths
115 if (fieldType == IntermediateFieldType.Path)
116 {
121 - var objectField = field.AsPath();
122 -
123 -#if TODO_PATCHING
124 - // Skip file resolution if the file is to be deleted.
125 - if (RowOperation.Delete == symbol.Operation)
126 - {
127 - continue;
128 - }
129 -#endif
130 -
131 - // File is embedded and path to it was not modified above.
132 - if (isDefault && objectField.Embed)
133 - {
134 - var extractPath = this.FilesWithEmbeddedFiles.AddEmbeddedFileToExtract(objectField.BaseUri, objectField.Path, this.IntermediateFolder);
135 -
136 - // Set the path to the embedded file once where it will be extracted.
137 - field.Set(extractPath);
138 - }
139 - else if (null != objectField.Path) // non-compressed file (or localized value)
140 - {
141 - try
142 - {
143 - if (!this.BuildingPatch) // Normal binding for non-Patch scenario such as link (light.exe)
144 - {
145 -#if TODO_PATCHING
146 - // keep a copy of the un-resolved data for future replay. This will be saved into wixpdb file
147 - if (null == objectField.UnresolvedData)
148 - {
149 - objectField.UnresolvedData = (string)objectField.Data;
150 - }
151 -#endif
152 -
153 - // resolve the path to the file
154 - var value = fileResolver.ResolveFile(objectField.Path, symbol.Definition, symbol.SourceLineNumbers, BindStage.Normal);
155 - field.Set(value);
156 - }
157 - else if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated) // Normal binding for Patch Scenario (normal patch, no re-basing logic)
158 - {
159 - // resolve the path to the file
160 - var value = fileResolver.ResolveFile(objectField.Path, symbol.Definition, symbol.SourceLineNumbers, BindStage.Normal);
161 - field.Set(value);
162 - }
163 -#if TODO_PATCHING
164 - else // Re-base binding path scenario caused by pyro.exe -bt -bu
165 - {
166 - // by default, use the resolved Data for file lookup
167 - string filePathToResolve = (string)objectField.Data;
168 -
169 - // if -bu is used in pyro command, this condition holds true and the tool
170 - // will use pre-resolved source for new wixpdb file
171 - if (fileResolver.RebaseUpdated)
172 - {
173 - // try to use the unResolved Source if it exists.
174 - // New version of wixpdb file keeps a copy of pre-resolved Source. i.e. !(bindpath.test)\foo.dll
175 - // Old version of winpdb file does not contain this attribute and the value is null.
176 - if (null != objectField.UnresolvedData)
177 - {
178 - filePathToResolve = objectField.UnresolvedData;
179 - }
180 - }
181 -
182 - objectField.Data = fileResolver.ResolveFile(filePathToResolve, symbol.Definition.Name, symbol.SourceLineNumbers, BindStage.Updated);
183 - }
184 -#endif
185 - }
186 - catch (WixException e)
187 - {
188 - this.Messaging.Write(e.Error);
189 - }
190 - }
117 + this.ResolvePathField(fileResolver, symbol, field);
118
119 #if TODO_PATCHING
120 if (null != objectField.PreviousData)
@@ -255,5 +182,95 @@ namespace WixToolset.Core.Bind
182
183 this.DelayedFields = delayedFields;
184 }
185 +
186 + private void ResolvePathField(FileResolver fileResolver, IntermediateSymbol symbol, IntermediateField field)
187 + {
188 + var fieldValue = field.AsPath();
189 + var originalFieldPath = fieldValue.Path;
190 +
191 +#if TODO_PATCHING
192 + // Skip file resolution if the file is to be deleted.
193 + if (RowOperation.Delete == symbol.Operation)
194 + {
195 + continue;
196 + }
197 +#endif
198 +
199 + // If the file is embedded and if the previous value has a bind variable in the path
200 + // which gets modified by resolving the previous value again then switch to that newly
201 + // resolved path instead of using the embedded file.
202 + if (fieldValue.Embed && field.PreviousValue != null)
203 + {
204 + var resolution = this.VariableResolver.ResolveVariables(symbol.SourceLineNumbers, field.PreviousValue.AsString(), errorOnUnknown: false);
205 +
206 + if (resolution.UpdatedValue && !resolution.IsDefault)
207 + {
208 + fieldValue = new IntermediateFieldPathValue { Path = resolution.Value };
209 + }
210 + }
211 +
212 + // If we're still using the embedded file.
213 + if (fieldValue.Embed)
214 + {
215 + // Set the path to the embedded file once where it will be extracted.
216 + var extractPath = this.FilesWithEmbeddedFiles.AddEmbeddedFileToExtract(fieldValue.BaseUri, fieldValue.Path, this.IntermediateFolder);
217 +
218 + field.Set(extractPath);
219 + }
220 + else if (fieldValue.Path != null)
221 + {
222 + try
223 + {
224 + var resolvedPath = fieldValue.Path;
225 +
226 + if (!this.BuildingPatch) // Normal binding for non-Patch scenario such as link (light.exe)
227 + {
228 +#if TODO_PATCHING
229 + // keep a copy of the un-resolved data for future replay. This will be saved into wixpdb file
230 + if (null == objectField.UnresolvedData)
231 + {
232 + objectField.UnresolvedData = (string)objectField.Data;
233 + }
234 +#endif
235 + resolvedPath = fileResolver.ResolveFile(fieldValue.Path, symbol.Definition, symbol.SourceLineNumbers, BindStage.Normal);
236 + }
237 + else if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated) // Normal binding for Patch Scenario (normal patch, no re-basing logic)
238 + {
239 + resolvedPath = fileResolver.ResolveFile(fieldValue.Path, symbol.Definition, symbol.SourceLineNumbers, BindStage.Normal);
240 + }
241 +#if TODO_PATCHING
242 + else // Re-base binding path scenario caused by pyro.exe -bt -bu
243 + {
244 + // by default, use the resolved Data for file lookup
245 + string filePathToResolve = (string)objectField.Data;
246 +
247 + // if -bu is used in pyro command, this condition holds true and the tool
248 + // will use pre-resolved source for new wixpdb file
249 + if (fileResolver.RebaseUpdated)
250 + {
251 + // try to use the unResolved Source if it exists.
252 + // New version of wixpdb file keeps a copy of pre-resolved Source. i.e. !(bindpath.test)\foo.dll
253 + // Old version of winpdb file does not contain this attribute and the value is null.
254 + if (null != objectField.UnresolvedData)
255 + {
256 + filePathToResolve = objectField.UnresolvedData;
257 + }
258 + }
259 +
260 + objectField.Data = fileResolver.ResolveFile(filePathToResolve, symbol.Definition.Name, symbol.SourceLineNumbers, BindStage.Updated);
261 + }
262 +#endif
263 +
264 + if (!String.Equals(originalFieldPath, resolvedPath, StringComparison.OrdinalIgnoreCase))
265 + {
266 + field.Set(resolvedPath);
267 + }
268 + }
269 + catch (WixException e)
270 + {
271 + this.Messaging.Write(e.Error);
272 + }
273 + }
274 + }
275 }
276 }
src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
+1 -1
@@ -144,7 +144,7 @@ namespace WixToolsetTest.CoreIntegration
144 }
145 }
146
147 - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6376")]
147 + [Fact]
148 public void CanOverridePathWixVariable()
149 {
150 var folder = TestData.Get(@"TestData\WixVariableOverride");