Skip to content

Commit 7879f8d

Browse files
committed
fix: Fix label and value escaping
Fix label and value escaping by defaulting to html escaping them. Provide Python and CLI args to allow reverting to old behavior of not escaping. Fixes #91
1 parent 67af667 commit 7879f8d

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,19 @@ Each threshold entry is used to define the upper bounds of the threshold. If you
351351
upper bound for your version number threshold you will need to provide an extreme upper bound -
352352
in this example it is `999.0.0`.
353353

354+
### Escaping
355+
356+
Badges are generated as .svg files, which utilize an XML-based markup language. Consequently,
357+
any HTML characters present in badge labels or values must be escaped to ensure proper
358+
representation. If you need to disable escaping, the following options are available:
359+
360+
- Python API
361+
- `escape_label=False`
362+
- `escape_value=False`
363+
- CLI
364+
- `--no-escape-label`
365+
- `--no-escape-value`
366+
354367
### Examples
355368

356369
#### Pylint using template

anybadge/badge.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from collections import OrderedDict
33
from pathlib import Path
44
from typing import Dict, Type, Optional, Union
5+
import html
56

67
from . import config
78
from .colors import Color
@@ -122,6 +123,8 @@ def __init__(
122123
value_format: Optional[str] = None,
123124
text_color: Optional[str] = None,
124125
semver: Optional[bool] = False,
126+
escape_label: Optional[bool] = True,
127+
escape_value: Optional[bool] = True,
125128
):
126129
"""Constructor for Badge class."""
127130
# Set defaults if values were not passed
@@ -209,6 +212,9 @@ def __init__(
209212
self.use_max_when_value_exceeds = use_max_when_value_exceeds
210213
self.mask_str = self.__class__._get_next_mask_str()
211214

215+
self.escape_label = escape_label
216+
self.escape_value = escape_value
217+
212218
def __repr__(self) -> str:
213219
"""Return a representation of the Badge object instance.
214220
@@ -333,6 +339,20 @@ def _get_svg_template(self) -> str:
333339
else:
334340
return self.template
335341

342+
@property
343+
def encoded_label(self) -> str:
344+
if self.escape_label:
345+
return html.escape(self.label)
346+
else:
347+
return self.label
348+
349+
@property
350+
def encoded_value(self) -> str:
351+
if self.escape_value:
352+
return html.escape(self.value_text)
353+
else:
354+
return self.value_text
355+
336356
@property
337357
def semver_version(self) -> Version:
338358
"""The semantic version represented by the value string.
@@ -638,8 +658,8 @@ def badge_svg_text(self) -> str:
638658
badge_text.replace("{{ badge width }}", str(self.badge_width))
639659
.replace("{{ font name }}", self.font_name)
640660
.replace("{{ font size }}", str(self.font_size))
641-
.replace("{{ label }}", self.label)
642-
.replace("{{ value }}", self.value_text)
661+
.replace("{{ label }}", self.encoded_label)
662+
.replace("{{ value }}", self.encoded_value)
643663
.replace("{{ label anchor }}", str(self.label_anchor))
644664
.replace("{{ label anchor shadow }}", str(self.label_anchor_shadow))
645665
.replace("{{ value anchor }}", str(self.value_anchor))

anybadge/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@ def parse_args(args):
155155
default=False,
156156
help="Treat value and thresholds as semantic versions.",
157157
)
158+
parser.add_argument(
159+
"--no-escape-label",
160+
action="store_true",
161+
default=False,
162+
help="Do not escape the label text.",
163+
)
164+
parser.add_argument(
165+
"--no-escape-value",
166+
action="store_true",
167+
default=False,
168+
help="Do not escape the value text.",
169+
)
158170
parser.add_argument(
159171
"args",
160172
nargs=argparse.REMAINDER,
@@ -217,6 +229,8 @@ def main(args=None):
217229
value_format=args.value_format,
218230
text_color=args.text_color,
219231
semver=args.semver,
232+
escape_label=not args.no_escape_label,
233+
escape_value=not args.no_escape_value,
220234
)
221235

222236
if args.file:

0 commit comments

Comments
 (0)