O que são, afinal, esses sinais de igual (=)?
(lars.ingebrigtsen.no)- 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)
- Ao dividir linhas longas, adiciona-se um sinal de igual (
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
cdesaparecendo
-
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=A0significa non-breaking space (espaço inquebrável) - Ele aparece com frequência em corpos de e-mail ao representar indentação ou caracteres especiais
- Ex.:
-
O autor estima que alguns conversores apenas fizeram substituições simples (search-replace) em
=C2,=A0etc., 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-printablee 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
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
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 '='
Houve uma pergunta: “por que servidores de e-mail odeiam linhas longas?”
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
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
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
HELO,MAIL FROM,RCPT TO,DATAetc.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
= == === .=. <== ==> <<== ==>> (==) => =~=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
.emlacumulados por mais de 20 anosO conceito parece simples, mas e-mail é surpreendentemente complexo
Validar endereços de e-mail, na prática, é algo quase impossível
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
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
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
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
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
.emlque decodificasse quoted-printable automaticamente ao abrir e-mails baixados do Outlook