[Bug]: `graphify export svg` writes a graph.svg that is not well-formed XML when a label contains a control character
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
- #4244 của @Yyunozor — đã đóng, không merge
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- python
- Lĩnh vực
- data-visualization
Hướng nghiên cứu
Trong graphify/export.py, kiểm tra to_svg và cách sử dụng hiện có của _strip_xml_illegal trong to_graphml. Thêm hoặc mở rộng một bài kiểm thử hồi quy bên cạnh các bài kiểm thử cho #2897, bao quát các ký tự điều khiển trong nhãn nút và phần chú giải. Chạy các bài kiểm thử xuất dữ liệu tập trung; hoàn thành khi đầu ra SVG là XML đúng định dạng và các ký tự điều khiển được loại bỏ khỏi văn bản được vẽ.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Pre-flight checks
- I have checked the Troubleshooting section in the README
What happened?
A node or community label that contains a C0 control character (an ANSI escape from a pasted terminal capture, a form feed used as a section separator, a NUL) ends up in graph.svg. XML 1.0 forbids those characters, so the file is not well-formed. graphify export svg still prints graph.svg written and exits 0.
The same graph exports a well-formed graph.graphml. #2897 made to_graphml strip these characters and left to_svg out, for a reason given in #2899: to_svg does not crash, matplotlib only warns about a missing glyph and draws a box. That holds for a label without a pair of $ (between two of them, a control character can make matplotlib read invalid mathtext and to_svg raise ValueError), but the file it writes is not valid XML, and the command reports success.
Expected: a well-formed graph.svg, with the control character dropped from the drawn text, as to_graphml does.
Cause, in graphify/export.py: to_svg hands the raw node labels to nx.draw_networkx_labels and the raw community label to mpatches.Patch. With the default svg.fonttype, matplotlib's SVG backend writes each drawn string into a comment (<!-- text -->). Its comment escaping handles &, <, > and --, not control characters. _strip_xml_illegal is only called from to_graphml.
Steps to reproduce
mkdir svg-repro && cd svg-repro
printf '# Notes\n\n## Build \033[31mlog capture\033[0m\n\nSome text.\n\n## Deploy\n\nSee [[Notes]].\n' > notes.md
printf 'def helper():\n return 1\n\ndef main():\n return helper()\n' > app.py
graphify update .
graphify export svg
xmllint --noout graphify-out/graph.svg
graphify export graphml
xmllint --noout graphify-out/graph.graphml
The legend takes the same path. On a project with no control character in any heading, graphify export svg --labels labels.json with {"0": "Core \u001b[0mmodule", "1": "Other\u000cgroup"} gives the same xmllint error (<!-- Core [0mmodule (4) -->).
Error output or graph output
.../graphify/export.py:1409: UserWarning: Glyph 27 () missing from font(s) DejaVu Sans.
plt.savefig(output_path, format="svg", bbox_inches="tight",
graph.svg written - embeds in Obsidian, Notion, GitHub READMEs
graphify-out/graph.svg:513: parser error : xmlParseComment: invalid xmlChar value 27
<!-- Build [31mlog capture[0m -->
The parentheses of the warning hold the ESC character. xmllint exits 1 on graph.svg and 0 on graph.graphml. The heading becomes the node Build \x1b[31mlog capture\x1b[0m in graph.json.
Graphify version
0.9.80 (v8 @ 6478eb7)
Operating System
macOS
Python Version
3.12
Installation Method
built from source (git clone)
Additional Environment Details
uv sync --all-extras --frozen, matplotlib 3.10.9 (the uv.lock version); the same file is malformed with matplotlib 3.11.2. AST-only path (graphify update), no API key involved. Reproduced on a clean checkout of v8 at 6478eb7 (no local change).
Additional context
I have a small fix and can open a PR: pass the node labels and the legend text through _strip_xml_illegal in to_svg, with a regression test next to the #2897 tests.
- Ngôn ngữ chính
- Python
- Star
- 124k
- Fork
- 11.9k
- Merge trung bình
- 2 giờ 35 phút
- Pull request đã merge (30 ngày)
- 6
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Graphify-Labs/graphify
-
[Bug]: valid JSON with the wrong global-manifest shape bypasses recoveryCó thể đã có người làm @azizur100389 đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
Graphify-Labs/graphify#5020 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: malformed learning sidecar data can hide valid annotationsCó thể đã có người làm @azizur100389 đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Graphify-Labs/graphify#5019 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: graphify update skips or partially rebuilds a missing graph when the manifest survivesCó thể đã có người làm @azizur100389 đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
Graphify-Labs/graphify#5016 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Graphify-Labs/graphify#5006 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
extract --out <dir>: semantic cache never saved, docs missing from manifest (relative source_file resolved against --out)Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Graphify-Labs/graphify#4831 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của Graphify-Labs/graphify
Issue tương tự
-
community enhancement good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
Hochfrequenz/sapgui.mcp#1039 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
didi/helixharness#18 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
API /search : typer la réponseĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
dataforgoodfr/democracy-watch#46 · 1 reaction ·