check image before uploading

This commit is contained in:
wellenvogel 2021-12-15 18:48:06 +01:00
parent 32ee425a5a
commit d3e1e9b3e8
3 changed files with 141 additions and 44 deletions

View File

@ -335,3 +335,6 @@ body {
width: 0px;
height: 100%;
}
.error{
color: red;
}

View File

@ -88,6 +88,10 @@
<span class="label">New Firmware</span>
<input type="file" name="file1" id="uploadFile">
</div>
<div class="row">
<span class="label"></span>
<span id="imageProperties" class="value"></span>
</div>
<div id="uploadProgress">
<div id="uploadDone"></div>
</div>

View File

@ -1453,9 +1453,29 @@ function uploadBin(){
let progressEl=document.getElementById("uploadDone");
if (! el) return;
if ( el.files.length < 1) return;
let file=el.files[0];
checkImageFile(file)
.then(function (result) {
let currentType;
let currentVersion;
forEl('.status-version', function (el) { currentVersion = el.textContent });
forEl('.status-fwtype', function (el) { currentType = el.textContent });
let confirmText = 'Ready to update firmware?\n';
if (currentType != result.fwtype) {
confirmText += "WARNING: image has different type: " + result.fwtype + "\n";
confirmText += "** Really update anyway? - device can become unusable **";
}
else {
if (currentVersion == result.version) {
confirmText += "WARNING: image has the same version as current " + result.version;
}
else {
confirmText += "version in image: " + result.version;
}
}
if (!confirm(confirmText)) return;
ensurePass()
.then(function (hash) {
let file=el.files[0];
let len = file.size;
let req = new XMLHttpRequest();
req.onloadend = function () {
@ -1501,6 +1521,57 @@ function uploadBin(){
req.send(formData);
})
.catch(function (e) { });
})
.catch(function (e) {
alert("This file is an invalid image file:\n" + e);
})
}
let HDROFFSET=288;
let VERSIONOFFSET=16;
let NAMEOFFSET=48;
let MINSIZE=HDROFFSET+NAMEOFFSET+32;
let imageCheckBytes={
0: 0xe9, //image magic
288: 0x32, //app header magic
289: 0x54,
290: 0xcd,
291: 0xab
};
function decodeFromBuffer(buffer,start,length){
while (length > 0 && buffer[start+length-1] == 0){
length--;
}
if (length <= 0) return "";
let decoder=new TextDecoder();
let rt=decoder.decode(buffer.slice(
start,
start+length));
return rt;
}
function checkImageFile(file){
return new Promise(function(resolve,reject){
if (! file) reject("no file");
if (file.size < MINSIZE) reject("file is too small");
let slice=file.slice(0,MINSIZE);
let reader=new FileReader();
reader.addEventListener('load',function(e){
let content=new Uint8Array(e.target.result);
for (let idx in imageCheckBytes){
if (content[idx] != imageCheckBytes[idx] ){
reject("missing magic byte at position "+idx+", expected "+
imageCheckBytes[idx]+", got "+content[idx]);
}
}
let version=decodeFromBuffer(content,HDROFFSET+VERSIONOFFSET,32);
let fwtype=decodeFromBuffer(content,HDROFFSET+NAMEOFFSET,32);
let rt={
fwtype:fwtype,
version: version,
};
resolve(rt);
});
reader.readAsArrayBuffer(slice);
});
}
window.setInterval(update, 1000);
window.setInterval(function () {
@ -1550,4 +1621,23 @@ window.addEventListener('load', function () {
even=!even;
}
}
forEl('#uploadFile',function(el){
el.addEventListener('change',function(ev){
if (ev.target.files.length < 1) return;
let file=ev.target.files[0];
checkImageFile(file)
.then(function(res){
forEl('#imageProperties',function(iel){
iel.textContent=res.fwtype+", "+res.version;
iel.classList.remove("error");
})
})
.catch(function(e){
forEl('#imageProperties',function(iel){
iel.textContent=e;
iel.classList.add("error");
})
})
})
})
});