Repository navigation
Conversation
PR Summary by QodoAdd shared English and Swedish localization across interfaces
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
1. A language link executes attacker script
|
| const requested = new URLSearchParams(window.location.search).get("lang"); | ||
| if (requested) return requested.toLowerCase().split("-")[0]; |
There was a problem hiding this comment.
1. A language link executes attacker script 🐞 Bug ⛨ Security
languageFromRequest accepts an arbitrary lang value, so one beginning with // makes the catalog URL point to an attacker-hosted, CORS-enabled JSON file. When a sponsored server is selected, startRenderingLoop inserts that catalog's server.sponsor value into innerHTML, allowing markup from the crafted link to execute.
Agent Prompt
## Issue description
An unvalidated `lang` parameter can load an attacker-controlled catalog, whose sponsor translation is inserted as HTML.
## Fix Focus Areas
- frontend/javascript/i18n.js[8-13]
- frontend/javascript/i18n.js[39-46]
- frontend/javascript/index.js[358-364]
## Recommended Fix
Accept only supported language codes before constructing the catalog URL, falling back to English for other values. Build the sponsor label and link with text nodes and DOM APIs rather than inserting translation text through `innerHTML`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| var pendingOpt = document.createElement("option"); | ||
| pendingOpt.value = ""; | ||
| pendingOpt.textContent = "Finding best server..."; | ||
| pendingOpt.textContent = window.LibreSpeedI18n.t("stability.finding-server", "Finding best server..."); |
There was a problem hiding this comment.
2. Configured stability tests fail to start 🐞 Bug ≡ Correctness
initServers now calls LibreSpeedI18n.t() while the page's inline script can run before the deferred localization script. When SPEEDTEST_SERVERS is configured as a nonempty array, loadServers invokes initServers synchronously and the missing global throws before initialization finishes.
Agent Prompt
## Issue description
A supported array-based server configuration initializes the stability page before its deferred localization script has installed the translation API.
## Fix Focus Areas
- stability.html[408-419]
- stability.html[485-490]
- stability.html[985-991]
## Recommended Fix
Start server loading only after the localization script has executed, preferably after its `ready` promise settles. Preserve startup when catalog loading fails.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
||
| // Bootstrap the application when the DOM is ready | ||
| window.addEventListener("DOMContentLoaded", async () => { | ||
| await window.LibreSpeedI18n.ready; |
There was a problem hiding this comment.
3. Slow translations block speed tests 🐞 Bug ☼ Reliability
The modern bootstrap awaits LibreSpeedI18n.ready, and the classic bootstrap also waits for that promise before initializing its test. If the catalog request remains pending, neither view reaches its test controls or server initialization, even though the page has English fallback text.
Agent Prompt
## Issue description
An indefinitely pending catalog request now prevents modern and classic speed tests from initializing.
## Fix Focus Areas
- frontend/javascript/i18n.js[39-53]
- frontend/javascript/index.js[27-34]
- index-classic.html[523-526]
## Recommended Fix
Give catalog loading a bounded wait or allow test initialization with English fallback while it proceeds. Ensure late translation does not overwrite live UI state.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| oninput="updateThreshold(this.value)" | ||
| /> | ||
| <span id="thresholdValue">Off</span> | ||
| <span id="thresholdValue" data-i18n="stability.off">Off</span> |
There was a problem hiding this comment.
4. Late translations reset stability status 🐞 Bug ≡ Correctness
translateDocument() unconditionally rewrites the mutable #thresholdValue text and #startBtn title from their static translation bindings. If a threshold is adjusted or server discovery finishes before the catalog loads, an active threshold can appear off and a ready or failed server control can appear to be finding a server.
Agent Prompt
## Issue description
A late catalog response overwrites stability controls whose text and title have already been updated to reflect live state.
## Fix Focus Areas
- stability.html[296-297]
- stability.html[365-367]
- stability.html[555-560]
- stability.html[942-946]
- frontend/javascript/i18n.js[26-36]
## Recommended Fix
Do not statically translate attributes or text owned by the stability state handlers. Translate their initial values and re-render the current server and threshold state once localization is ready.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| <a href="index.html?design=new" data-i18n="classic.modern">Try the modern design</a><br> | ||
| <a href="stability.html" data-i18n="classic.stability">Stability Test</a> | <a href="https://github.com/librespeed/speedtest" data-i18n="classic.source">Source code</a> |
There was a problem hiding this comment.
5. Swedish selection resets across views 🐞 Bug ≡ Correctness
The translated navigation links still point to URLs without the current lang parameter. A visitor who selected ?lang=sv in a browser whose preferred language is not Swedish returns to another view in that browser language or English.
Agent Prompt
## Issue description
Navigation between localized views drops the visitor's explicit Swedish selection.
## Fix Focus Areas
- index-classic.html[572-573]
- index-modern.html[80-82]
- stability.html[279-280]
- frontend/javascript/i18n.js[8-14]
## Recommended Fix
Carry a supported, explicitly selected `lang` parameter into links between the classic, modern, and stability views, while retaining each link's existing design parameter where applicable.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| <h2 data-i18n="privacy.title">Privacy Policy</h2> | ||
| <p data-i18n="privacy.telemetry">This HTML5 speed test server is configured with telemetry enabled.</p> | ||
| <h4 data-i18n="privacy.collect-title">What data we collect</h4> |
There was a problem hiding this comment.
6. Classic privacy terms remain in english 🐞 Bug ≡ Correctness
index-classic.html binds translations to the privacy headings and list items but leaves the explanatory paragraphs, consent and removal terms, and close control as unbound English text. With ?lang=sv, those parts of the privacy policy remain English beside the translated sections; the server and test-ID labels also remain English.
Agent Prompt
## Issue description
The classic view localizes selected headings and items but leaves substantial privacy-policy text and several interface labels in English.
## Fix Focus Areas
- index-classic.html[529-533]
- index-classic.html[564-566]
- index-classic.html[575-615]
- frontend/locales/en.json[21-42]
- frontend/locales/sv.json[21-42]
## Recommended Fix
Add bindings for the remaining privacy paragraphs, list text, close control, server label, and test-ID label. Reuse existing catalog keys where available and add matching English and Swedish entries for the rest.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
||
| <button class="small inverted hidden" id="share-results"> | ||
| Share results | ||
| <span data-i18n="share.results">Share results</span> |
There was a problem hiding this comment.
7. Modern share control stays in english 🐞 Bug ≡ Correctness
frontend/index.html adds a share.results binding to its button, but the corresponding button in index-modern.html remains unbound. Visitors using the root modern view with ?lang=sv see “Share results” after the other bound controls have been translated.
Agent Prompt
## Issue description
The root modern page omits the share-button translation binding added to its frontend counterpart.
## Fix Focus Areas
- frontend/index.html[72-75]
- index-modern.html[75-78]
## Recommended Fix
Add the `share.results` binding to the button in `index-modern.html`, matching `frontend/index.html`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Adds dependency-free JSON localization for LibreSpeed interfaces, with complete English and Swedish catalogs. The browser language is selected automatically, and
?lang=svexplicitly selects Swedish.The modern UI, classic UI, and stability test use the shared catalog; dynamic status messages are covered too.
Validation: browser-verified all three views with
?lang=sv; l10n-lint reports 0 errors; svlang writing rules pass; Gitleaks reports 0 findings.