U4-10301 Change the PluginManager hash to use more reliable and consistent hashes
This commit is contained in:
@@ -44,8 +44,8 @@ namespace Umbraco.Core
|
||||
private readonly object _typesLock = new object();
|
||||
private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>();
|
||||
|
||||
private long _cachedAssembliesHash = -1;
|
||||
private long _currentAssembliesHash = -1;
|
||||
private string _cachedAssembliesHash = null;
|
||||
private string _currentAssembliesHash = null;
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
private bool _reportedChange;
|
||||
|
||||
@@ -75,9 +75,9 @@ namespace Umbraco.Core
|
||||
|
||||
if (detectChanges)
|
||||
{
|
||||
//first check if the cached hash is 0, if it is then we ne
|
||||
//first check if the cached hash is string.Empty, if it is then we need
|
||||
//do the check if they've changed
|
||||
RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == 0;
|
||||
RequiresRescanning = (CachedAssembliesHash != CurrentAssembliesHash) || CachedAssembliesHash == string.Empty;
|
||||
//if they have changed, we need to write the new file
|
||||
if (RequiresRescanning)
|
||||
{
|
||||
@@ -180,23 +180,20 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Gets the currently cached hash value of the scanned assemblies.
|
||||
/// </summary>
|
||||
/// <value>The cached hash value, or 0 if no cache is found.</value>
|
||||
internal long CachedAssembliesHash
|
||||
/// <value>The cached hash value, or string.Empty if no cache is found.</value>
|
||||
internal string CachedAssembliesHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cachedAssembliesHash != -1)
|
||||
if (_cachedAssembliesHash != null)
|
||||
return _cachedAssembliesHash;
|
||||
|
||||
var filePath = GetPluginHashFilePath();
|
||||
if (File.Exists(filePath) == false) return 0;
|
||||
if (File.Exists(filePath) == false) return string.Empty;
|
||||
|
||||
var hash = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
|
||||
long val;
|
||||
if (long.TryParse(hash, out val) == false) return 0;
|
||||
|
||||
_cachedAssembliesHash = val;
|
||||
|
||||
_cachedAssembliesHash = hash;
|
||||
return _cachedAssembliesHash;
|
||||
}
|
||||
}
|
||||
@@ -205,11 +202,11 @@ namespace Umbraco.Core
|
||||
/// Gets the current assemblies hash based on creating a hash from the assemblies in various places.
|
||||
/// </summary>
|
||||
/// <value>The current hash.</value>
|
||||
internal long CurrentAssembliesHash
|
||||
internal string CurrentAssembliesHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_currentAssembliesHash != -1)
|
||||
if (_currentAssembliesHash != null)
|
||||
return _currentAssembliesHash;
|
||||
|
||||
_currentAssembliesHash = GetFileHash(new List<Tuple<FileSystemInfo, bool>>
|
||||
@@ -245,41 +242,40 @@ namespace Umbraco.Core
|
||||
/// <returns>The hash.</returns>
|
||||
/// <remarks>Each file is a tuple containing the FileInfo object and a boolean which indicates whether to hash the
|
||||
/// file properties (false) or the file contents (true).</remarks>
|
||||
internal static long GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, ProfilingLogger logger)
|
||||
internal static string GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, ProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<PluginManager>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
var hashCombiner = new HashCodeCombiner();
|
||||
|
||||
{
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
var uniqContent = new HashSet<string>();
|
||||
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
var info = fileOrFolder.Item1;
|
||||
if (fileOrFolder.Item2)
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
{
|
||||
// add each unique file's contents to the hash
|
||||
// normalize the content for cr/lf and case-sensitivity
|
||||
|
||||
if (uniqContent.Contains(info.FullName)) continue;
|
||||
uniqContent.Add(info.FullName);
|
||||
if (File.Exists(info.FullName) == false) continue;
|
||||
var content = RemoveCrLf(File.ReadAllText(info.FullName));
|
||||
hashCombiner.AddCaseInsensitiveString(content);
|
||||
var info = fileOrFolder.Item1;
|
||||
if (fileOrFolder.Item2)
|
||||
{
|
||||
// add each unique file's contents to the hash
|
||||
// normalize the content for cr/lf and case-sensitivity
|
||||
if (uniqContent.Add(info.FullName))
|
||||
{
|
||||
if (File.Exists(info.FullName) == false) continue;
|
||||
var content = RemoveCrLf(File.ReadAllText(info.FullName));
|
||||
generator.AddCaseInsensitiveString(content);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add each unique folder/file to the hash
|
||||
if (uniqInfos.Add(info.FullName))
|
||||
{
|
||||
generator.AddFileSystemItem(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add each unique folder/file to the hash
|
||||
|
||||
if (uniqInfos.Contains(info.FullName)) continue;
|
||||
uniqInfos.Add(info.FullName);
|
||||
hashCombiner.AddFileSystemItem(info);
|
||||
}
|
||||
}
|
||||
|
||||
return ConvertHashToInt64(hashCombiner.GetCombinedHashCode());
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,34 +299,25 @@ namespace Umbraco.Core
|
||||
/// <param name="filesAndFolders">A collection of files.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <returns>The hash.</returns>
|
||||
internal static long GetFileHash(IEnumerable<FileSystemInfo> filesAndFolders, ProfilingLogger logger)
|
||||
internal static string GetFileHash(IEnumerable<FileSystemInfo> filesAndFolders, ProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<PluginManager>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
var hashCombiner = new HashCodeCombiner();
|
||||
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
if (uniqInfos.Contains(fileOrFolder.FullName)) continue;
|
||||
uniqInfos.Add(fileOrFolder.FullName);
|
||||
hashCombiner.AddFileSystemItem(fileOrFolder);
|
||||
}
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
|
||||
return ConvertHashToInt64(hashCombiner.GetCombinedHashCode());
|
||||
foreach (var fileOrFolder in filesAndFolders)
|
||||
{
|
||||
if (uniqInfos.Contains(fileOrFolder.FullName)) continue;
|
||||
uniqInfos.Add(fileOrFolder.FullName);
|
||||
generator.AddFileSystemItem(fileOrFolder);
|
||||
}
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string hash value into an Int64.
|
||||
/// </summary>
|
||||
internal static long ConvertHashToInt64(string val)
|
||||
{
|
||||
long outVal;
|
||||
return long.TryParse(val, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out outVal) ? outVal : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user