← back to Crazy News Channel Shadowman
Fix malformed hash crash: wrap decodeURIComponent in try/catch, start tick before renderRoute
63ec4a9df83c4d95d43cd6db26043baa33bcdae2 · 2026-09-23 17:47:26 -0700 · Steve Abrams
Hole #1 from Cody red-team: a malformed URI fragment (e.g., #/article/%) caused
decodeURIComponent() to throw an uncaught URIError in getRouteId(), which aborted
init() before setInterval(tick, 1000) could register. This froze the clock and
escalation forever. Now: (1) getRouteId wraps decode in try/catch, returning null
on malformed URIs just like unknown ids; (2) setInterval(tick) fires BEFORE
renderRoute() so clock starts even if routing fails. Reproduced + verified fixed
on malformed hash — clock now ticks with zero errors.
Files touched
Diff
commit 63ec4a9df83c4d95d43cd6db26043baa33bcdae2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 23 17:47:26 2026 -0700
Fix malformed hash crash: wrap decodeURIComponent in try/catch, start tick before renderRoute
Hole #1 from Cody red-team: a malformed URI fragment (e.g., #/article/%) caused
decodeURIComponent() to throw an uncaught URIError in getRouteId(), which aborted
init() before setInterval(tick, 1000) could register. This froze the clock and
escalation forever. Now: (1) getRouteId wraps decode in try/catch, returning null
on malformed URIs just like unknown ids; (2) setInterval(tick) fires BEFORE
renderRoute() so clock starts even if routing fails. Reproduced + verified fixed
on malformed hash — clock now ticks with zero errors.
---
index.html | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/index.html b/index.html
index b5cce6f..996871c 100644
--- a/index.html
+++ b/index.html
@@ -1723,7 +1723,13 @@ function findArticleSource(id) {
function getRouteId() {
const m = location.hash.match(/^#\/article\/(.+)$/);
- return m ? decodeURIComponent(m[1]) : null;
+ if (!m) return null;
+ try {
+ return decodeURIComponent(m[1]);
+ } catch (e) {
+ // Malformed URI (e.g., %XX with no valid hex) — treat as "not found"
+ return null;
+ }
}
function buildRelatedLinks(currentId) {
@@ -1939,11 +1945,13 @@ function init() {
updateMoodUI();
setTickerMode(state.reducedMotion);
refreshTicker();
+ // Start the 1000ms tick loop BEFORE rendering route, so malformed hashes
+ // can't abort init() and freeze the clock/escalation forever
+ setInterval(tick, 1000);
renderStories();
renderFeatures();
renderRoute({ moveFocus: false }); // honor a deep link on initial load, without stealing focus from the page load itself
updateClock();
- setInterval(tick, 1000);
}
document.addEventListener("DOMContentLoaded", init);
← 744e857 Add remaining SDXL story photos (all 40 stories now have an
·
back to Crazy News Channel Shadowman
·
auto-data-snapshot: 2026-09-23T17:59:00 (5 data files) — cta 213738e →