Skip to content

GUI: tools-survey.asp - upgrade to v2.01#191

Open
wellloaded wants to merge 1 commit intoFreshTomato-Project:arm-masterfrom
wellloaded:survey2
Open

GUI: tools-survey.asp - upgrade to v2.01#191
wellloaded wants to merge 1 commit intoFreshTomato-Project:arm-masterfrom
wellloaded:survey2

Conversation

@wellloaded
Copy link
Contributor

  • Changed charts from canvas to SVG
  • Sped up the initial display of data after initial page load, this might display 2.4Ghz first and 5Ghz after 1 or 2 seconds, but it's faster than waiting the refresh timer
  • Fixed some odd loading behaviour, especially when the page first loads
  • "error: unable to fetch scan results" is not displayed any more, if no data is available at refresh it will just keep trying until a first result are obtained
  • Added Loading... + spinner to the charts at page load to suggest data is coming
  • “Display” filter is hidden if only one frequency is enabled under basic/network
  • Fixed first page visit ever when a refresh is not yet set (now defaults to 15s)
  • Fixed bug when SSIDs contains the character: "
  • Overall better look and feel using the page

Copilot AI review requested due to automatic review settings January 4, 2026 15:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the WiFi survey tool to v2.01, migrating from Canvas to SVG-based charts and implementing several performance and UX improvements. The changes introduce a shell command fallback mechanism for fetching scan results, add loading indicators, and fix various bugs related to SSID handling and page initialization.

Key changes:

  • Complete migration from HTML5 Canvas to SVG for chart rendering with new helper functions
  • New shell-based scanning fallback mechanism (runShell, fetchShellScanResults, parseWlScanResults) when CGI data is unavailable
  • Enhanced loading experience with spinner overlays and fast-polling logic for initial data display

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
doit();

var isError = (wlscandata && (wlscandata.length == 1) && (!wlscandata[0][0]));
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check wlscandata.length == 1 uses loose equality. For consistency with other parts of the code and to avoid type coercion issues, use strict equality (===) instead.

Suggested change
var isError = (wlscandata && (wlscandata.length == 1) && (!wlscandata[0][0]));
var isError = (wlscandata && (wlscandata.length === 1) && (!wlscandata[0][0]));

Copilot uses AI. Check for mistakes.
'stroke-width': 1
}));

if (a == 'ellipses2') {
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loose equality (==) is used in the board comparison. Use strict equality (===) for consistency with modern JavaScript best practices.

Suggested change
if (a == 'ellipses2') {
if (a === 'ellipses2') {

Copilot uses AI. Check for mistakes.
var frag = document.createDocumentFragment();
var w = sz.w;
var h = sz.h;
var gridColor = (can == 'ellipses2') ? '#f2f2f2' : '#f4f4f4';
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comparison uses loose equality (==) instead of strict equality (===). Use strict equality for consistency with the codebase and to avoid type coercion issues.

Copilot uses AI. Check for mistakes.
frag.appendChild(svgEl('rect', { x: (w / div24) * 15, y: 0, width: (w / div24) * 11, height: vsize, fill: shade }));
frag.appendChild(svgEl('rect', { x: (w / div24) * 13, y: 0, width: (w / div24) * 15, height: vsize, fill: shade }));
}
else if (can == 'ellipses5') {
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition uses loose equality (==) for the board comparison. Use strict equality (===) for consistency with JavaScript best practices.

Copilot uses AI. Check for mistakes.
Comment on lines 479 to +771
sg.insert(-1, e, [ '<small>'+seen+'<\/small>', ''+e.col, ''+e.ssid, mac, (e.rssi < 0 ? e.rssi+'' : ''), ''+e.snr,
(e.qual < 0 ? '' : '<small>'+e.qual+'<\/small><br><img src="bar'+MIN(MAX(Math.floor(e.qual / 12), 1), 6)+'.gif" id="bar_'+i+'" alt="">'),
''+e.control+'/'+e.channel, '<small>'+e.cap, '<\/small>'+e.rates], false);
(e.qual < 0 ? '' : '<small>'+e.qual+'<\/small><br><img src="bar'+MIN(MAX(Math.floor(e.qual / 12), 1), 6)+'.gif" id="bar_'+i+'" alt="">'),
''+e.control+'/'+e.channel, '<small>'+e.cap, '<\/small>'+e.rates], false);
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent indentation is used in the table row insertion. The first line uses spaces while subsequent lines use tabs. This should be standardized to match the rest of the file's indentation style.

Copilot uses AI. Check for mistakes.
var c;
if (((c = cookie.get(cprefix+'_notes_vis')) != null) && (c == '1'))
toggleVisibility(cprefix, 'notes');

Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default refresh time has been changed from index 9 to index 5, but there's no documentation or comment explaining what these index values represent. This magic number makes the code harder to maintain. Consider adding a comment explaining the time values corresponding to each index.

Suggested change
// Default refresh time: use option at index 5 of the <select id="expire-time"> list
// when there is no saved cookie value. This index is 0-based and refers to the
// position of the desired refresh interval option in the HTML, not the time itself.
// If you change the order or number of options for #expire-time, adjust this index
// accordingly to keep the same default interval.

Copilot uses AI. Check for mistakes.
svg.appendChild(frag);
}

function clearCanvas(canvas) {
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name clearCanvas is misleading since it now operates on SVG elements, not canvas elements. This should be renamed to something more generic like clearChart or clearSVG to accurately reflect its current purpose.

Copilot uses AI. Check for mistakes.
if (!wlscandata || !wlscandata.length)
return false;
for (var i = 0; i < wlscandata.length; i++) {
if (wlscandata[i] && (wlscandata[i][9] == freq))
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comparison uses loose equality (==) which can lead to unexpected type coercion. Use strict equality (===) instead for more predictable behavior and consistency with the rest of the codebase.

Suggested change
if (wlscandata[i] && (wlscandata[i][9] == freq))
if (wlscandata[i] && (wlscandata[i][9] === freq))

Copilot uses AI. Check for mistakes.
Comment on lines 219 to +438
eval(text);
}
catch (ex) {
console.error('wlscan refresh eval failed:', ex);
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ref.refresh handler calls eval(text) directly on the response from update.cgi?exec=wlscan, which contains Wi-Fi scan results including attacker-controlled SSID strings from nearby access points. On the server side, asp_wlscan only partially escapes SSIDs (it prepends a single backslash before the first '), so an SSID like \';alert(1);// will break out of the string literal in the generated JavaScript and execute arbitrary code when eval runs. Treat the wlscan payload as data instead of code (e.g. use a structured format and a safe parser) and ensure SSIDs are fully escaped before they reach any JavaScript execution sink like eval.

Suggested change
eval(text);
}
catch (ex) {
console.error('wlscan refresh eval failed:', ex);
// Treat wlscan response as data, not executable code.
// Expect either a JSON array or a JSON object with a `wlscandata` array.
var parsed = JSON.parse(text);
if (parsed && parsed.wlscandata && parsed.wlscandata.length !== undefined) {
wlscandata = parsed.wlscandata;
}
else if (parsed && parsed.length !== undefined) {
wlscandata = parsed;
}
else {
throw new Error('Unexpected wlscan response format');
}
}
catch (ex) {
console.error('wlscan refresh parse failed:', ex);

Copilot uses AI. Check for mistakes.
Comment on lines 479 to +771
sg.insert(-1, e, [ '<small>'+seen+'<\/small>', ''+e.col, ''+e.ssid, mac, (e.rssi < 0 ? e.rssi+'' : ''), ''+e.snr,
(e.qual < 0 ? '' : '<small>'+e.qual+'<\/small><br><img src="bar'+MIN(MAX(Math.floor(e.qual / 12), 1), 6)+'.gif" id="bar_'+i+'" alt="">'),
''+e.control+'/'+e.channel, '<small>'+e.cap, '<\/small>'+e.rates], false);
(e.qual < 0 ? '' : '<small>'+e.qual+'<\/small><br><img src="bar'+MIN(MAX(Math.floor(e.qual / 12), 1), 6)+'.gif" id="bar_'+i+'" alt="">'),
''+e.control+'/'+e.channel, '<small>'+e.cap, '<\/small>'+e.rates], false);
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SSID value from wlscandata (s[1]) is assigned to e.ssid and then injected directly into the grid via sg.insert with escCells set to false, which means it is written into the DOM using innerHTML without any escaping. Because SSIDs come from nearby Wi-Fi beacons and can contain arbitrary characters (e.g. <img onerror=...>), a malicious access point in range can inject HTML/JavaScript into the Tools → Wireless Survey page when an admin views it. Ensure SSIDs are HTML-escaped (e.g. using a helper like escapeHTML) or rendered via textContent/escCells=true so that untrusted SSID strings cannot become executable markup.

Copilot uses AI. Check for mistakes.
@HommeOursPorc
Copy link
Contributor

Is it only me or copilot is annoying!? Is that a new option or it is forced?

@wellloaded
Copy link
Contributor Author

I think it's something on my side to be fair. I need to tweak it to give local feedback only and not after a PR is created.

@scoobasteve83
Copy link
Contributor

Is it only me or copilot is annoying!? Is that a new option or it is forced?

:) now now you are not treating it strictly equal.

Ehhh it has its purpose to be honest likely brought up a good point or two. I'm all for making code more easily readable through comments and better names especially in a codebase this large no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants