Python: NAMED_ARG_REGEX character-class bug [${1}] lets non-$-prefixed values ({, 1, }) be silently parsed as variable references
Maintainer thường phản hồi trong vòng 3 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 85/100
Hướng nghiên cứu
Bắt đầu tại python/semantic_kernel/template_engine/blocks/named_arg_block.py, dòng 21, và tái hiện các trường hợp NamedArgBlock được liệt kê để xác nhận hành vi của regex. Cập nhật việc khớp dạng biến để chỉ chấp nhận tiền tố $ nguyên văn, sau đó xác minh rằng $var vẫn được phân tích cú pháp và 1var, {var và }var gây ra NamedArgBlockSyntaxError.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
What happens
NamedArgBlock's parsing regex, NAMED_ARG_REGEX, is supposed to require a named argument's variable form to start with a literal $ (per the grammar: [parameter] ::= [variable] | [value] and [variable] ::= "$" [valid-name]). Because of a regex mistake, it instead accepts a variable reference whose first character is $, {, 1, or } and always treats the rest as the variable name, silently dropping that first character. This means unquoted, non-$-prefixed argument text that starts with 1, {, or } is silently reinterpreted as a variable substitution instead of raising a syntax error, and the value actually used at render time comes from an unrelated kernel argument instead of the text the template author wrote.
Where
python/semantic_kernel/template_engine/blocks/named_arg_block.py, line 21:
NAMED_ARG_REGEX = r"^(?P<name>[0-9A-Za-z_]+)[=]{1}(?P<value>[${1}](?P<var_name>[0-9A-Za-z_]+)|(?P<quote>[\"'])(?P<val>.[^\"^']*)(?P=quote))$"
The variable-form alternative is [${1}](?P<var_name>...). Inside a character class, {1} is not a quantifier, it is three literal characters {, 1, }. So [${1}] is a 4-character class matching any one of $, {, 1, } — not "a literal $, exactly once" as the {1} clearly was intended to express (that would need to be written outside the brackets, e.g. \$ or [$]).
Why
Confirmed directly against the regex and the real class, on semantic-kernel==1.44.1 (byte-identical to current main for this file):
from semantic_kernel.template_engine.blocks.named_arg_block import NamedArgBlock
for content in ["arg1=$var", "arg1={var", "arg1=1var", "arg1=}var"]:
b = NamedArgBlock(content=content)
print(content, "-> name=", b.name, "variable=", b.variable)
Output:
arg1=$var -> name= arg1 variable= content='$var' name='var'
arg1={var -> name= arg1 variable= content='{var' name='var'
arg1=1var -> name= arg1 variable= content='1var' name='var'
arg1=}var -> name= arg1 variable= content='}var' name='var'
All four are accepted and all four produce a VarBlock pointing at the variable named var, even though only the first one actually starts with $. The {, 1, and } prefixes are silently swallowed instead of causing a NamedArgBlockSyntaxError (which is what happens for any other non-$/non-quote prefix, e.g. arg1=Xvar is correctly rejected).
Full end-to-end repro (real rendering, not just the regex)
import asyncio
from semantic_kernel import Kernel
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.functions.kernel_function_decorator import kernel_function
from semantic_kernel.prompt_template.kernel_prompt_template import KernelPromptTemplate
from semantic_kernel.prompt_template.prompt_template_config import PromptTemplateConfig
class MyPlugin:
@kernel_function(name="echo")
def echo(self, arg1: str) -> str:
return f"GOT[{arg1}]"
kernel = Kernel()
kernel.add_plugin(MyPlugin(), plugin_name="my")
async def main():
args = KernelArguments(var="SECRET_VALUE")
template_str = "{{ my.echo arg1=1var }}" # arg1 is meant to be the literal text "1var"
tpl = KernelPromptTemplate(prompt_template_config=PromptTemplateConfig(template=template_str))
print(await tpl.render(kernel, args))
asyncio.run(main())
Output:
GOT[SECRET_VALUE]
Expected vs actual
- Expected:
arg1=1vardoes not match the[variable]grammar rule ("$" [valid-name]), so it should either be rejected withNamedArgBlockSyntaxError(consistent witharg1=Xvar, which is correctly rejected) or, if unquoted plain-text arguments were meant to be legal, treated as the literal text1var. Either wayarg1should never end up holding the value of an unrelated kernel argument calledvar. - Actual: the call silently succeeds and
arg1is substituted withargs["var"]("SECRET_VALUE"), not the text the template author wrote. The same happens for any unquoted, non-quoted value that happens to start with{or}.
Suggested fix
Move the quantifier out of the character class so only a literal $ starts the variable form, e.g.:
NAMED_ARG_REGEX = r"^(?P<name>[0-9A-Za-z_]+)=(?P<value>\$(?P<var_name>[0-9A-Za-z_]+)|(?P<quote>[\"'])(?P<val>.[^\"^']*)(?P=quote))$"
Environment
semantic-kernel1.44.1 (PyPI), verified byte-for-byte identical againstpython/semantic_kernel/template_engine/blocks/named_arg_block.pyon the currentmainbranch.- Python 3.13, Windows.
- Ngôn ngữ chính
- C#
- Star
- 28.6k
- Fork
- 4.8k
- Merge trung bình
- 2 ngày 12 giờ
- Pull request đã merge (30 ngày)
- 22
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/semantic-kernel
-
Python: Bug: Anthropic, Bedrock, Google AI and Vertex AI tool formatters ignore include_in_function_choices=FalseCó thể đã có người làm @wasim-builds đã nhận hôm nay. Đang mởpython triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
microsoft/semantic-kernel#14615 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Python: Bug: AnnotationContent and StreamingAnnotationContent to_element writes CitationType.X, so annotations in a rendered chat history fail to parseCó thể đã có người làm @CRYPTONIKAV đã nhận 3 ngày trước. Đang mởpython triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
microsoft/semantic-kernel#14590 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Python: Bug: TimePlugin timeZoneOffset and timeZoneName always return an empty stringCó thể đã có người làm @jeevan1098 đã nhận 2 ngày trước. Đang mởpython triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 80/100
microsoft/semantic-kernel#14583 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
.Net: gpt-image-1 is the default image model in the .NET OpenAI connector, and OpenAI shuts it down on October 23Có thể đã có người làm @nightcityblade đã nhận 14 ngày trước. Đang mở.NET triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
microsoft/semantic-kernel#14526 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Python: VolatileMemoryStore.get_batch and get_nearest_matches ignore with_embeddings=False (deepcopy result is discarded)Có thể đã có người làm @VANDRANKI đã nhận 16 ngày trước. Đang mởpython triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
microsoft/semantic-kernel#14522 ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của microsoft/semantic-kernel
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
sebastienros/jint#4282 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 76/100
pyrevitlabs/pyRevit#3792 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 60/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Update the about pageĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
fboucher/2d6-dungeon-app#256 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area: design documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
eyalgolan/statecraft-israel#883 ·
Maintainer thường phản hồi trong vòng 1 ngày