zlib 1.3.1 no sgcWebSockets e no sgcOpenAPI | Blog eSeGeCe

zlib 1.3.1 no sgcWebSockets e no sgcOpenAPI

· Componentes

O zlib é uma das poucas partes de código C de terceiros dentro do sgcWebSockets. Ele dá suporte à extensão WebSocket permessage-deflate, portanto todo quadro comprimido que o seu servidor envia ou recebe passa por ele, e também cuida da codificação de conteúdo HTTP. O sgcOpenAPI compartilha o mesmo código fonte, então usa a mesma cópia. A partir da versão 2026.8.0 essa cópia passa do zlib 1.2.12 para o zlib 1.3.1.

A mudança é invisível na API. Nada no seu código precisa ser alterado, e o comportamento da compressão continua o mesmo. O que vale a pena explicar é por que a atualização de versão de uma pequena biblioteca C é bem mais do que trocar um arquivo, e o que fizemos para ter certeza de que ela é segura em todos os compiladores que suportamos.

O que a 1.3.1 corrige, e por que você não estava exposto

A correção mais destacada entre a 1.2.12 e a 1.3.1 é a CVE-2022-37434, uma leitura além dos limites do heap em inflate(). Ela só é alcançável quando a aplicação chamadora entrega ao zlib um gz_header cujo campo extra aponta para um buffer. O zlib então copia o campo extra do gzip para esse buffer, e na 1.2.12 essa cópia não tinha verificação de limites.

O sgcWebSockets nunca satisfez essa condição. Ele chama inflateGetHeader apenas com um gz_header inicializado com zeros, e nunca atribui head.extra, portanto o ramo afetado não podia ser alcançado. Verificamos isso no código fonte antes de decidir o que fazer, e afirmamos com clareza: aplicações compiladas com versões anteriores não estavam vulneráveis por esse caminho.

Ainda assim, atualizamos. As strings de versão são o que os scanners automatizados e os questionários de fornecedores leem, não os grafos de chamadas, e um cliente que executa uma análise de dependências não deveria precisar reconstruir o nosso raciocínio para encerrar um alerta. Atualizar encerra a conversa em vez de exigir que ela se repita indefinidamente.

Por que atualizar o zlib não é trocar um arquivo

O zlib é compilado dentro do seu executável em vez de ser distribuído como DLL, e é por isso que uma aplicação sgcWebSockets não tem nenhuma zlib1.dll ao lado dela. Essa vinculação é feita com arquivos de objeto pré-compilados, e o Delphi é exigente quanto ao formato deles. Atualizar o zlib significa, portanto, recompilar esses objetos, e não existe um conjunto, existem três.

Usado porFormatoCompilado com
Delphi 7 até XEOMFbcc32, ZEXPORT=__fastcall
XE2 e posteriores, Win32OMFbcc32, ZEXPORT=__cdecl
XE2 e posteriores, Win64COFFMSVC cl

Os dois conjuntos de 32 bits diferem na convenção de chamada, porque os compiladores mais antigos vinculam o zlib com a convenção de registradores do Delphi, enquanto o XE2 e posteriores usam cdecl. O conjunto de 64 bits é, mais uma vez, um formato de objeto diferente. Vale notar que o bcc64 não consegue produzi-lo, porque gera objetos ELF e o linker Win64 do Delphi quer COFF, então esse conjunto é compilado com o compilador da Microsoft.

Nada disso fica visível para você. É simplesmente a razão pela qual atualizar o zlib é um exercício de compilação e não um download.

Verificado em todos os compiladores, não apenas no mais recente

Objetos recompilados podem compilar sem erros e ainda assim estar errados, portanto um teste de vinculação não basta por si só. Cada compilador suportado foi usado para compilar e depois executar um programa que comprime um buffer, descomprime, compara byte a byte e verifica que os objetos vinculados informam a versão esperada.

uses
  sgcIdCTypes, sgcIdGlobal, sgcIdZLibHeaders;

var
  vPackedLen: TIdC_ULONG;
begin
  vPackedLen := SizeOf(vPacked);
  if compress(PIdAnsiChar(@vPacked[0]), vPackedLen,
              PIdAnsiChar(@vSrc[0]), SizeOf(vSrc)) <> 0 then
    raise Exception.Create('compress failed');

  WriteLn('zlib ', String(AnsiString(zlibVersion)));   // zlib 1.3.1
end;

Isso rodou em Delphi 7, Delphi 2007, Delphi 2009 e RAD Studio XE6 até 13, em Win32 e em Win64 onde a plataforma existe. Todas as 25 combinações passam e informam 1.3.1.

Um bug latente de 64 bits corrigido no caminho

A matriz revelou algo que não tinha nenhuma relação com a nova versão. No Delphi 10 Seattle, as compilações de 64 bits estavam selecionando os objetos de 32 bits, que não podem ser vinculados a um executável de 64 bits e produziam um erro Bad object file format. A causa era uma antiga condicional criada para contornar um problema específico do Seattle, que direcionava essa única combinação para o conjunto de objetos errado. O Seattle 64 bits agora usa os mesmos objetos de todos os outros destinos de 64 bits, e compila.

O sgcOpenAPI recebe a mesma atualização

O sgcOpenAPI compartilha o seu código fonte com o sgcWebSockets, zlib incluído, portanto passa para a 1.3.1 na mesma versão, sem nenhuma ação separada da sua parte.

O que você precisa fazer

Instale a 2026.8.0 e recompile os seus projetos. Não há propriedade a configurar, unidade a adicionar ou remover, nem mudança de distribuição, porque o zlib já estava dentro do seu executável e continua estando. Se você mantém uma lista de materiais de software para o seu próprio produto, atualize a entrada do zlib para 1.3.1 e pode eliminar qualquer observação sobre a CVE-2022-37434 que estivesse carregando.