Skip to content

Fix mutable defaults, security hardening, and bug fixes#623

Open
pjleduc wants to merge 4 commits intofatihak:mainfrom
pjleduc:pjleduc/fixes
Open

Fix mutable defaults, security hardening, and bug fixes#623
pjleduc wants to merge 4 commits intofatihak:mainfrom
pjleduc:pjleduc/fixes

Conversation

@pjleduc
Copy link
Copy Markdown

@pjleduc pjleduc commented Mar 15, 2026

Summary

  • Mutable default arguments: Replace dangerous =[] / ={} defaults with =None pattern across 9 files (display_manager, abstract_display, inky_display, mock_display, waveshare_display, image_utils, base_plugin, app_utils, config)
  • Security hardening: Strip newlines in API key values to prevent .env injection, replace os.system() with subprocess.Popen() for reboot/shutdown, use os.urandom() for Flask secret key, narrow bare except to except OSError
  • Bug fixes:
    • Calendar plugin: skip failed calendar URLs gracefully instead of crashing the entire plugin (fixes blank screen when one URL times out)
    • Weather plugin: fix Open-Meteo forecast off-by-one day label bug (same fix as Fix day label off-by-one in parse_open_meteo_forecast #613 — Open-Meteo returns local dates, not UTC)
    • Model: remove duplicate scheduled refresh logic that could cause incorrect refresh behavior
    • Refresh task: add 60s timeout to refresh_event.wait() to prevent indefinite hangs on manual updates
    • Plugin blueprint: return 400 instead of crashing with KeyError when plugin_id missing from form data

Test plan

  • Tested on Raspberry Pi Zero 2 W with Inky e-ink display (800x480)
  • All plugins (weather, calendar, RSS, comics, clock, etc.) confirmed working after changes
  • Calendar plugin correctly skips failing Outlook URLs and renders remaining calendars
  • Weather plugin shows correct day labels with Open-Meteo provider
  • Service runs stable for 48+ hours with no errors from these changes

🤖 Generated with Claude Code

pjleduc and others added 4 commits March 14, 2026 22:02
Replace dangerous mutable defaults (=[], ={}) with =None pattern
to prevent shared state bugs across function calls.

Files: display_manager, abstract_display, inky_display, mock_display,
waveshare_display, image_utils, base_plugin, app_utils, config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- apikeys.py: strip newlines to prevent .env injection
- settings.py: replace os.system() with subprocess.Popen()
- inkypi.py: use os.urandom() for secret key, narrow bare except
- plugin.py: graceful 400 on missing plugin_id, fix mutable default

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- calendar.py: skip failed calendar URLs instead of crashing plugin
- weather.py: fix Open-Meteo forecast day label off-by-one (PR fatihak#613)
- model.py: remove duplicate scheduled refresh logic
- refresh_task.py: add 60s timeout to prevent indefinite hangs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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