From 1d83bec7d1e2fe75092d5e187d410c75956fc3cb Mon Sep 17 00:00:00 2001 From: Ramsey McGrath Date: Sat, 15 Aug 2026 02:50:30 -0400 Subject: [PATCH] fix: source TemplateRenderError from canonical exceptions module CodeQL #783 (py/useless-except) flagged the `except TemplateRenderError` handler in pcileech_generator. The name was imported from the templating package, whose __init__ sets `TemplateRenderError = None` on its ImportError fallback. In that degraded state the handler becomes `except None`, raising TypeError at match time and masking the real SystemVerilog-generation error. Import TemplateRenderError from pcileechfwgenerator.exceptions, where it is defined unconditionally and is the same class template_renderer raises, so it can never be None. Adds a regression test that reproduces the fallback. --- src/device_clone/pcileech_generator.py | 2 +- ...cileech_generator_template_error_import.py | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/test_pcileech_generator_template_error_import.py diff --git a/src/device_clone/pcileech_generator.py b/src/device_clone/pcileech_generator.py index 99140f9b..a786d757 100644 --- a/src/device_clone/pcileech_generator.py +++ b/src/device_clone/pcileech_generator.py @@ -34,6 +34,7 @@ from pcileechfwgenerator.exceptions import ( PCILeechGenerationError, PlatformCompatibilityError, + TemplateRenderError, ) from pcileechfwgenerator.pci_capability.msix_bar_validator import ( validate_msix_bar_configuration, @@ -50,7 +51,6 @@ from pcileechfwgenerator.templating import ( AdvancedSVGenerator, TemplateRenderer, - TemplateRenderError, ) from pcileechfwgenerator.templating.tcl_builder import format_hex_id diff --git a/tests/test_pcileech_generator_template_error_import.py b/tests/test_pcileech_generator_template_error_import.py new file mode 100644 index 00000000..56ff52c4 --- /dev/null +++ b/tests/test_pcileech_generator_template_error_import.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +"""Regression tests for the ``TemplateRenderError`` import in pcileech_generator. + +CodeQL alert #783 (py/useless-except) flagged the ``except TemplateRenderError`` +handler in ``pcileech_generator._generate_systemverilog_modules``. The root cause +is the import source: ``TemplateRenderError`` was pulled from the +``pcileechfwgenerator.templating`` package, whose ``__init__`` sets +``TemplateRenderError = None`` when its optional ``template_renderer`` import +fails (see ``src/templating/__init__.py``). In that degraded state the handler +becomes ``except None``, which raises ``TypeError`` at match time and masks the +real SystemVerilog-generation error. + +The fix imports ``TemplateRenderError`` from the canonical +``pcileechfwgenerator.exceptions`` module, where it is defined unconditionally +and can never be ``None`` -- while remaining the exact same class object that +``template_renderer`` raises. +""" + +import importlib +import sys + +import pytest + +import pcileechfwgenerator.exceptions as exceptions_mod + +PG_MODULE = "pcileechfwgenerator.device_clone.pcileech_generator" + + +def _reload_pcileech_generator(): + """Import (or re-import) the pcileech_generator module fresh.""" + sys.modules.pop(PG_MODULE, None) + return importlib.import_module(PG_MODULE) + + +def test_template_render_error_is_canonical_exception(): + """In normal state the handler name is a real, canonical exception class.""" + pg = importlib.import_module(PG_MODULE) + + assert isinstance(pg.TemplateRenderError, type) + assert issubclass(pg.TemplateRenderError, BaseException) + # Must be the identical class template_renderer actually raises. + assert pg.TemplateRenderError is exceptions_mod.TemplateRenderError + + +def test_template_render_error_survives_templating_fallback(monkeypatch): + """Regression for #783: the handler name must stay a valid exception class + even when the templating package takes its ImportError fallback and sets + ``TemplateRenderError = None``. + + Pre-fix this fails because pcileech_generator sourced the name from the + templating package (binding ``None``); post-fix it passes because the name + comes from ``pcileechfwgenerator.exceptions``. + """ + templating_pkg = importlib.import_module("pcileechfwgenerator.templating") + + # Reproduce exactly what src/templating/__init__.py does on ImportError. + monkeypatch.setattr(templating_pkg, "TemplateRenderError", None, raising=False) + # Ensure the module body re-executes its imports under the degraded package. + monkeypatch.delitem(sys.modules, PG_MODULE, raising=False) + + pg = _reload_pcileech_generator() + + assert pg.TemplateRenderError is not None, ( + "pcileech_generator.TemplateRenderError became None when the templating " + "package hit its ImportError fallback -- `except TemplateRenderError` " + "would raise TypeError at match time (CodeQL #783)." + ) + assert isinstance(pg.TemplateRenderError, type) + assert issubclass(pg.TemplateRenderError, BaseException) + + # A real error routed through the handler's class still behaves correctly. + with pytest.raises(pg.TemplateRenderError): + raise pg.TemplateRenderError("boom") + + +@pytest.fixture(autouse=True) +def _restore_pcileech_generator(): + """Guarantee a clean, canonical module is cached for subsequent tests.""" + yield + _reload_pcileech_generator() + + +if __name__ == "__main__": + pytest.main([__file__, "-v"])