Escaping the `repl` argument to `re.sub()`, `re.subn()`
未关闭
还没有人认领这个 Issue。
docs
topic-regex
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Documentation
It's not immediately obvious how to escape the repl (replacement for matches) argument to re.sub() and re.subn() if repl is chosen by a potentially hostile actor. Obviously, re.escape() isn't the answer, as that escapes far too much.
The right answer seems to be escaped_repl = raw_repl.replace(bslash, bslash*2) where bslash = '\\'. It might be worth adding this to the documentation.
Here's the code I used to empirically validate the "right answer" given above (checked on Python 3.8 & 3.12):
from __future__ import annotations
import re, sys
def escape_re_sub_repl(repl: str) -> str:
return repl.replace('\\', '\\\\')
def test_escape_re_sub_repl() -> None:
backslash = '\\'
assert len(backslash) == 1
base_regex = 'TARGET'
assert base_regex == re.escape(base_regex)
base_prefix = 'BEFORE:'
base_suffix = ':AFTER'
base_input = f'{base_prefix}{base_regex}{base_suffix}'
base_chars = tuple(chr(p) for p in range(sys.maxunicode + 1))
escaped_chars = tuple(f'{backslash}{c}' for c in base_chars)
test_cases = base_chars + escaped_chars
assert {len(f) for f in test_cases} == {1, 2}
for raw in test_cases:
repl = escape_re_sub_repl(raw)
got, change_count = re.subn(base_regex, repl, base_input)
assert change_count == 1
assert got == f'{base_prefix}{raw}{base_suffix}'
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先找到 re.sub() 和 re.subn() 的文档及其替换字符串规则。检查现有的 re.escape() 相关指南,然后记录针对恶意替换文本采用反斜杠加倍的方法,并根据提供的示例进行验证;当相关文档中的安全转义指南清晰明确时,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- documentation
- Issue 类型
- 文档
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 45/100