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,54 +1453,125 @@ function uploadBin(){
let progressEl=document.getElementById("uploadDone");
if (! el) return;
if ( el.files.length < 1) return;
ensurePass()
.then (function(hash){
let file=el.files[0];
let len=file.size;
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 len = file.size;
let req = new XMLHttpRequest();
req.onloadend=function(){
let result="unknown error";
try{
let jresult=JSON.parse(req.responseText);
if (jresult.status == 'OK'){
result='';
req.onloadend = function () {
let result = "unknown error";
try {
let jresult = JSON.parse(req.responseText);
if (jresult.status == 'OK') {
result = '';
}
else{
else {
if (jresult.status) {
result=jresult.status;
result = jresult.status;
}
}
}catch (e){
result="Error "+req.status;
} catch (e) {
result = "Error " + req.status;
}
if (progressEl){
progressEl.style.width=0;
if (progressEl) {
progressEl.style.width = 0;
}
if (! result){
if (!result) {
alertRestart();
}
else{
alert("update error: "+result);
else {
alert("update error: " + result);
}
}
req.onerror=function(e){
alert("unable to upload: "+e);
req.onerror = function (e) {
alert("unable to upload: " + e);
}
if (progressEl){
progressEl.style.width=0;
req.upload.onprogress=function(ev){
if (ev.lengthComputable){
let percent=100*ev.loaded/ev.total;
progressEl.style.width=percent+"%";
if (progressEl) {
progressEl.style.width = 0;
req.upload.onprogress = function (ev) {
if (ev.lengthComputable) {
let percent = 100 * ev.loaded / ev.total;
progressEl.style.width = percent + "%";
}
}
}
let formData = new FormData();
formData.append("file1", el.files[0]);
req.open("POST", '/api/update?_hash='+encodeURIComponent(hash));
req.open("POST", '/api/update?_hash=' + encodeURIComponent(hash));
req.send(formData);
})
.catch(function(e){});
.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");
})
})
})
})
});