Skip to content

Fix crash, security, and UI-freeze bugs found in full repository audit - #2

Merged
pQu4k3r merged 3 commits into
mainfrom
develop
Sep 7, 2026
Merged

Fix crash, security, and UI-freeze bugs found in full repository audit#2
pQu4k3r merged 3 commits into
mainfrom
develop

Conversation

@pQu4k3r

@pQu4k3r pQu4k3r commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

A full audit of the plugin (33 Python files, ~16k lines) plus the install/packaging layer surfaced several critical and high-severity issues. This PR fixes the ones that could be verified and validated by reading code alone (no Enigma2 hardware available in this environment to run the plugin live).

  • Crash bugs: plugin.py had day_selected/target_date referenced outside the conditional branches that assign them, causing NameError/UnboundLocalError when the API returns incomplete data. foreca_svg_map_viewer.py imported REGION_CENTERS/get_background_for_layer from a module that never defined them, causing an immediate ImportError on any wind-symbol SVG map. foreca_map_menu.py had a debug-loop leftover variable compared instead of the current layer's id, making the map layer filter behave inconsistently.
  • Security: removed hardcoded, real-looking Foreca API credentials from foreca_map_api.py (used as a fallback default and written into the generated .example config); tightened the saved credentials file to 0600 and dropped the needless execute bit on other saved config files; added host validation before trusting a third-party API response (rain_maps.py) to build subsequent outbound URLs; URL-encoded user search input in city_panel.py.
  • UI freezes + missing dependency: meteogram.py and moon_calendar.py ran blocking network/CPU-heavy work synchronously from onLayoutFinish, freezing the whole Enigma2 UI on screen open — both now background the work and marshal only widget updates back via reactor.callFromThread, matching the pattern already used elsewhere in the plugin. Fixed a thread-unsafe widget update in plugin.py. Added the missing Pillow dependency to CONTROL/preinst (the opkg/.ipk install path never installed it despite several modules importing PIL for map rendering).

Test plan

  • python3 -m py_compile passes on all changed Python files
  • sh -n passes on CONTROL/preinst
  • Reviewed each fix against the specific failure scenario it addresses (see commit messages for details)
  • Smoke-test on real Enigma2 hardware/emulator before wide release — not available in this environment

Not included (flagged as follow-up, not done here)

  • Fully backgrounding plugin.py's _load_favorite (core weather-refresh path, higher risk, needs hardware testing)
  • Python 2 / f-string incompatibility (needs a maintainer decision on whether PY2 support is still a goal)
  • slideshow.py HTTP→HTTPS switch (not verified whether the source host supports TLS)
  • Remaining low-severity/cosmetic findings from the audit

pQu4k3r and others added 3 commits September 7, 2026 08:38
- plugin.py: day_selected and target_date were only assigned inside
  conditional branches but referenced unconditionally afterward,
  causing NameError/UnboundLocalError crashes when the API returns
  fewer days than expected or the hourly forecast is empty.
- foreca_svg_map_viewer.py: removed an import of REGION_CENTERS and
  get_background_for_layer from foreca_map_viewer, which never
  defined them (ImportError on opening any wind-symbol SVG map).
  Defined both locally, mapped to background PNGs that actually
  exist under thumb/.
- foreca_map_menu.py: a debug-loop leftover variable was compared
  instead of the current layer's id when filtering layer 3 from the
  map menu, so filtering behaved inconsistently depending on API
  response ordering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UPpumFb2PP21ATpDwJBYBB
- foreca_map_api.py: replaced hardcoded, real-looking Foreca API
  credentials (used as a fallback default and written into the
  generated .example config) with the same placeholder values
  already used elsewhere in the file.
- plugin.py: the saved API credentials file is now chmod 600
  (previously inherited the process umask, typically world-readable);
  dropped the needless execute bit on other saved plain-data files
  (favorites/color/alpha configs), tightening 0o655 to 0o644.
- rain_maps.py: validate the tile-server host returned by
  api.rainviewer.com's JSON response before using it to build
  subsequent outbound tile-fetch URLs, instead of trusting it
  unconditionally.
- city_panel.py: URL-encode the user-entered city search term before
  interpolating it into the request URL, matching the existing
  correct pattern already used in foreca_weather_api.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UPpumFb2PP21ATpDwJBYBB
- plugin.py: _update_station_label ran in a background Thread but
  called self["station_name"].setText(...) directly from that
  thread instead of marshaling back to the UI thread, risking GUI
  corruption if the screen closes/rebuilds mid-fetch. Now wrapped
  in reactor.callFromThread, matching the pattern already used
  elsewhere in the file (_moon_api_callback).
- meteogram.py: fetch_data ran its network request and HTML/JSON
  parsing synchronously from onLayoutFinish, freezing the whole
  Enigma2 UI while it waited. Split into a background-thread worker
  that fetches/parses data and a UI-thread method that only
  populates widgets, connected via reactor.callFromThread.
- moon_calendar.py: load_calendar performed ~365 trig-heavy lunar
  position calculations synchronously from onLayoutFinish. Same
  treatment: computation moved to a background Thread, only the
  final widget population runs via reactor.callFromThread.
- CONTROL/preinst: the opkg (.ipk) install path never installed
  Pillow even though several plugin modules import it for map
  rendering, unlike installer.sh which already installs it
  correctly. Added the missing ${PY}-pillow install.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UPpumFb2PP21ATpDwJBYBB
@pQu4k3r
pQu4k3r merged commit 15801e5 into main Sep 7, 2026
6 checks passed
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.

1 participant