Skip to content

fix(fpc): corrige hash de headers com range e overflow checking - #620

Merged
regyssilveira merged 1 commit into
HashLoad:masterfrom
regyssilveira:codex/fix-fpc-header-hash-range-checks
Oct 20, 2026
Merged

regyssilveira merged 1 commit into
HashLoad:masterfrom
regyssilveira:codex/fix-fpc-header-hash-range-checks

Conversation

@regyssilveira

Copy link
Copy Markdown
Contributor

Problema

O DJB2 de THorseHeaderComparer.GetHashCode dependia do truncamento implícito de valores maiores que 32 bits. Com range checking ativado no FPC, o cálculo de headers comuns como Content-Type e Authorization podia lançar ERangeError, impedindo operações do dicionário e a extração dos headers da requisição.

A falha foi reproduzida no FPC 3.2.2/Linux x86_64 com -Cr e com -Cr -Co. Nessa plataforma, ativar apenas -Co não reproduziu a exceção; o problema observado foi o erro de faixa ao converter o resultado para DWord.

Solução

O cálculo usa um intermediário QWord e aplica explicitamente a máscara de 32 bits antes da conversão:

Result := DWord((QWord(Result) * 33 + Ord(LChar)) and QWord($FFFFFFFF));

Isso preserva o DJB2 módulo 2³² e seus hashes anteriores. O intermediário é limitado a (2³² - 1) * 33 + Ord(LChar), e o valor convertido já está dentro da faixa de DWord. O contrato de IEqualityComparer<string> continua retornando DWord, sem depender de desabilitar as verificações de range/overflow e sem introduzir alocações de strings no cálculo.

Testes de regressão

Adiciona tests/fpc-header-hash, com 4 grupos e 63 verificações:

  • Vetores DJB2 conhecidos, incluindo resultados acima de MaxInt, chave vazia e equivalência entre maiúsculas/minúsculas ASCII.
  • Entrada longa de 4.096 caracteres, validando as reduções sucessivas a 32 bits.
  • Inserção, busca, atualização e remoção no dicionário real de headers, sem duplicar chaves que diferem apenas em caixa.
  • Extração de Content-Type e Host por THorseCoreParamHeader.GetHeaders a partir de uma requisição FPC.

O script recompila o teste e as units do Horse com -B -Cr -Co, habilita diagnóstico de memória com -gh e retorna erro em falhas de compilação, verificações ou blocos não liberados. O programa também recusa compilação sem range e overflow checking ativados.

Antes da correção, os quatro grupos falharam com ERangeError, e o teste retornou código 1. Após a correção, todos passaram:

Ambiente/configuração Resultado
FPC 3.2.2, Linux x86_64, padrão, -Cr -Co 63 verificações, 0 falhas
FPC 3.2.2, Linux x86_64, Epoll, -Cr -Co 63 verificações, 0 falhas
Delphi 13 Florence, padrão 91 testes de parâmetros e API HTTP, 0 falhas/erros

Nenhum vazamento foi reportado pelo heaptrc nos testes FPC. git diff --check também passou.

Os testes FPC exercitam as classes diretamente, sem abrir servidor HTTP; a validação HTTP acima foi executada em Delphi. A expressão corrigida é exclusiva do caminho FPC.

CI e reprodução

Integra a regressão ao job FPC estável e ao job FPC trunk existente, executando as configurações padrão e Epoll em ambos. A execução local cobriu FPC 3.2.2; os resultados de trunk serão fornecidos pelos checks desta PR.

sh tests/fpc-header-hash/run-header-hash-test.sh
sh tests/fpc-header-hash/run-header-hash-test.sh -dHORSE_PROVIDER_EPOLL

@regyssilveira
regyssilveira merged commit 999f57a into HashLoad:master Oct 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant