Resumo

  • A RFC 5229 introduziu set, expansão de strings e variáveis de correspondência, mas apenas quando o script declara explicitamente a capacidade variables.
  • A memória continuou limitada: as capturas dependem do fluxo de execução, os valores só ficam visíveis no script em andamento e limites de implementação podem truncá-los.

O filtro precisava de um pouco de memória, não de uma máquina maior

Em janeiro de 2008, o Sieve já tinha uma função definida: filtrar mensagens na hora da entrega final. A especificação básica o descrevia como uma linguagem útil, mas deliberadamente restrita. Ela não tinha variáveis nem laços e não podia chamar comandos do shell. Essas ausências não eram uma lista de recursos esquecidos à espera de qualquer extensão. Eram parte da fronteira do que um filtro escrito pelo usuário poderia solicitar ao servidor de e-mail.

A RFC 5229 ampliou uma pequena parte dessa fronteira. O script podia declarar require "variables", guardar uma string com nome por meio de set, reutilizá-la dentro de outra string e testar valores produzidos pelo próprio script. Uma correspondência bem-sucedida com curingas podia expor o resultado inteiro em ${0} e os trechos capturados em ${1}, ${2} e assim por diante. Uma regra poderia extrair o nome de uma lista de um cabeçalho e incorporá-lo ao caminho de uma pasta sem repetir o mesmo fragmento em vários lugares.

Isso não equivale a dar memória duradoura ao filtro. O texto da RFC limita a visibilidade ao script que está em execução. Não especifica um repositório compartilhado por toda a caixa postal, um registro de mensagens anteriores ou estado comum entre usuários. A palavra “variável” parece ampla; o objeto padronizado é menor: um nome associado a texto enquanto aquele script roda.

Declarar a capacidade também fazia parte do modelo de segurança

O script precisava pedir a capacidade antes de usá-la. Sem variables, o significado das strings não mudava silenciosamente. Em uma linguagem extensível, esse detalhe importa: uma função envolve não só uma operação, mas um acordo explícito entre o script e o interpretador de que ela está disponível.

As referências eram expandidas quando o fluxo chegava à instrução, usando os valores daquele momento, em uma única passagem. Uma variável inexistente virava uma string vazia; maiúsculas e minúsculas no nome não faziam diferença. A concisão tinha um custo: certos erros ficavam escondidos. Uma referência escrita incorretamente podia simplesmente sumir da string, sem acusar um valor ausente. Se o valor inserido contivesse outra referência ${...}, não haveria uma segunda expansão recursiva.

Os modificadores adicionados eram poucos: alterar a caixa das letras ASCII, mudar a primeira letra, escapar curingas e obter o comprimento da string. Havia também um teste string. Não surgiam operações aritméticas, laços ou execução de código arbitrário. O aumento de expressividade significava poder nomear e reutilizar algumas strings de maneiras definidas, não poder calcular qualquer coisa.

Uma captura depende da condição que de fato foi avaliada

Com variáveis de correspondência, o fluxo de controle passa a determinar de onde vêm os dados. A RFC 5229 exige testes em ordem, da esquerda para a direita, e encerramento antecipado quando o resultado lógico já está decidido. Em anyof (true, header :matches ...), por exemplo, o teste do cabeçalho nem chega a rodar; portanto, não produz captura. Uma correspondência posterior que tenha sucesso pode substituir a lista anterior. Uma tentativa malsucedida não fornece novos trechos. Em uma regra complexa, confiar em ${1} exige saber qual teste realmente foi executado.

Uma extensão posterior não herda automaticamente os efeitos de captura. Publicada três meses depois, a RFC 5173 estabelece uma distinção reveladora: com variables habilitada, referências dentro das chaves do teste body são expandidas; já os curingas usados nesse teste não podem preencher as variáveis de correspondência. Os documentos permitem algumas composições entre extensões, mas não fingem que operações apenas parecidas têm a mesma semântica.

Os limites mínimos tornam essa contenção concreta. Uma implementação precisava suportar pelo menos 128 variáveis, nomes com ao menos 32 caracteres, valores com pelo menos 4.000 caracteres e as capturas ${1} até ${9}. Se o valor ultrapassasse a capacidade real da implementação, a RFC recomendava detectar o problema na compilação, quando possível; se só fosse percebido durante a execução, o valor deveria ser truncado e isso não deveria ser tratado como erro. A seção de segurança alerta contra estruturas grandes e sensíveis nas variáveis e lembra que o remetente pode controlar o texto capturado.

Muitos anos de rascunhos não medem adoção

O histórico no Datatracker remonta aos primeiros rascunhos individuais, de março de 2003. Versões do grupo de trabalho Sieve aparecem a partir do fim de 2004, seguidas de várias revisões em 2005. O registro do IESG identifica a especificação como produto do grupo de trabalho Sieve Mail Filtering Language. A aprovação em 2006 e a publicação da RFC em janeiro de 2008 são etapas distintas. Essa cronologia não explica o tempo do processo nem informa quantos servidores adotaram a extensão.

A nota de Heng Lu sobre “Minimum Initial Specification” oferece uma lente para interpretar o mecanismo: require permite que uma base enxuta conviva com recursos futuros ativados localmente por cada script. “Running-Code Primacy” lembra que uma capacidade publicada não comprova que um servidor específico a implementa ou habilita. A análise de “Reality Layers” ajuda a separar o recurso declarado, o estado interno do interpretador, o comportamento do servidor e a experiência que aparece na caixa postal. São ferramentas analíticas posteriores, não evidências sobre a intenção dos autores da RFC.

O filtro passou a poder guardar o resultado de uma correspondência e reutilizar algumas strings nomeadas. Isso, por si só, não prova que ele se lembre de mensagens anteriores, autentique quem enviou ou confirme o destino final de uma mensagem. A mudança histórica da RFC 5229 não foi apagar as fronteiras do Sieve, mas tornar mais útil uma pequena passagem declarada de propósito.

Fontes