Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions wled00/wled_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#endif

constexpr uint32_t WLED_CUSTOM_DESC_MAGIC = 0x57535453; // "WSTS" (WLED System Tag Structure)
constexpr uint32_t WLED_CUSTOM_DESC_VERSION = 1;
constexpr uint32_t WLED_CUSTOM_DESC_VERSION = 2; // v1 - original PR; v2 - "safe to update from" version

// Compile-time validation that release name doesn't exceed maximum length
static_assert(sizeof(WLED_RELEASE_NAME) <= WLED_RELEASE_NAME_MAX_LEN,
Expand Down Expand Up @@ -59,6 +59,11 @@ const wled_metadata_t __attribute__((section(BUILD_METADATA_SECTION))) WLED_BUIL
TOSTRING(WLED_VERSION),
WLED_RELEASE_NAME, // release_name
std::integral_constant<uint32_t, djb2_hash_constexpr(WLED_RELEASE_NAME)>::value, // hash - computed at compile time; integral_constant enforces this
#if defined(ESP32) && defined(CONFIG_IDF_TARGET_ESP32)
{ 0, 15, 3 }, // Some older ESP32 might have bootloader issues; assume we'll have it sorted by 0.15.3
#else
{ 0, 15, 2 }, // All other platforms can update safely
#endif
};

static const char repoString_s[] PROGMEM = WLED_REPO;
Expand Down Expand Up @@ -96,7 +101,7 @@ bool findWledMetadata(const uint8_t* binaryData, size_t dataSize, wled_metadata_
memcpy(&candidate, binaryData + offset, sizeof(candidate));

// Found potential match, validate version
if (candidate.desc_version != WLED_CUSTOM_DESC_VERSION) {
if (candidate.desc_version > WLED_CUSTOM_DESC_VERSION) {
DEBUG_PRINTF_P(PSTR("Found WLED structure at offset %u but version mismatch: %u\n"),
offset, candidate.desc_version);
continue;
Expand Down Expand Up @@ -151,13 +156,43 @@ bool shouldAllowOTA(const wled_metadata_t& firmwareDescription, char* errorMessa

if (strncmp_P(safeFirmwareRelease, releaseString, WLED_RELEASE_NAME_MAX_LEN) != 0) {
if (errorMessage && errorMessageLen > 0) {
snprintf_P(errorMessage, errorMessageLen, PSTR("Firmware compatibility mismatch: current='%s', uploaded='%s'."),
snprintf_P(errorMessage, errorMessageLen, PSTR("Firmware release name mismatch: current='%s', uploaded='%s'."),
releaseString, safeFirmwareRelease);
errorMessage[errorMessageLen - 1] = '\0'; // Ensure null termination
}
return false;
}

if (firmwareDescription.desc_version > 1) {
// Add safe version check
// Parse our version (x.y.z) and compare it to the "safe version" array
const char* our_version = versionString;
for(unsigned v_index = 0; v_index < 3; ++v_index) {
char* our_version_end = nullptr;
long our_v_parsed = strtol(our_version, &our_version_end, 10);
if (!our_version_end || (our_version_end == our_version)) {
// We were built with a malformed version string
// We blame the integrator and attempt the update anyways - nothing the user can do to fix this
break;
}

if (firmwareDescription.safe_update_version[v_index] > our_v_parsed) {
if (errorMessage && errorMessageLen > 0) {
snprintf_P(errorMessage, errorMessageLen, PSTR("Cannot update from this version: requires at least %d.%d.%d, current='%s'."),
firmwareDescription.safe_update_version[0], firmwareDescription.safe_update_version[1], firmwareDescription.safe_update_version[2],
versionString);
errorMessage[errorMessageLen - 1] = '\0'; // Ensure null termination
}
return false;
} else if (firmwareDescription.safe_update_version[v_index] < our_v_parsed) {
break; // no need to check the other components
}

if (*our_version_end == '.') ++our_version_end;
our_version = our_version_end;
}
}

// TODO: additional checks go here

return true;
Expand Down
1 change: 1 addition & 0 deletions wled00/wled_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef struct {
char wled_version[WLED_VERSION_MAX_LEN];
char release_name[WLED_RELEASE_NAME_MAX_LEN]; // Release name (null-terminated)
uint32_t hash; // Structure sanity check
uint8_t safe_update_version[3]; // Indicates version it's known to be safe to install this update from: major, minor, patch
} __attribute__((packed)) wled_metadata_t;


Expand Down