An odd problem when switching frameworks

At my day job, I write software, mainly (at least in the past few years) using C#. I recently switched the framework version of one product from .NET 3.0 to .NET 4.5. When I did so, some code which had been working suddenly failed in a quite spectacular manner. The code in question was placing a call to the unmanaged¬†PathCompactPathEx¬†function (which truncates long pathnames by removing parts of the path and replacing them with …), which was causing the entire application to crash.

After scratching my head for a few seconds, it occurred to me that when the StringBuilder was initialized, its initial capacity was not being set explicitly. I don’t know for sure, but I suspect that because of that oversight there is a good chance that the unmanaged code was overflowing a buffer somewhere.

The fixed code is shown below for anyone who may want it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);
 
/// <summary>
/// Reduces a long path (if necessary) such that its length is less than or equal to the specified maximum length.
/// </summary>
/// <param name="path">The initial (full) path that may need modification.</param>
/// <param name="maximumLength">The maximum length that the modified path can occupy</param>
/// <returns>The path, truncated as necessary</returns>
public string CompactPathToLength(string path, int maximumLength)
{
var sb = new StringBuilder(maximumLength);
PathCompactPathEx(sb, path, maximumLength, 0);
return sb.ToString();
}
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);

/// <summary>
/// Reduces a long path (if necessary) such that its length is less than or equal to the specified maximum length.
/// </summary>
/// <param name="path">The initial (full) path that may need modification.</param>
/// <param name="maximumLength">The maximum length that the modified path can occupy</param>
/// <returns>The path, truncated as necessary</returns>
public string CompactPathToLength(string path, int maximumLength)
{
var sb = new StringBuilder(maximumLength);
PathCompactPathEx(sb, path, maximumLength, 0);
return sb.ToString();
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Protected by WP Anti Spam