Skip to content

fix: upstream bug batch A + security hardening - #14

Merged
SomethingNew71 merged 6 commits into
masterfrom
fix/upstream-batch-a
Oct 2, 2026
Merged

SomethingNew71 merged 6 commits into
masterfrom
fix/upstream-batch-a

Conversation

@SomethingNew71

Copy link
Copy Markdown

Summary

Batch A of the upstream issue work. The triage of all 160 open wireviz/WireViz issues is in docs/plans/2026-10-02-upstream-issue-triage.md.

Upstream bug fixes

Security fixes for code already in v1.0.0 (found in review)

  • image.scale could hide a second <img> from check_dot_images. In untrusted mode, Graphviz then read a local image into PNG/PDF output.
  • A bare > in a label value (gauge, color in SHORT mode) could end a Graphviz HTML label early. All values are now escaped, image width/height must be numbers, and untrusted mode checks that every node label is well-formed.
  • Untrusted image files must be png/jpg/gif/webp and match their extension. Pillow no longer probes other decoders such as EPS (Ghostscript).
  • sanitize_svg no longer depends on ElementTree's global prefix table. WeasyPrint resets that table, which turned untrusted SVG into <ns0:svg>.

Review

Two Code Reviewer rounds (Opus) on this batch, plus fixes from the batch B and C reviews that belong here.

Test plan

  • pytest on Python 3.9, 3.12 and 3.14
  • Gallery: Graphviz source and BOM unchanged
  • All 27 gallery examples render in untrusted mode
  • CI green

Stacked PRs: this one, then batch B, then batch C.

🤖 Generated with Claude Code

…reviz#342, wireviz#487, wireviz#230, wireviz#300, wireviz#265, wireviz#292, wireviz#432

- wireviz#208: a wire number beyond the wire count, or an unknown wire label,
  raises a clear error (an unknown label used to render as the shield)
- wireviz#305: YAML is read with YAML 1.2 booleans, so NO/NC/ON/Yes stay text
  in labels; boolean attributes still accept yes/no/on/off
- wireviz#426, wireviz#342: empty component entries, empty and comment-only input
  give clear errors; an empty string is never read as a path
- wireviz#487: edges are written with each endpoint part quoted, so
  designators may contain ":"
- wireviz#230, wireviz#266: bare &, < and > in label text are escaped; tags and
  entities are kept; documented in syntax.md
- wireviz#300: ignore_in_bom also hides additional components; the diagram
  lists them in full because they have no BOM number
- wireviz#265: list attributes given as a single value (colors: DIN) raise a
  clear error that points at color_code
- wireviz#292: image: file.png is a short form of image: {src: file.png},
  and goes through the same untrusted-mode path checks
- wireviz#432, wireviz#465: loops accept pin labels (Connector.resolve_pin, shared
  with connections and mates); regression test for non-sequential pins
- wireviz#300: additional components get ignore_in_bom (default: inherit the
  parent), so a hidden connector can still list its terminals
- wireviz#230: only Graphviz HTML elements and HTML entity names are kept as
  markup; <VBAT>, a&b;c and <!-- --> in user text are escaped; gauge and
  length units are escaped too
- wireviz#208: wire s on a cable without a shield is an error
- quoted numeric wire and pin labels ('10') resolve in connections
- the empty-cable error names the cable
…check_dot_images

image.scale was written raw into the generated <img> tag. check_dot_images
removes the exact generated tag, so a second <img> hidden in scale went
with it, and Graphviz rasterized that file into PNG/PDF output in
untrusted mode. scale now accepts only Graphviz's five values and is
escaped. Present since v1.0.0; found in the batch B review.
…usted mode

Round-2 review of the batch A/B security fixes:
- translate_color output (SHORT mode returns user text) and gauge values
  are escaped; image.width/height must be positive numbers
- untrusted mode: check_html_label refuses a generated node label that
  is not well-formed or has unbalanced < > (the DOT parser ends a label
  where they balance, so a raw > turned the rest into DOT)
- untrusted mode: supplied images must be png/jpg/gif/webp and match
  their extension; Pillow opens them with formats=[...]
…ee prefix table

Other libraries (WeasyPrint) reset ElementTree's global namespace table,
after which every untrusted SVG was written as <ns0:svg> and shown as
plain text. The prefixes are registered again before each serialization,
and a lost prefix raises instead of producing broken output. Found in
the batch C review.
@SomethingNew71
SomethingNew71 merged commit 8ebf03e into master Oct 2, 2026
24 checks passed
@SomethingNew71
SomethingNew71 deleted the fix/upstream-batch-a branch October 2, 2026 22:51
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