3 pontos por GN⁺ 2026-02-04 | 1 comentários | Compartilhar no WhatsApp
  • Recentemente, trechos de citações de e-mails antigos circularam no Twitter, levantando a dúvida sobre por que surgem sinais de igual (=) no fim das frases
  • Esse símbolo aparece por causa do processo de codificação quoted-printable, sendo usado para indicar a continuação da linha quando uma linha longa é forçadamente quebrada
  • No envio de e-mails, usa-se CRLF (carriage return + line feed) como quebra de linha, mas ao converter isso para o NL do Unix, o algoritmo de decodificação pode funcionar incorretamente, fazendo o sinal de igual permanecer ou causando perda de caracteres
  • O sinal de igual também é usado para representar caracteres não ASCII (ex.: =C2=A0), e um decodificador defeituoso pode simplesmente substituí-los, gerando erros
  • A causa do problema é uma combinação de lógica de decodificação com bug e tratamento de conversão inadequado, o que mostra que quem processou o e-mail tinha pouca familiaridade técnica

A origem dos sinais de igual (=) em citações de e-mails

  • Nos últimos dias, várias citações de e-mails antigos foram compartilhadas no Twitter, e o aparecimento de sinais de igual no fim das frases chamou atenção

    • O autor rebate interpretações de que isso seria código ou erro de OCR (reconhecimento óptico de caracteres)
    • Na realidade, trata-se de um erro de processamento de codificação ocorrido durante a conversão para um formato mais legível
  • Antigamente, e-mails eram texto simples, mas para lidar com linhas longas e caracteres especiais foi introduzida a codificação quoted-printable

    • Ao dividir linhas longas, adiciona-se um sinal de igual (=) ao fim da linha para indicar que “esta linha continua”
    • Nesse caso, o sinal de igual é seguido por CRLF (carriage return + line feed)

Codificação de quebras de linha e erros de decodificação

  • Servidores de e-mail usam CRLF como padrão de quebra de linha, enquanto sistemas Unix usam apenas NL

    • Durante a conversão, um byte é removido, e se o decodificador tratar isso de forma incorreta, o sinal de igual pode permanecer ou caracteres podem desaparecer
    • Como exemplo, se “non- =CRLF cloven” for processado incorretamente, pode virar “non- loven”, com o c desaparecendo
  • Algumas implementações tratam um sinal de igual no fim da linha apagando dois caracteres

    • Esse algoritmo falha em arquivos no formato Unix, fazendo com que o sinal de igual permaneça no texto

Outro uso do sinal de igual: codificação de caracteres não ASCII

  • O sinal de igual também é usado na codificação de caracteres não ASCII

    • Ex.: =C2=A0 significa non-breaking space (espaço inquebrável)
    • Ele aparece com frequência em corpos de e-mail ao representar indentação ou caracteres especiais
  • O autor estima que alguns conversores apenas fizeram substituições simples (search-replace) em =C2, =A0 etc., em vez de usar um decodificador adequado

Contexto técnico e padrão

  • O padrão RFC 2045 define a codificação quoted-printable como algo voltado ao transporte

    • Após o recebimento, ela deveria ser decodificada e armazenada como texto limpo
    • Porém, em implementações reais, essa etapa às vezes é omitida, causando erros frequentes no tratamento de quebras de linha
  • No código de exemplo, (quoted-printable-decode-string "he=\nllo") é restaurado corretamente para "hello"

    • Isso acontece porque foi reutilizado um algoritmo que pressupõe CRLF no contexto de servidores SMTP
    • Em arquivos baseados em Windows, funciona normalmente, mas em Unix falha

Conclusão

  • Os sinais de igual em citações de e-mails são resquícios da codificação quoted-printable e resultado da combinação entre falhas no tratamento de quebras de linha e na decodificação de caracteres não ASCII
  • A causa fundamental do problema é uma implementação imprecisa do decodificador e erros na conversão de codificação
  • O autor resume isso como “um problema técnico e o resultado de um processamento incorreto”, enfatizando a necessidade de seguir cuidadosamente os padrões no processo de conversão de e-mails

1 comentários

 
GN⁺ 2026-02-04
Comentários do Hacker News
  • O protagonista deste texto é Lars Ingebrigtsen, a pessoa que escreveu o manual do Gnus, o pacote leitor de e-mail/Usenet do Emacs
    O manual dele é espirituoso e informativo, e mostra um entendimento de parsing de e-mail muito mais profundo do que o da maioria das pessoas
    O manual pode ser visto aqui, e há outra versão neste link

    • Além do manual, ele também é desenvolvedor do próprio Gnus
      Eu me lembro da época em que ele estava criando o Gnus pela primeira vez na Universidade de Oslo (UiO)
      Entre os estudantes do nosso departamento de informática, ele era uma pequena estrela do desenvolvimento, e todo mundo usava Emacs e Gnus
  • Este caso é um exemplo clássico de “saber o bastante para ser perigoso
    Eu sabia que e-mail não era só texto simples, mas não sabia que não dá para tratar a decodificação de quoted-printable com substituição simples
    É o mesmo tipo de bug de tentar fazer parsing de HTML diretamente com regex: no começo parece funcionar, mas depois acaba em uma situação em que uma prova apresentada ao Congresso fica cheia de sinais de '='

    • Em relação a isso, compartilharam uma famosa resposta no Stack Overflow que explica com humor por que não se deve fazer parsing de HTML com regex
    • Como a saída normalmente continua legível, ninguém percebe o problema, e ele só vem à tona anos depois, quando é apresentado como evidência ao Congresso
    • Termina com a piada: “nossos melhores profissionais estão cuidando disso agora”
  • Houve uma pergunta: “por que servidores de e-mail odeiam linhas longas?”

    • O SMTP é um protocolo baseado em linhas, então o corpo da mensagem também é transmitido linha por linha
      O servidor precisa fazer parsing dos cabeçalhos, então não pode tratar tudo como um simples blob binário
      O IMAP exige parsing completo no servidor, e o POP3 foi feito para um único dispositivo, então hoje já não faz muito sentido
    • No passado, os e-mails eram processados linha por linha com buffers de tamanho fixo
      A RFC 821 limitava o comprimento de linha a 1000 bytes, e por compatibilidade era comum quebrar em até 80 caracteres
      Por isso, a codificação Base64 também insere quebras de linha a cada 76 caracteres
    • Quando o SMTP foi projetado, a memória era extremamente limitada
      Por exemplo, o PDP-11 tinha cerca de 512 KB e o VAX-11, cerca de 2 MB, e os programadores contavam memória byte por byte
    • Mostraram diretamente o fluxo de comandos do SMTP, explicando a estrutura da comunicação com HELO, MAIL FROM, RCPT TO, DATA etc.
    • Também mencionaram a rede universitária dos anos 1980, a BITNET, lembrando que naquela época também havia limites de tamanho de linha
      Documentos relacionados podem ser vistos na documentação oficial da IBM e na Wikipedia
  • No começo, achei que o texto seria sobre o significado de operadores como = == === .=. <== ==> <<== ==>> (==) => =~=

    • Surgiu a piada: “isso é Haskell para formigas?”
    • Mas disseram que o conteúdo real era muito mais interessante
  • Eu, pessoalmente, já escrevi um software de arquivamento de e-mails
    A parte mais difícil foi lidar com os casos de borda em arquivos .eml acumulados por mais de 20 anos
    O conceito parece simples, mas e-mail é surpreendentemente complexo

    • Os padrões de e-mail não foram feitos do zero; são um padrão amaldiçoado montado à força a partir de sistemas anteriores
      Validar endereços de e-mail, na prática, é algo quase impossível
    • Também fiz um cliente de e-mail para console, 25% em C++ e 75% em Lua, com a UI e o processamento definidos assim
      Teve alguns poucos usuários por alguns anos, mas o tratamento de MIME foi a parte mais dolorosa
  • O que achei interessante não foi tanto o sinal de '=', mas o fenômeno de sumirem caracteres ao redor dele
    Parecia um erro off-by-one: em vez de apagar o '=', parte do texto real é que parecia desaparecer
    Talvez uma conversão de CRLF/LF tenha relação com isso

    • O artigo original explica exatamente o motivo
    • É assim que surgem esses mistérios de caracteres desaparecendo em provas
  • Fiquei curioso sobre por que esse problema está aparecendo agora
    Nos últimos dias, as pessoas vêm postando e-mails antigos no Twitter, e eu me perguntava o motivo

    • Provavelmente é por causa da divulgação de e-mails relacionados a Epstein
    • Disseram que o DOJ realmente divulgou mais e-mails de Epstein
  • Alguém levantou a possibilidade de que a causa do problema não seja o Gmail, mas sim uma transformação em um servidor intermediário
    Além da conversão CRLF→LF, aplicar quoted-printable duas vezes também pode deixar sinais de '=', então pode ter havido dois servidores de e-mail envolvidos

    • Em alguns PDFs aparece metadata plist do Apple Mail.app, então é possível que tenham sido extraídos de um formato interno
    • Esse tipo de coisa acontece com frequência na coleta de evidências legais
      Na prática, um estagiário sem especialização junta os dados com ferramentas simples, eles passam por várias conversões e o formato se estraga
      O original já foi destruído, e o que sobra são apenas fragmentos de dados com a forma preservada
    • Às vezes isso acontece ao importar os e-mails para um arquivo PST do MS Outlook
    • Não parece um dump único do Gmail, mas sim o resultado de vários sistemas “tentando ajudar” e alterando os dados no processo
    • Houve quem dissesse que essa hipótese parece a mais convincente
  • O artigo no archive.today também mostra o mesmo problema de quoted-printable quebrado
    Os links relacionados são pastes.io/correspond e a thread no HN

  • Disseram que seria bom existir um visualizador de .eml que decodificasse quoted-printable automaticamente ao abrir e-mails baixados do Outlook