diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad501620..d3f111dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ All notable changes to this project will be documented in this file. - [GUI] Use better console hiding API (#4051 by: HebaruSan) - [Core] Trigger progress updates for frozen downloads (#4052 by: HebaruSan) - [GUI] Fix NRE on trying to update all when there's nothing to update (#4054 by: HebaruSan) -- [Core] Tolerate null repo URLs (#4077 by: HebaruSan) +- [Core] Fix NRE in repo update with corrupted etags.json file (#4077, #4078 by: HebaruSan) ### Internal diff --git a/Core/Repositories/RepositoryDataManager.cs b/Core/Repositories/RepositoryDataManager.cs index 4e76e8363..3baef358c 100644 --- a/Core/Repositories/RepositoryDataManager.cs +++ b/Core/Repositories/RepositoryDataManager.cs @@ -146,9 +146,7 @@ public UpdateResult Update(Repository[] repos, .Where(r => r.uri != null && (r.uri.IsFile || skipETags - || (!etags.TryGetValue(r.uri, out string etag) - || !File.Exists(GetRepoDataPath(r)) - || etag != Net.CurrentETag(r.uri)))) + || repoDataStale(r))) .ToArray(); if (toUpdate.Length < 1) { @@ -240,11 +238,15 @@ public UpdateResult Update(Repository[] repos, /// public event Action Updated; + #region ETags + private void loadETags() { try { - etags = JsonConvert.DeserializeObject>(File.ReadAllText(etagsPath)); + etags = JsonConvert.DeserializeObject>(File.ReadAllText(etagsPath)) + // An empty or all-null file can deserialize as null + ?? new Dictionary(); } catch { @@ -270,6 +272,16 @@ private void setETag(Uri url, string filename, Exception error, string etag) } } + private bool repoDataStale(Repository r) + // No ETag on file + => !etags.TryGetValue(r.uri, out string etag) + // No data on disk + || !File.Exists(GetRepoDataPath(r)) + // Current ETag doesn't match + || etag != Net.CurrentETag(r.uri); + + #endregion + private RepositoryData GetRepoData(Repository repo) => repositoriesData.TryGetValue(repo, out RepositoryData data) ? data