copyparty/copyparty/web/w.hash.js
ed 49c7124776 fix errorhandling for browser-oom
because chrome-bug 383568268 is possibly making a return soon
(observed in google-chrome 138.0.7191.0 and chromium 139.0.7205.0)
2025-05-27 15:25:09 +00:00

126 lines
3.2 KiB
JavaScript

"use strict";
function hex2u8(txt) {
return new Uint8Array(txt.match(/.{2}/g).map(function (b) { return parseInt(b, 16); }));
}
function esc(txt) {
return txt.replace(/[&"<>]/g, function (c) {
return {
'&': '&amp;',
'"': '&quot;',
'<': '&lt;',
'>': '&gt;'
}[c];
});
}
var subtle = null;
try {
subtle = crypto.subtle;
subtle.digest('SHA-512', new Uint8Array(1)).then(
function (x) { },
function (x) { load_fb(); }
);
}
catch (ex) {
load_fb();
}
function load_fb() {
subtle = null;
if (self.hashwasm)
return;
importScripts('deps/sha512.hw.js');
console.log('using fallback hasher');
}
var reader = null,
gc1, gc2, gc3,
busy = false;
onmessage = (d) => {
if (d.data == 'nosubtle')
return load_fb();
if (d.data == 'ping')
return postMessage(['pong']);
if (busy)
return postMessage(["panic", 'worker got another task while busy']);
if (!reader)
reader = new FileReader();
var [nchunk, fobj, car, cdr] = d.data,
t0 = Date.now();
reader.onload = function (e) {
try {
// chrome gc forgets the filereader output; remind it
// (for some chromes, also necessary for subtle)
gc1 = e.target.result;
gc2 = new Uint8Array(gc1, 0, 1);
gc3 = new Uint8Array(gc1, gc1.byteLength - 1);
//console.log('[ w] %d HASH bgin', nchunk);
postMessage(["read", nchunk, cdr - car, Date.now() - t0]);
hash_calc(gc1);
}
catch (ex) {
busy = false;
postMessage(["panic", ex + '']);
}
};
reader.onerror = function () {
busy = false;
var err = esc('' + reader.error);
if (err.indexOf('NotReadableError') !== -1 || // win10-chrome defender
err.indexOf('NotFoundError') !== -1 // macos-firefox permissions
)
return postMessage(["fail", 'OS-error', err + ' @ ' + car]);
postMessage(["ferr", err]);
};
//console.log('[ w] %d read bgin', nchunk);
busy = true;
reader.readAsArrayBuffer(fobj.slice(car, cdr));
var hash_calc = function (buf) {
var hash_done = function (hashbuf) {
// stop gc from attempting to free early
if (!gc1 || !gc2 || !gc3)
return console.log('torch went out');
gc1 = gc2 = gc3 = null;
busy = false;
try {
var hslice = new Uint8Array(hashbuf).subarray(0, 33);
//console.log('[ w] %d HASH DONE', nchunk);
postMessage(["done", nchunk, hslice, cdr - car]);
}
catch (ex) {
postMessage(["panic", ex + '']);
}
};
// stop gc from attempting to free early
if (!gc1 || !gc2 || !gc3)
console.log('torch went out');
if (subtle)
subtle.digest('SHA-512', buf).then(hash_done);
else {
// note: lifting u8buf counterproductive for the chrome gc bug
var u8buf = new Uint8Array(buf);
hashwasm.sha512(u8buf).then(function (v) {
hash_done(hex2u8(v))
});
}
};
}