Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Python: NAMED_ARG_REGEX character-class bug [${1}] lets non-$-prefixed values ({, 1, }) be silently parsed as variable references

Abierto Apto para principiantes
#14,491 0 comentarios 0 reacciones 0 asignados Ver en GitHub

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
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
backend

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

python triage

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=1var does not match the [variable] grammar rule ("$" [valid-name]), so it should either be rejected with NamedArgBlockSyntaxError (consistent with arg1=Xvar, which is correctly rejected) or, if unquoted plain-text arguments were meant to be legal, treated as the literal text 1var. Either way arg1 should never end up holding the value of an unrelated kernel argument called var.
  • Actual: the call silently succeeds and arg1 is substituted with args["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-kernel 1.44.1 (PyPI), verified byte-for-byte identical against python/semantic_kernel/template_engine/blocks/named_arg_block.py on the current main branch.
  • 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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/semantic-kernel

Todos los issues de microsoft/semantic-kernel

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.