|
143 | 143 | DEFAULT_TAB_WIDTH = 4 |
144 | 144 |
|
145 | 145 |
|
146 | | -SECRET_SALT = urandom(16) |
147 | | -# MD5 function was previously used for this; the "md5" prefix was kept for |
148 | | -# backwards compatibility. |
| 146 | +# _hash_text is used to temporarily replace characters and HTML which |
| 147 | +# should be ignored by the processor. |
| 148 | +# |
| 149 | +# Afterwards, we find stuff that looks like 'key32-???' and convert it back |
| 150 | +# to the escaped things. |
| 151 | +HEX_DIGITS = "0123456789abcdef" |
149 | 152 | def _hash_text(s: str) -> str: |
150 | | - return 'md5-' + sha256(SECRET_SALT + s.encode("utf-8")).hexdigest()[32:] |
| 153 | + h = hash(s) # Not cryptographically sure, but that's fine |
| 154 | + h = h*2 + int(h>0) # As a positive number |
| 155 | + h = hex(abs(h))[2:34] # Convert to hex. |
| 156 | + h = '0'*(32-len(h)) + h # Pad if needed |
| 157 | + return 'key32-' + h |
| 158 | +HASH_REGEX = r'key32-[0-9a-f]{32}' |
151 | 159 |
|
152 | 160 | # Table of hash values for escaped characters: |
153 | 161 | g_escape_table = {ch: _hash_text(ch) |
@@ -1341,7 +1349,7 @@ def _is_code_span(index, token): |
1341 | 1349 | except IndexError: |
1342 | 1350 | return False |
1343 | 1351 |
|
1344 | | - return re.match(r'<code>md5-[A-Fa-f0-9]{32}</code>', ''.join(peek_tokens)) |
| 1352 | + return re.match('<code>' + HASH_REGEX + '</code>', ''.join(peek_tokens)) |
1345 | 1353 |
|
1346 | 1354 | def _is_comment(token): |
1347 | 1355 | if self.safe_mode == 'replace': |
@@ -2491,7 +2499,7 @@ def sub_hash(self, match: re.Match) -> str: |
2491 | 2499 | def test(self, text): |
2492 | 2500 | if self.md.order < Stage.ITALIC_AND_BOLD: |
2493 | 2501 | return '*' in text or '_' in text |
2494 | | - return self.hash_table and re.search(r'md5-[0-9a-z]{32}', text) |
| 2502 | + return self.hash_table and re.search(HASH_REGEX, text) |
2495 | 2503 |
|
2496 | 2504 |
|
2497 | 2505 | class _LinkProcessorExtraOpts(TypedDict, total=False): |
|
0 commit comments