Skip to content

Commit

Permalink
Don’t use overlapping groups for regular expressions
Browse files Browse the repository at this point in the history
The section between 'rgb(' and the final ')' contains multiple overlapping
groups.

Since all three infinitely repeating groups accept spaces, a long string of
spaces causes catastrophic backtracking when it is not followed by a closing
parenthesis.

The complexity is cubic, so doubling the length of the malicious string of
spaces makes processing take 8 times as long.
  • Loading branch information
liZe committed Dec 31, 2020
1 parent 9c4a982 commit 063185b
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions cairosvg/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@
'transparent': (0, 0, 0, 0),
}

RGBA = re.compile(r'rgba\([ \n\r\t]*(.+?)[ \n\r\t]*\)')
RGB = re.compile(r'rgb\([ \n\r\t]*(.+?)[ \n\r\t]*\)')
RGBA = re.compile(r'rgba\((.+?)\)')
RGB = re.compile(r'rgb\((.+?)\)')
HEX_RRGGBB = re.compile('#[0-9a-f]{6}')
HEX_RGB = re.compile('#[0-9a-f]{3}')

Expand All @@ -212,14 +212,14 @@ def color(string, opacity=1):
if match:
r, g, b, a = tuple(
float(i.strip(' %')) / 100 if '%' in i else float(i) / 255
for i in match.group(1).split(','))
for i in match.group(1).strip().split(','))
return (r, g, b, a * 255 * opacity)

match = RGB.search(string)
if match:
r, g, b = tuple(
float(i.strip(' %')) / 100 if '%' in i else float(i) / 255
for i in match.group(1).split(','))
for i in match.group(1).strip().split(','))
return (r, g, b, opacity)

match = HEX_RRGGBB.search(string)
Expand Down

0 comments on commit 063185b

Please sign in to comment.