-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Add OTA metadata validation v2 #4998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -17,7 +17,26 @@ | |||||
} | ||||||
window.open(getURL("/update?revert"),"_self"); | ||||||
} | ||||||
function GetV() {/*injected values here*/} | ||||||
function GetV() { | ||||||
// Fetch device info via JSON API instead of compiling it in | ||||||
fetch('/json/info') | ||||||
.then(response => response.json()) | ||||||
.then(data => { | ||||||
document.querySelector('.installed-version').textContent = `${data.brand} ${data.ver} (${data.vid})`; | ||||||
document.querySelector('.release-name').textContent = data.release; | ||||||
// TODO - assemble update URL | ||||||
// TODO - can this be done at build time? | ||||||
if (data.arch == "esp8266") { | ||||||
toggle('rev'); | ||||||
} | ||||||
}) | ||||||
.catch(error => { | ||||||
console.log('Could not fetch device info:', error); | ||||||
// Fallback to compiled-in value if API call fails | ||||||
document.querySelector('.installed-version').textContent = 'Unknown'; | ||||||
document.querySelector('.release-name').textContent = 'Unknown'; | ||||||
}); | ||||||
} | ||||||
</script> | ||||||
<style> | ||||||
@import url("style.css"); | ||||||
|
@@ -27,11 +46,15 @@ | |||||
<body onload="GetV()"> | ||||||
<h2>WLED Software Update</h2> | ||||||
<form method='POST' action='./update' id='upd' enctype='multipart/form-data' onsubmit="toggle('upd')"> | ||||||
Installed version: <span class="sip">WLED ##VERSION##</span><br> | ||||||
Installed version: <span class="sip installed-version">Loading...</span><br> | ||||||
Release: <span class="sip release-name">Loading...</span><br> | ||||||
Download the latest binary: <a href="https://github.com/wled-dev/WLED/releases" target="_blank" | ||||||
style="vertical-align: text-bottom; display: inline-flex;"> | ||||||
<img src="https://img.shields.io/github/release/wled-dev/WLED.svg?style=flat-square"></a><br> | ||||||
<input type="hidden" name="skipValidation" value="" id="sV"> | ||||||
<input type='file' name='update' required><br> <!--should have accept='.bin', but it prevents file upload from android app--> | ||||||
<input type='checkbox' onchange="sV.value=checked?1:''" id="skipValidation"> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix uncaught ReferenceError in checkbox handler. The inline event handler references Apply this diff to fix the handler: -<input type='checkbox' onchange="sV.value=checked?1:''" id="skipValidation">
+<input type='checkbox' onchange="sV.value=this.checked?1:''" id="skipValidation"> 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't throw, though: the value is correctly set. I've tested this many times with two different browser engines. Can you find a reference document online that indicates why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Short answer: inline handler code runs as a Function whose scope chain includes the element itself, so properties like checked are visible without writing this.checked — you can use checked, the element's id as a variable, or event.currentTarget/target instead. See examples and spec notes below. Why: the HTML spec requires the content of an on... attribute to be interpreted as the body of a function with one argument named event and "the new function's scope chain [linked] ... to the element, to the element's form owner, ... to the Document object, to the Window object." That means the element's own properties/attributes and prototype properties are reachable as unqualified names inside the handler (effectively like a with(this) around the body). (w3.org) Examples
Caveats
If you want, I can show a minimal runnable example demonstrating each approach. Citations:
@willmmiles, you're absolutely right, and I apologize for the incorrect comment. The code works as written. According to the HTML specification, inline event handler attributes have a special scope chain that includes the element itself. This means the element's properties (like So both of these are valid and work identically:
Your implementation is correct and spec-compliant. Thank you for pushing back and asking for documentation - the code does not need to be changed. 🧠 Learnings used
|
||||||
<label for='skipValidation'>Ignore firmware validation</label><br> | ||||||
<button type="submit">Update!</button><br> | ||||||
<hr class="sml"> | ||||||
<button id="rev" type="button" onclick="cR()">Revert update</button><br> | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -414,7 +414,7 @@ void prepareArtnetPollReply(ArtPollReply *reply) { | |
|
||
reply->reply_port = ARTNET_DEFAULT_PORT; | ||
|
||
char * numberEnd = versionString; | ||
char * numberEnd = (char*) versionString; // strtol promises not to try to edit this. | ||
reply->reply_version_h = (uint8_t)strtol(numberEnd, &numberEnd, 10); | ||
numberEnd++; | ||
reply->reply_version_l = (uint8_t)strtol(numberEnd, &numberEnd, 10); | ||
Comment on lines
+417
to
420
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reconsider casting away const. Casting Consider a safer approach: - char * numberEnd = (char*) versionString; // strtol promises not to try to edit this.
+ const char * numberEnd = versionString;
reply->reply_version_h = (uint8_t)strtol(numberEnd, &numberEnd, 10); Note: This change assumes
🤖 Prompt for AI Agents
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alas, strtol's second parameter is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @willmmiles, you're absolutely right—my apologies for the incorrect suggestion. I overlooked that Given this constraint, the current approach of casting away const with the explanatory comment is a reasonable pragmatic solution, especially since:
If you wanted to be strictly const-correct, you could make a small local mutable copy: char versionBuffer[WLED_VERSION_MAX_LEN];
strlcpy(versionBuffer, versionString, sizeof(versionBuffer));
char* numberEnd = versionBuffer;
reply->reply_version_h = (uint8_t)strtol(numberEnd, &numberEnd, 10);
numberEnd++;
reply->reply_version_l = (uint8_t)strtol(numberEnd, &numberEnd, 10); However, given the simplicity of the parsing and the explanatory comment, the current implementation is perfectly acceptable. The cast is well-documented and the risk is negligible. |
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical logic error in
has_def
function.The condition
if f == name:
is outside the loop, so it only checks the last element incppdefs
. This will cause incorrect behavior when checking for the presence of a definition.Apply this diff to fix the logic:
📝 Committable suggestion
🤖 Prompt for AI Agents