I have found a bug in the MMM 1.0 RC 5.0 FOMod script. Starting on line 657:
string file = dataFilesToInstall[i];this._form.Invoke(new MethodInvoker(delegate(){ string temp = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); TextRenderer.MeasureText(temp, this.uxFilename.Font, this.uxFilename.Size, TextFormatFlags.ModifyString | TextFormatFlags.PathEllipsis); this.uxFilename.Text = temp;}));InstallFileFromFomod(dataFilesToInstall[i]);
Because of how strings are handled in C#, and because
TextRenderer.MeasureText modifies the given text rather than creating a new string, if the call to
TextRenderer.MeasureText results in the string being changed, then the call to
InstallFileFromFomod may be passed the modified string. Becaused the modified string will not point to a real file, the call to
InstallFileFromFomod will fail (silently in this case as you do not check the success of the call).
To be more precise, the above code snippet will cause problems if the original file name does not contain
Path.AltDirectorySeparatorChar characters. If the original file name
does not contain
Path.AltDirectorySeparatorChar characters, then
string temp = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
will not create a new string as no replacement will be required, so
temp will point to the same string as
file which points to the same string as
dataFilesToInstall[ i]. Thus, if
TextRenderer.MeasureText alters the string, then
dataFilesToInstall[ i] will also be altered, resulting in a bad file name being passed to
InstallFileFromFomod.
Conversely, if the original file name
does contain
Path.AltDirectorySeparatorChar characters, then
string temp = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
will create a new string as a replacement will be required, so
temp will point to a new string. Thus, if
TextRenderer.MeasureText alters the string, then
dataFilesToInstall[ i] will not be altered, resulting in a valid file name being passed to
InstallFileFromFomod.
This has not caused any problems in FOMM thus far, as, by coincidence, FOMM has always returned paths containing
Path.AltDirectorySeparatorChar characters when
GetFomodFileList is called (which was done in your script to populate
dataFilesToInstall). As such,
string temp = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
has always created a new string, avoiding the bug. However, FOMM 0.12.x may no longer return paths containing
Path.AltDirectorySeparatorChar characters, thus raising the possibility of the bug described above where bad file names are passed to
InstallFileFromFomod.
The fix for this bug is to use a copy of the string when calling
TextRenderer.MeasureText so that any changes to the string are isolated, and
dataFilesToInstall[ i] will not ever be modified. The corrected code block is as follows:
string file = dataFilesToInstall[i];this._form.Invoke(new MethodInvoker(delegate(){ string temp = String.Copy(file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)); TextRenderer.MeasureText(temp, this.uxFilename.Font, this.uxFilename.Size, TextFormatFlags.ModifyString | TextFormatFlags.PathEllipsis); this.uxFilename.Text = temp;}));InstallFileFromFomod(dataFilesToInstall[i]);
Note that the only change is to line 660, which changed from:
string temp = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
to
string temp = String.Copy(file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
Further, note that the same change needs to be made to line 687.
If you have any questions, or require further clarification, please do not hesitate to contact me here, on sourceforge, or on the nexus.
[edit]
Martigen, I've noticed that your script is quite popular among mod authors. Do you have any idea of exactly how widespread it has become?
[/edit]