-
Status do intake: implemented-pending-homologation
-
Data: 2026-08-28
-
Origem: relato de erro 404 ao carregar imagem no publisher-pages (
https://novo.[REDACTED].com/Ela-(1).webp), onde a imagem física existe em disco (contents/Ela (1).webpecontents/mini/Ela (1).webp), mas diverge entre hífen e espaço gerando 404 no controlador estático -
Classificação: bugfix, controlador estático (
arquivo-estatico.php), móduloadmin-arquivos, bibliotecaarquivo.php, resiliência de assets -
Batch candidato: BATCH-143
1. Contexto e Diagnóstico Técnico
Durante a criação e edição de páginas no módulo publisher-pages, foi constatado que imagens inseridas pelo usuário resultam em erro HTTP 404 - Arquivo não encontrado ao serem requisitadas no navegador pela URL entregue pelo gestor (exemplo real medido em produção: https://novo.[REDACTED].com/Ela-(1).webp).
Evidências Coletadas via HTTP
-
URL requisitada pelo frontend/página:
-
GET /Ela-(1).webp$\rightarrow$ HTTP 404 Not Found (emitido pelo controladorarquivo-estatico.phpviaarquivo_estatico_404());
-
-
URL com espaço (%20):
-
GET /Ela%20(1).webp$\rightarrow$ HTTP 200 OK (Content-Type: image/webp,Content-Length: 59252,Last-Modified: Fri, 28 Aug 2026 14:30:41 GMT);
-
-
Miniatura:
-
GET /mini/Ela%20(1).webp$\rightarrow$ HTTP 200 OK (Content-Type: image/webp,Content-Length: 15848).
-
Causa-Raiz 1: Inserção Indevida de Espaço na Resolução de Colisão do Upload
No arquivo gestor/modulos/admin-arquivos/admin-arquivos.php (linha 720), o loop de resolução de duplicidades no upload de arquivos utiliza:
$nomeFinal = $nomeBase . ' (' . $i . ')' . ($ext !== '' ? '.' . $ext : '');Esse trecho insere deliberadamente um caractere de espaço antes do parêntese (' (' . $i . ')'). Isso contraria a diretriz normativa do BATCH-100, que estabeleceu que nenhum arquivo salvo em disco deve conter espaços, já que espaços literais em URLs quebram atributos HTML e geram falhas de reescrita no Apache.
Causa-Raiz 2: Divergência por Sanitização Automática nos Consumidores
Quando o caminho 'Ela (1).webp' é consumido pelo interface.php, publisher-pages ou outros componentes do sistema, ele passa pela função canônica arquivo_caminho_relativo_seguro(), que invoca arquivo_nome_sanitizar(). Esta última substitui todos os espaços por hífens (preg_replace('/\s+/u', '-', $nome)), transformando o identificador em 'Ela-(1).webp'. Como resultado:
-
A URL montada na página pública passa a ser
https://novo.[REDACTED].com/Ela-(1).webp.
Causa-Raiz 3: Inflexibilidade no arquivo-estatico.php
No controlador gestor/controladores/arquivo-estatico/arquivo-estatico.php, a busca sob $_GESTOR['contents-path'] é estrita:
$file = $_GESTOR['contents-path'].$_GESTOR['caminho-total'];
$fileResolvido = arquivo_estatico_resolver_autorizado($file, $basesAutorizadas);Como o caminho recebido é Ela-(1).webp, e no disco o arquivo foi gravado como Ela (1).webp, realpath() falha e o controlador imediatamente aborta com HTTP 404, tornando o sistema incapaz de servir arquivos gravados com espaço quando referenciados por suas URLs normalizadas.
2. Escopo Técnico Requerido
Módulo 1: Fallback Inteligente no Controlador Estático (arquivo-estatico.php)
-
Localização:
gestor/controladores/arquivo-estatico/arquivo-estatico.php. -
Ações:
-
No tratamento de arquivos de usuários (
$_GESTOR['contents-path']):-
Caso o arquivo exato não seja encontrado via
realpath(): -
Tentativa 1 (Percent-Decode): Testar o caminho decodificado com
rawurldecode($_GESTOR['caminho-total']); -
Tentativa 2 (Compatibilidade Hífen $\leftrightarrow$ Espaço para Legados): Se o caminho contiver o padrão
-(\d+)(típico de colisões sanitizadas) ou hífens no nome base, verificar se existe o arquivo equivalente com espaço (ex:preg_replace('/-(?=\(\d+\))/', ' ', $caminhoTotal)ou substituição controlada de hífens por espaço) dentro da base autorizada.
-
-
Se a variante física correspondente existir sob a base autorizada, servi-la normalmente com
arquivo_estatico_enviar($fileResolvido, $ext), preservando cache e streaming HTTP Range. -
O mesmo fallback deve operar de forma idêntica para o caminho de miniaturas (ex:
/mini/Ela-(1).webp$\rightarrow$/mini/Ela (1).webp).
-
Módulo 2: Correção da Resolução de Colisão no admin-arquivos.php
-
Localização:
gestor/modulos/admin-arquivos/admin-arquivos.php(linha 720). -
Ações:
-
Alterar a montagem do nome de arquivo duplicado para utilizar hífen sem espaço:
$nomeFinal = $nomeBase . '-(' . $i . ')' . ($ext !== '' ? '.' . $ext : ''); -
Garantir que todos os arquivos futuros salvos em colisões já nasçam em perfeita conformidade com
arquivo_nome_sanitizar().
-
Módulo 3: Testes Automatizados Unitários
-
Localização:
tests/Unit/PHP/AdminArquivosSegurancaTest.phpe novo teste unitário ou casos emtests/Unit/PHP/ArquivoEstaticoRangeTest.php. -
Cobertura:
-
Teste unitário confirmando que resolução de colisão gera nomes com
-($i)e nunca com espaços; -
Teste da rotina de resolução estática demonstrando que requisições por URLs com hífen conseguem localizar e servir arquivos físicos que possuam espaço no nome (compatibilidade retroativa).
-
3. Critérios de Aceite e Validação
-
Acesso HTTP a Arquivos Legados: Uma requisição para
https://.../Ela-(1).webp(ou qualquer arquivo com espaço no disco requisitado com hífen) deve ser atendida com HTTP 200 OK e o tipo MIME correto, sem emitir 404; -
Miniaturas: A requisição de miniaturas no mesmo padrão (
/mini/Ela-(1).webp) também deve resolver a miniatura física existente (/mini/Ela (1).webp); -
Novos Uploads: Ao fazer upload de um arquivo com nome duplicado no
admin-arquivos, o novo arquivo gerado em disco deve seguir a convenção sem espaços (ex:foto-(1).jpg); -
Suíte Automatizada: Todos os testes PHPUnit e Vitest devem passar com 100% de sucesso sem regressões de segurança ou path traversal.