Skip to content

Commit 0254d6e

Browse files
committed
Use hash-wasm to calculate the hash of a file.
1 parent 91c2aad commit 0254d6e

File tree

8 files changed

+57
-18
lines changed

8 files changed

+57
-18
lines changed

.github/workflows/javascript.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ jobs:
6868
- name: "Check '@ckeditor/ckeditor5-inspector'"
6969
run: |
7070
diff -wu wcfsetup/install/files/js/3rdParty/ckeditor/ckeditor5-inspector/inspector.js node_modules/@ckeditor/ckeditor5-inspector/build/inspector.js
71+
- name: "Check 'hash-wasm'"
72+
run: |
73+
diff -wu wcfsetup/install/files/js/3rdParty/hash-wasm/sha256.umd.min.js node_modules/hash-wasm/dist/sha256.umd.min.js

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@woltlab/visual-dom-diff": "git+https://github.com/WoltLab/visual-dom-diff.git#e5b51fce3157d1eda310566fc1f86101341d1fea",
2626
"@woltlab/zxcvbn": "git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
2727
"focus-trap": "^7.6.5",
28+
"hash-wasm": "^4.12.0",
2829
"html-parsed-element": "^0.4.1",
2930
"perfect-scrollbar": "^1.5.6",
3031
"qr-creator": "^1.0.0",

ts/WoltLabSuite/Core/Component/File/Upload.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import ImageResizer from "WoltLabSuite/Core/Image/Resizer";
1111
import { AttachmentData } from "../Ckeditor/Attachment";
1212
import { innerError } from "WoltLabSuite/Core/Dom/Util";
1313
import { getPhrase } from "WoltLabSuite/Core/Language";
14+
import { createSHA256 } from "hash-wasm";
1415

1516
export type CkeditorDropEvent = {
1617
file: File;
@@ -36,6 +37,8 @@ type ResizeConfiguration = {
3637
quality: number;
3738
};
3839

40+
const BUFFER_SIZE = 10 * 1_024 * 1_024;
41+
3942
async function upload(
4043
element: WoltlabCoreFileUploadElement,
4144
file: File,
@@ -74,7 +77,7 @@ async function upload(
7477
const end = start + chunkSize;
7578
const chunk = file.slice(start, end);
7679

77-
const checksum = await getSha256Hash(await chunk.arrayBuffer());
80+
const checksum = await getSha256Hash(chunk);
7881

7982
const response = await uploadChunk(identifier, i, checksum, chunk);
8083
if (!response.ok) {
@@ -119,12 +122,20 @@ async function chunkUploadCompleted(fileElement: WoltlabCoreFileElement, result:
119122
}
120123
}
121124

122-
async function getSha256Hash(data: BufferSource): Promise<string> {
123-
const buffer = await window.crypto.subtle.digest("SHA-256", data);
125+
async function getSha256Hash(data: Blob): Promise<string> {
126+
const sha256 = await createSHA256();
127+
sha256.init();
128+
129+
let offset = 0;
130+
131+
while (offset < data.size) {
132+
const chunk = data.slice(offset, offset + BUFFER_SIZE);
133+
const buffer = await chunk.arrayBuffer();
134+
sha256.update(new Uint8Array(buffer));
135+
offset += BUFFER_SIZE;
136+
}
124137

125-
return Array.from(new Uint8Array(buffer))
126-
.map((b) => b.toString(16).padStart(2, "0"))
127-
.join("");
138+
return sha256.digest("hex");
128139
}
129140

130141
export function clearPreviousErrors(element: WoltlabCoreFileUploadElement): void {
@@ -312,9 +323,7 @@ export function setup(): void {
312323
}
313324
}
314325

315-
const checksums = await Promise.allSettled(
316-
validFiles.map((file) => file.arrayBuffer().then((buffer) => getSha256Hash(buffer))),
317-
);
326+
const checksums = await Promise.allSettled(validFiles.map((file) => getSha256Hash(file)));
318327

319328
for (let i = 0, length = checksums.length; i < length; i++) {
320329
const result = checksums[i];
@@ -354,7 +363,7 @@ export function setup(): void {
354363

355364
void resizeImage(element, file).then(async (resizeFile) => {
356365
try {
357-
const checksum = await getSha256Hash(await resizeFile.arrayBuffer());
366+
const checksum = await getSha256Hash(resizeFile);
358367
const data = await upload(element, resizeFile, checksum);
359368
if (data === undefined || typeof data.data.attachmentID !== "number") {
360369
promiseReject();

ts/global.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,8 @@ declare global {
148148
"woltlab-core-google-maps": WoltlabCoreGoogleMapsElement;
149149
"woltlab-core-reaction-summary": WoltlabCoreReactionSummaryElement;
150150
}
151+
152+
// The type `Buffer` does not exist. To avoid having to load `@types/node`, we define it here.
153+
// @see https://github.com/Daninet/hash-wasm/issues/68
154+
type Buffer = BufferSource;
151155
}

wcfsetup/install/files/js/3rdParty/hash-wasm/sha256.umd.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wcfsetup/install/files/js/WoltLabSuite/Core/Component/File/Upload.js

Lines changed: 15 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wcfsetup/install/files/js/require.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ requirejs.config({
1717
"@woltlab/editor": "3rdParty/ckeditor/ckeditor5.bundle",
1818
"ckeditor5-translation": "3rdParty/ckeditor/translations",
1919
"diff-match-patch": "3rdParty/diff-match-patch/diff_match_patch.min",
20+
"hash-wasm": "3rdParty/hash-wasm/sha256.umd.min",
2021
},
2122
packages: [
2223
{

0 commit comments

Comments
 (0)