Python: NAMED_ARG_REGEX character-class bug [${1}] lets non-$-prefixed values ({, 1, }) be silently parsed as variable references
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 85/100
Línea de trabajo
Empieza en python/semantic_kernel/template_engine/blocks/named_arg_block.py, línea 21, y reproduce los casos de NamedArgBlock indicados para confirmar el comportamiento de la expresión regular. Actualiza la coincidencia de la forma de variable para que solo se acepte un prefijo $ literal y, a continuación, verifica que $var siga analizándose y que 1var, {var y }var generen NamedArgBlockSyntaxError.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- C#
- Estrellas
- 28.6k
- Forks
- 4.8k
- Merge medio
- 12 h 20 min
- PR fusionados (30 d)
- 12
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/semantic-kernel
-
python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
microsoft/semantic-kernel#14490 ·
Los mantenedores suelen responder en 2 días
-
Python: [Python] structured_outputs_transform reuses ChatHistory across calls (prompt pollution)Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
microsoft/semantic-kernel#14483 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
.NET python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
microsoft/semantic-kernel#14482 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Python: [Python] as_agent_framework_tool drops parameter defaults (optionals become required)Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
microsoft/semantic-kernel#14481 ·
Los mantenedores suelen responder en 2 días
-
python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
microsoft/semantic-kernel#14460 ·
Los mantenedores suelen responder en 2 días
Todos los issues de microsoft/semantic-kernel
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
fluentassertions/fluentassertions#3353 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
Dificultad 2/5 Medio día Aptitud para principiantes 78/100
unoplatform/uno#24769 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
AvaloniaUI/Avalonia#22323 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
microsoft/onnxruntime-genai#2633 ·
Los mantenedores suelen responder en 1 día