Skip to content

Commit a28a257

Browse files
CR: Use base64 hashes
1 parent 203f1a7 commit a28a257

File tree

4 files changed

+25
-15
lines changed

4 files changed

+25
-15
lines changed

src/Components/Blazor/Build/src/Tasks/GenerateBlazorBootJson.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,7 @@ internal void WriteBootJson(Stream output, string entryAssemblyName)
7676
var resourceFileRelativePath = GetResourceFileRelativePath(resource);
7777
if (!resourceList.ContainsKey(resourceFileRelativePath))
7878
{
79-
// It's safe to truncate to a fairly short string, since the hash is not used for any
80-
// security purpose - the developer produces these files themselves, and the hash is
81-
// only used to check whether an earlier cached copy is up-to-date.
82-
// This truncation halves the size of blazor.boot.json in typical cases.
83-
resourceList.Add(resourceFileRelativePath, resource.GetMetadata("FileHash").Substring(0, 16).ToLowerInvariant());
79+
resourceList.Add(resourceFileRelativePath, resource.GetMetadata("FileHash"));
8480
}
8581
}
8682
}

src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@
350350
<_BlazorBootResource BootResourceType="wasm" Condition="'%(Extension)' == '.wasm'" />
351351
</ItemGroup>
352352

353-
<GetFileHash Files="@(_BlazorBootResource->HasMetadata('BootResourceType'))">
353+
<GetFileHash Files="@(_BlazorBootResource->HasMetadata('BootResourceType'))" Algorithm="SHA256" HashEncoding="base64">
354354
<Output TaskParameter="Items" ItemName="_BlazorBootResourceWithHashes" />
355355
</GetFileHash>
356356

src/Components/Web.JS/dist/Release/blazor.webassembly.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Platform/WebAssemblyResourceLoader.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,31 @@ function getPerformanceEntry(url: string): PerformanceResourceTiming | undefined
160160
}
161161
}
162162

163-
async function assertContentHashMatchesAsync(name: string, data: ArrayBuffer, expectedHashPrefix: string) {
163+
async function assertContentHashMatchesAsync(name: string, data: ArrayBuffer, expectedHashBase64: string) {
164+
const expectedHashDataUri = `data:text/plain;base64,${expectedHashBase64}`;
165+
const expectedHashResponse = await fetch(expectedHashDataUri);
166+
const expectedHashBuffer = await expectedHashResponse.arrayBuffer();
164167
const actualHashBuffer = await crypto.subtle.digest('SHA-256', data);
165-
const actualHash = new Uint8Array(actualHashBuffer);
166-
for (var byteIndex = 0; byteIndex*2 < expectedHashPrefix.length; byteIndex++) {
167-
const expectedByte = parseInt(expectedHashPrefix.substr(byteIndex * 2, 2), 16);
168-
const actualByte = actualHash[byteIndex];
169-
if (actualByte !== expectedByte) {
170-
const actualHashString = Array.from(actualHash).map(b => b.toString(16).padStart(2, '0')).join('');
171-
throw new Error(`Resource hash mismatch for '${name}'. Expected prefix: '${expectedHashPrefix}'. Actual hash: '${actualHashString}'. If a deployment was in progress, try reloading the page.`);
168+
if (!arrayBuffersAreEqual(expectedHashBuffer, actualHashBuffer)) {
169+
var actualHashBase64 = btoa(String.fromCharCode(...new Uint8Array(actualHashBuffer)));
170+
throw new Error(`Resource hash mismatch for '${name}'. Expected hash: '${expectedHashBase64}'. Actual hash: '${actualHashBase64}'. If a deployment was in progress, try reloading the page.`);
171+
}
172+
}
173+
174+
function arrayBuffersAreEqual(a: ArrayBuffer, b: ArrayBuffer) {
175+
if (a.byteLength !== b.byteLength) {
176+
return false;
177+
}
178+
179+
const arrayA = new Uint8Array(a);
180+
const arrayB = new Uint8Array(b);
181+
for (let i = 0; i < arrayA.byteLength; i++) {
182+
if (arrayA[i] !== arrayB[i]) {
183+
return false;
172184
}
173185
}
186+
187+
return true;
174188
}
175189

176190
// Keep in sync with bootJsonData in Microsoft.AspNetCore.Blazor.Build

0 commit comments

Comments
 (0)