Skip to content

Commit 3c80baa

Browse files
authored
Fix <svg: prefix in the SVG output causing invalid markup when inlined within HTML documents (#412)
* Avoid `svg:` prefix in output by directly using the tag instead of `QName` for SVG namespace handling. Fixes #317 Fixes #353 * Update changes * Use tag directly, no need to detour
1 parent ca2a1a3 commit 3c80baa

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

CHANGES.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ WIP 8.x
4343
- **Added** ``GappedCircleModuleDrawer`` (PIL) to render QR code modules as non-contiguous circles. (BenwestGate in `#373`_)
4444
- **Added** ability to execute as a Python module: ``python -m qrcode --output qrcode.png "hello world"`` (stefansjs in `#400`_)
4545
- **Removed** the hardcoded 'id' argument from SVG elements. The fixed element ID caused conflicts when embedding multiple QR codes in a single document. (m000 in `#385`_)
46-
- Improved test coveraged (akx in `#315`_)
47-
- Fixed typos in code that used ``embeded`` instead of ``embedded``. For backwards compatibility, the misspelled parameter names are still accepted but now emit deprecation warnings. These deprecated parameter names will be removed in v9.0. (benjnicholls in `#349`_)
46+
- **Fixed** typos in code that used ``embeded`` instead of ``embedded``. For backwards compatibility, the misspelled parameter names are still accepted but now emit deprecation warnings. These deprecated parameter names will be removed in v9.0. (benjnicholls in `#349`_)
47+
- **Fixed** an issue where an ``<svg:`` prefix in the SVG output caused invalid markup when inlined within HTML documents. (bartTC in `#412`_)
4848
- Migrate pyproject.toml to PEP 621-compliant [project] metadata format. (hroncok in `#399`_)
49+
- Improved test coveraged (akx in `#315`_)
4950
- Implement Ruff rules and perform comprehensive code cleanup.
5051

5152
.. _#315: https://github.com/lincolnloop/python-qrcode/pull/315
@@ -54,6 +55,7 @@ WIP 8.x
5455
.. _#385: https://github.com/lincolnloop/python-qrcode/pull/385
5556
.. _#399: https://github.com/lincolnloop/python-qrcode/pull/399
5657
.. _#400: https://github.com/lincolnloop/python-qrcode/pull/400
58+
.. _#412: https://github.com/lincolnloop/python-qrcode/pull/412
5759

5860
8.2 (01 May 2025)
5961
-----------------

qrcode/image/styles/moduledrawers/svg.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class SvgQRModuleDrawer(BaseSvgQRModuleDrawer):
5353

5454
def initialize(self, *args, **kwargs) -> None:
5555
super().initialize(*args, **kwargs)
56-
self.tag_qname = ET.QName(self.img._SVG_namespace, self.tag)
5756

5857
def drawrect(self, box, is_active: bool):
5958
if not is_active:
@@ -72,7 +71,7 @@ def initialize(self, *args, **kwargs) -> None:
7271
def el(self, box):
7372
coords = self.coords(box)
7473
return ET.Element(
75-
self.tag_qname,
74+
self.tag,
7675
x=self.img.units(coords.x0),
7776
y=self.img.units(coords.y0),
7877
width=self.unit_size,
@@ -90,7 +89,7 @@ def initialize(self, *args, **kwargs) -> None:
9089
def el(self, box):
9190
coords = self.coords(box)
9291
return ET.Element(
93-
self.tag_qname,
92+
self.tag,
9493
cx=self.img.units(coords.xh),
9594
cy=self.img.units(coords.yh),
9695
r=self.radius,

qrcode/tests/regression/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import io
2+
3+
import pytest
4+
5+
import qrcode
6+
from qrcode.image import svg
7+
from qrcode.tests.consts import UNICODE_TEXT
8+
9+
10+
@pytest.mark.parametrize(
11+
"image_factory",
12+
[
13+
svg.SvgFillImage,
14+
svg.SvgFragmentImage,
15+
svg.SvgImage,
16+
svg.SvgPathFillImage,
17+
# svg.SvgPathImage, # Result does not contain <rect elements
18+
],
19+
)
20+
def test_svg_no_namespace_prefix(image_factory: svg.SvgFragmentImage):
21+
"""
22+
Test that SVG output doesn't contain <svg:rect> elements.
23+
24+
This regression test ensures that rect elements in SVG output are rendered as
25+
<rect> without the svg: namespace prefix, which can cause rendering issues in
26+
browsers, when loaded in HTML.
27+
28+
https://github.com/lincolnloop/python-qrcode/issues/353
29+
https://github.com/lincolnloop/python-qrcode/issues/317
30+
"""
31+
# Create a QR code
32+
qr = qrcode.QRCode()
33+
qr.add_data(UNICODE_TEXT)
34+
35+
img = qr.make_image(image_factory=image_factory)
36+
f = io.BytesIO()
37+
img.save(f)
38+
svg_content = f.getvalue().decode("utf-8")
39+
40+
# Check that there are no <svg:rect> elements in the output
41+
assert "<svg:rect" not in svg_content
42+
43+
# Check that there are <rect> elements in the output
44+
assert "<rect" in svg_content

0 commit comments

Comments
 (0)