chore(composer): silence Codacy's 18 findings, all of them false positives

Checked each one rather than blanket-suppressing.

Python (Opengrep, 4). The Jinja2 environment disables autoescaping on
purpose -- these templates emit Python, not HTML, and escaping a quote in
a plugin name would corrupt the generated source. The safety comes from
the values instead (_safe_int, _rgb_expr, _reject_source_breaking), which
test_composer_code_injection.py covers. Both the Environment( line and
the autoescape= line are reported separately, so each needs its own
nosemgrep. The two "Flask route directly returning a formatted string"
hits are not routes at all: _as_rgb_filter is a Jinja filter and
_rgb_tuple a private helper, both emitting a Python tuple literal with
every channel coerced to int first.

JavaScript (Biome + ESLint, 14). useQwikValidLexicalScope fired five
times on plain arrow-function consts -- it is a Qwik rule about the $()
serialization boundary, and this is Alpine.js. noUnusedVariables flagged
composerApp(), which the template calls as x-data="composerApp()", where
the linter cannot see it. The eight detect-object-injection hits are
array indices (this.elements[idx], rawVals[i]) or lookups on
module-private maps keyed by an internal element type; none takes an
attacker-supplied property name, so disabled per file with the reason
rather than eight times inline.

.codacy.yml only supports exclude_paths, so these have to be inline.
Matches the repo's existing "eslint-disable-line <rule> -- <reason>" form.

372 composer tests pass, including the 14 JS contract tests that parse
these two files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
This commit is contained in:
ChuckBuilds
2026-09-07 11:20:47 -04:00
co-authored by Claude Opus 5
parent 2f42d179f6
commit ea54e56bed
3 changed files with 28 additions and 4 deletions
@@ -7,6 +7,12 @@
* - localStorage autosaves on every mutation (debounced 1.5s)
* - composer_version in payload allows future server-side migration
*/
/* eslint-disable security/detect-object-injection --
Every hit in this file is either an array index (this.elements[idx],
rawVals[i]) or a lookup on a module-private map keyed by an internal
element type (_HANDLE_CURSORS, ELEMENT_DEFAULTS, previewValues). None of
them takes an attacker-supplied property name, so none can reach a
prototype. Disabled per file rather than eight times inline. */
// ── Template library ─────────────────────────────────────────────────────────
const COMPOSER_TEMPLATES = [
@@ -186,6 +192,7 @@ function _debouncedAutosave(payload) {
}
// ── Main component ───────────────────────────────────────────────────────────
// biome-ignore lint/correctness/noUnusedVariables: called from the template as x-data="composerApp()" (composer.html), which the linter cannot see.
function composerApp() {
return {
// ── Plugin metadata ───────────────────────────────────────────────
@@ -836,7 +843,9 @@ function composerApp() {
x = Math.round(x / this.snapSize) * this.snapSize;
y = Math.round(y / this.snapSize) * this.snapSize;
}
// biome-ignore lint/correctness/useQwikValidLexicalScope: not Qwik -- this is an Alpine.js component, and the rule is about Qwik's $() serialization boundary, which does not exist here.
const clampX = v => Math.max(-this.MATRIX_W, Math.min(this.MATRIX_W * 2, v));
// biome-ignore lint/correctness/useQwikValidLexicalScope: not Qwik -- this is an Alpine.js component, and the rule is about Qwik's $() serialization boundary, which does not exist here.
const clampY = v => Math.max(-this.MATRIX_H, Math.min(this.MATRIX_H * 2, v));
if (el.type === 'line') {
el.x0 = clampX(x); el.y0 = clampY(y);