From e85b496361f2b8063251a41a8ca852d145148601 Mon Sep 17 00:00:00 2001 From: Scott Zager Date: Sat, 18 Jul 2026 20:08:26 -0400 Subject: [PATCH] fix: defensive hardening across SkyAware frontend - restrictUrlRequest: add isFinite check to prevent NaN in localStorage - flag_image: validate filename pattern before setting img src - altitude cell: use DOM manipulation instead of innerHTML Fixes #310 --- public_html/formatter.js | 20 ++++++++++++++++++++ public_html/script.js | 21 +++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/public_html/formatter.js b/public_html/formatter.js index 3ae74205c..b9288de9f 100644 --- a/public_html/formatter.js +++ b/public_html/formatter.js @@ -45,6 +45,26 @@ function format_track_long(track) { return Math.round(track) + DEGREES + NBSP + "(" + TrackDirections[trackDir] + ")"; } +// Return altitude text without HTML +function format_altitude_text(alt, displayUnits) { + if (alt === null) { + return ""; + } else if (alt === "ground") { + return "ground"; + } + return Math.round(convert_altitude(alt, displayUnits)).toLocaleString() + NBSP; +} + +// Return vertical rate triangle character (no HTML) +function format_vert_rate_triangle(vr) { + if (vr > 128) { + return UP_TRIANGLE; + } else if (vr < -128) { + return DOWN_TRIANGLE; + } + return NBSP; +} + // alt in feet function format_altitude_brief(alt, vr, displayUnits) { var alt_text; diff --git a/public_html/script.js b/public_html/script.js index 7217613ca..df1af8d7e 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -156,8 +156,12 @@ function processReceiverUpdate(data, receiver_source) { // set flag image if available if (ShowFlags && plane.icaorange.flag_image !== null) { - $('img', plane.tr.cells[1]).attr('src', FlagPath + plane.icaorange.flag_image); - $('img', plane.tr.cells[1]).attr('title', plane.icaorange.country); + if (/^[a-zA-Z0-9_-]+\.png$/.test(plane.icaorange.flag_image)) { + $('img', plane.tr.cells[1]).attr('src', FlagPath + plane.icaorange.flag_image); + $('img', plane.tr.cells[1]).attr('title', plane.icaorange.country); + } else { + $('img', plane.tr.cells[1]).css('display', 'none'); + } } else { $('img', plane.tr.cells[1]).css('display', 'none'); } @@ -1733,7 +1737,16 @@ function refreshTableInfo() { tableplane.tr.cells[3].textContent = (tableplane.registration !== null ? tableplane.registration : ""); tableplane.tr.cells[4].textContent = (tableplane.icaotype !== null ? tableplane.icaotype : ""); tableplane.tr.cells[5].textContent = (tableplane.squawk !== null ? tableplane.squawk : ""); - tableplane.tr.cells[6].innerHTML = format_altitude_brief(tableplane.altitude, tableplane.vert_rate, DisplayUnits); + { + var cell = tableplane.tr.cells[6]; + cell.textContent = ''; + var altText = format_altitude_text(tableplane.altitude, DisplayUnits); + cell.appendChild(document.createTextNode(altText)); + var vrSpan = document.createElement('span'); + vrSpan.className = 'verticalRateTriangle'; + vrSpan.textContent = format_vert_rate_triangle(tableplane.vert_rate); + cell.appendChild(vrSpan); + } tableplane.tr.cells[7].textContent = format_speed_brief(tableplane.gs, DisplayUnits); tableplane.tr.cells[8].textContent = format_vert_rate_brief(tableplane.vert_rate, DisplayUnits); tableplane.tr.cells[9].textContent = format_distance_brief(tableplane.sitedist, DisplayUnits); @@ -2577,7 +2590,7 @@ function hideBanner() { // Helper function to restrict the range of the inputs function restrictUrlRequest(c) { let v = parseFloat(c); - if (v < 0) { + if (!isFinite(v) || v < 0) { v = 0; } else if (v > 5) { v = 5;