Skip to content

Corrige o uso de XMLWithPre.body_fragment_fingerprint e XMLWithPre.body_fingerprint - #1040

Closed
robertatakenaka wants to merge 3 commits into
scieloorg:mainfrom
robertatakenaka:fix_pid_provider_body_fragment_fingerprint
Closed

Corrige o uso de XMLWithPre.body_fragment_fingerprint e XMLWithPre.body_fingerprint#1040
robertatakenaka wants to merge 3 commits into
scieloorg:mainfrom
robertatakenaka:fix_pid_provider_body_fragment_fingerprint

Conversation

@robertatakenaka

Copy link
Copy Markdown
Member

O que esse PR faz?

Corrige o falso-positivo de match em QueryBuilderPidProviderXML.partial_body_query causado por um bug em XMLWithPre.body_fragment_fingerprint, que retornava o fingerprint do corpo INTEIRO do artigo em vez do fingerprint de um fragmento. Isso permitia colisão entre artigos diferentes que compartilham rótulos de seção genéricos no início do corpo (ex.: "ARTIGO DE REVISÃO"), já que o hash legado z_partial_body é calculado apenas a partir do primeiro parágrafo não vazio.

A correção foi feita em duas frentes:

  1. packtools (dependência externa, atualizada para 4.16.11): XMLWithPre passa a expor dois atributos distintos — body_fingerprint (corpo INTEIRO) e body_fragment_fingerprint (fragmento, agora corrigido).
  2. pid_provider/query_params.py: QueryBuilderPidProviderXML passa a ler ambos os atributos (self.z_body e self.z_body_fragment) e considerá-los como candidatos independentes em partial_body_query, junto com o hash legado z_partial_body, sem exigir migração/backfill dos registros já existentes.

Onde a revisão poderia começar?

pid_provider/query_params.py, método partial_body_query (e o construtor __init__ da classe QueryBuilderPidProviderXML, onde self.z_body e self.z_body_fragment são definidos).

Como este poderia ser testado manualmente?

  1. Atualizar a dependência packtools conforme requirements/base.txt (4.16.11).
  2. Rodar a suíte de testes: python manage.py test pid_provider.tests.test_query_params.
  3. Opcionalmente, simular em shell dois XMLs de artigos diferentes com o mesmo primeiro parágrafo genérico e corpos distintos, gerando via XMLWithPre os fingerprints, e verificar que QueryBuilderPidProviderXML(...).partial_body_query produz condições z_partial_body__in distintas para cada um (não deve haver match cruzado ao consultar PidProviderXML.objects.filter(...)).

Algum cenário de contexto que queira dar?

Esta correção resolve um incidente de produção em que artigos distintos, com seção inicial de rótulo genérico (comum em editoriais/artigos de revisão), estavam sendo indevidamente associados a um mesmo registro PidProviderXML durante o processo de re-ingestão/atualização de XML, devido à imprecisão do hash de corpo parcial. A solução mantém retrocompatibilidade: registros antigos que gravaram no campo z_partial_body tanto o formato legado quanto o formato (bugado) anterior de body_fragment_fingerprint continuam sendo encontrados, pois todos os hashes conhecidos entram como candidatos no IN.

Screenshots

Não aplicável (mudança de lógica de backend, sem interface gráfica).

Quais são os tickets relevantes?

Relacionado à issue de correção do falso-positivo de match em PidProviderXML (falso-positivo de QueryDocumentMultipleObjectsReturnedError).

Fixes #1039

Referências

  • packtools 4.16.11: https://github.com/scieloorg/packtools (correção de XMLWithPre.body_fragment_fingerprint)
  • Documentação interna sobre NULL = NULL ser UNKNOWN em SQL (motivação do fallback z_partial_body__isnull=True)

Segurança da informação (NSI.04)

Seção obrigatória. Marque as opções aplicáveis e justifique quando necessário. Referência: NSI.04 - Norma de Desenvolvimento Seguro.

Este PR manipula dados sensíveis ou pessoais (LGPD)?

  • Sim — descreva os controles de proteção aplicados (criptografia, mascaramento, anonimização, etc.):
  • Não

Este PR altera autenticação, autorização, controle de acesso ou gerenciamento de sessão?

  • Sim — descreva o que mudou e por quê:
  • Não

Este PR introduz, atualiza ou remove dependências de terceiros?

  • Sim — as novas dependências foram verificadas no SBOM/Trivy sem vulnerabilidades críticas/altas em aberto?
    • Verificado e aprovado
    • Pendente / vulnerabilidade aceita com justificativa: atualização de versão do packtools (4.16.84.16.11), dependência já utilizada no projeto; pendente validação formal via SBOM/Trivy no pipeline de CI.
  • Não

Este PR foi validado pelo pipeline de segurança (SonarQube / Trivy)?

  • Sim — link do job:
  • Não aplicável a este PR (justifique):

Este PR concatena, monta ou executa comandos SQL, HTML ou JavaScript a partir de entrada externa?

  • Sim — confirme que há sanitização/parametrização (prepared statements, escaping, etc.):
  • Não — as queries são construídas via Django ORM (Q objects), sem concatenação de strings SQL.

Este PR expõe novos endpoints, telas ou serviços?

  • Sim — HTTPS obrigatório está garantido e o acesso segue o princípio de menor privilégio?
  • Não

Algum segredo, senha, chave ou token está sendo adicionado ao código-fonte?

  • Não, nenhum segredo foi commitado
  • Sim (bloquear merge e corrigir antes de prosseguir)

Propósito: Atualizar a versão fixada do packtools no requirements/base.txt.

Solução técnica: Bump de packtools de 4.16.8 para 4.16.11 via egg
git+https://github.com/scieloorg/packtools.git@4.16.11#egg=packtools,
versão que corrige o bug de XMLWithPre.body_fragment_fingerprint
(que retornava incorretamente o fingerprint do corpo INTEIRO em vez
do fragmento), e cria XMLWithPre.body_fingerprint que retorna fingerprint do corpo INTEIRO, pré-requisito para a correção em query_params.py.
…l_body_query

Propósito: Corrigir falso-positivo de match em
QueryBuilderPidProviderXML.partial_body_query causado pelo bug do
XMLWithPre.body_fragment_fingerprint, que retornava o fingerprint do
corpo INTEIRO do artigo em vez do fragmento, permitindo colisão entre
artigos diferentes com rótulos de seção genéricos (ex.: 'ARTIGO DE
REVISÃO').

Solução técnica: Adiciona leitura de xml_with_pre.body_fingerprint
(novo atributo, fingerprint do corpo INTEIRO) em self.z_body, mantendo
self.z_body_fragment como fingerprint do FRAGMENTO (agora corrigido no
packtools 4.16.11). partial_body_query passa a compor candidates com
os três hashes disponíveis (z_partial_body legado, z_body_fragment,
z_body), preservando fallback para z_partial_body__isnull=True quando
nenhum estiver presente. Remove também variável morta other_pids em
identifier_queries.
…t em partial_body_query

Propósito: Validar a correção de partial_body_query após o fix do
bug em XMLWithPre.body_fragment_fingerprint, garantindo que o
fingerprint do corpo INTEIRO (body_fingerprint) e o do fragmento
(body_fragment_fingerprint) sejam tratados como candidatos distintos
e corretos, evitando regressão do falso-positivo original.

Solução técnica: Adiciona parâmetro body_fingerprint em
make_xml_adapter, setando explicitamente
adapter.xml_with_pre.body_fingerprint (default None) para evitar Mock
truthy espúrio nas asserções. Ajusta testes existentes para usar
'hash-fragmento-do-corpo' em vez de 'hash-corpo-inteiro' onde o valor
representa body_fragment_fingerprint, e para comparar
z_partial_body__in com set (não list), refletindo a implementação em
produção. Adiciona novos testes cobrindo os três hashes combinados
(test_combines_textual_fields_with_all_three_body_hashes) e a
regressão direta do incidente
(test_two_articles_with_same_legacy_hash_but_different_body_fingerprint_differ).
@robertatakenaka

Copy link
Copy Markdown
Member Author

este Pr não será necessário porque nenhuma release entrou em produção com o defeito que corrige

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.

Corrigir uso de XMLWithPre.body_fragment_fingerprint no pid provider

4 participants