Resumen

  • El test añadido el 11 de septiembre fuerza el almacenamiento en disco con un umbral de un byte y verifica que FileUpload.getBytes() conserva exactamente el contenido.
  • Los nombres organizations.xlsx y carta-ce.pdf describen la intención de uso, pero sus datos son texto sintético; el método no abre OOXML ni analiza un PDF completo.
  • La cobertura más creíble consiste en conservar esa prueba de transporte y enlazarla con recibos distintos de formato, reglas electorales, autorización y consumo de recursos.

El experimento exacto

El método se llama wicketFileUploadGetBytesWorksForDiskBackedExcelAndPdf. Su nombre parece reunir toda la ruta de dos tipos de documento. El cuerpo del test cuenta una historia más precisa. Construye una DiskFileItemFactory, utiliza el directorio temporal de JUnit y fija el tamaño del búfer en 1. Después crea un elemento multipart, escribe un arreglo de bytes, lo envuelve con FileUpload de Wicket, llama a getBytes() y exige igualdad exacta. El elemento temporal se borra en un bloque finally.

Commons FileUpload explica por qué ese detalle importa. Por debajo de un umbral, un DiskFileItem puede conservar el contenido en memoria; al alcanzar o superar el umbral, lo escribe en un archivo temporal. Con un valor de uno, los dos ejemplos no pueden quedarse en la ruta cómoda de memoria. El test protege el caso en el que el marco web recupera un contenido que ya vive en disco. Para una actualización de dependencias, esa es una señal diagnóstica limpia.

Pero los datos no son los documentos anunciados por las extensiones. El arreglo llamado spreadsheet contiene ORGID, un salto de línea y ALFA-001. No contiene las partes ZIP, relaciones, tipos de contenido y XML de un libro .xlsx. El arreglo llamado pdf contiene %PDF-1.1, un salto, %carta y otro salto. Tiene la firma inicial, pero no la estructura completa de un PDF. Asignar esos bytes a los nombres organizations.xlsx y carta-ce.pdf no cambia su naturaleza.

La afirmación correcta, por tanto, es robusta y acotada: los bytes escritos en un elemento multipart almacenado en disco son los mismos que entrega Wicket. No demuestra que un analizador acepte el formato, que las columnas satisfagan una elección, que un usuario tenga permiso o que una operación produzca el cambio esperado. Esta separación no reduce el valor del test. Impide que una evidencia buena sea utilizada para responder una pregunta distinta.

Tres rutas reales, tres conjuntos de controles

El propio repositorio evita una lectura simplista. En la misma clase, otra prueba pasa texto con el nombre photo.jpg por el validador de imágenes y espera un rechazo por formato. Un caso adicional fabrica un PNG real de 800 por 600 píxeles, lo procesa, confirma que la salida es JPEG y vuelve a decodificarla para comprobar un máximo de 400 por 400. Allí la prueba sí entra en la semántica del contenido: la imagen debe decodificarse y transformarse.

La gestión de organizaciones también continúa mucho más allá del nombre. El primer validador considera candidato a un archivo si su nombre termina en .xlsx o si el tipo MIME declarado es el de una hoja OOXML. Ese filtro admite una declaración del cliente, pero después las rutas de deudores y bajas invocan validación remota, mientras que las altas y actualizaciones ejecutan validación detallada al enviar el formulario.

En ExcelUtils, los bytes se escriben a un archivo temporal. El código exige el MIME OOXML, abre el contenido con XSSFWorkbook de Apache POI, toma la primera hoja, encuentra encabezados y recorre filas. Para listas de organizaciones requiere ORGID; para actualizaciones exige un conjunto mayor de columnas y valida valores, duplicados y campos obligatorios. Antes de poner una modificación en cola, el panel aplica verificaciones relacionadas con la elección y con la operación. Si ya existe un procesamiento activo, no inicia otro.

Esto explica una aparente paradoja. El texto ORGID\nALFA-001 supera la prueba nueva porque el objetivo es recuperar los mismos bytes. El flujo real de Excel lo rechazará al intentar construir un XSSFWorkbook. Ambos resultados pueden ser correctos al mismo tiempo porque protegen fronteras diferentes.

El padrón electoral mantiene esa distinción. Su panel obtiene el objeto de carga, valida si la actualización se puede aplicar a la elección y solo entonces solicita ponerla en cola. El test nuevo refleja la llamada a getBytes(), no las columnas del padrón, las condiciones de la elección ni el efecto final.

Las cartas de resultados tienen otro diseño. El formulario multipart impone un máximo de 10 MB. Al guardar, la página vuelve a cargar la elección, comprueba el acceso y se detiene si está cerrada. Evalúa por separado las cargas opcionales en español, inglés y portugués; si las tres decisiones son válidas, guarda los bytes junto con el administrador y la dirección del cliente.

La función isPdf, sin embargo, solo compara los primeros cuatro bytes con %PDF. Por eso el ejemplo corto del test satisface la condición. Esta regla puede funcionar como reconocimiento inicial, pero no prueba que el archivo sea renderizable ni que contenga una estructura PDF coherente. El límite de tamaño y el control electoral son garantías reales, aunque independientes de la validez estructural del documento.

Una matriz de aceptación legible

La organización más útil no es un único test end-to-end que falle sin explicar dónde. Es una matriz de recibos pequeños conectados entre sí.

El recibo de transporte debería probar explícitamente tanto memoria como disco, afirmar que la variante en disco de verdad no está en memoria, comparar bytes, cerrar flujos y verificar la limpieza. La prueba nueva ya cubre la parte principal. Un nombre centrado en “preservación de bytes almacenados en disco” evitaría que las extensiones parezcan resultados de análisis.

El recibo de formato requiere muestras auténticas. Para OOXML, un libro mínimo generado por POI o una herramienta equivalente, con la hoja y los encabezados pedidos; junto a él, un ZIP que no sea OOXML, un archivo truncado y los casos cifrados que defina la política. Para PDF, un documento mínimo completo aceptado por el analizador elegido, un simple encabezado, un archivo cortado y muestras engañosas relevantes. La firma y el MIME pueden aportar señales, pero no sustituyen la estructura.

El recibo del dominio debe atravesar las reglas de organizaciones y padrón. Tiene que distinguir un error de lectura de una columna ausente, una fila vacía, un ORGID duplicado o una referencia no aplicable a la elección. También debería confirmar el contenido del informe de errores y que un rechazo no deje trabajo pendiente.

El recibo de autorización y efecto utiliza una elección abierta y una cerrada, un administrador con permiso y una sesión sin él. Comprueba que solo el caso válido crea una operación, que el contexto de auditoría queda asociado, que dos solicitudes concurrentes no producen dos trabajos y que el resultado durable coincide con las filas aceptadas. Para las cartas, una carga inválida en un idioma debe impedir que se apliquen parcialmente los otros cambios.

El recibo de recursos aborda tamaño, memoria, archivos temporales, tiempo y expansión comprimida. Commons FileUpload ofrece umbrales y límites de solicitud. La guía de Apache POI advierte que analizar documentos no confiables exige defensas adicionales y que la biblioteca no puede eliminar todos los efectos adversos. ZipSecureFile incorpora límites de razón de compresión y tamaño de entrada descomprimida. OWASP recomienda combinar extensión, MIME, firma, autorización y tamaño, incluida la expansión después de descomprimir.

Nada de esto permite afirmar que LACNIC sufra una vulnerabilidad. La fotografía disponible es un commit público, no una inspección del despliegue. El módulo administrativo del árbol fijado declara Wicket 10.9.0 y su configuración de WildFly apunta a POI OOXML 5.0.0. Esas versiones describen el código revisado. Tampoco se puede deducir, por la cercanía entre una actualización y la prueba, que la primera haya causado un fallo.

El valor de decir menos y probarlo mejor

Una afirmación estrecha resiste mejor el paso del tiempo. Si cambia Commons FileUpload y la variante en disco falla, el test apunta directamente a la integración. Si el test sigue verde, nadie debería tener que inferir que las reglas de un libro Excel o de una carta PDF también se ejecutaron. Cada equipo puede acudir al recibo correspondiente.

En sistemas de gobernanza, los nombres circulan fuera del código. Aparecen en revisiones, actas técnicas y explicaciones a responsables que no abren el método. “Excel y PDF pasan” es una frase fácil de recordar, pero más amplia que el experimento. “Los bytes sobreviven al almacenamiento temporal y a Wicket” parece modesta; en realidad es una garantía más útil porque señala exactamente qué cambiaría un resultado rojo.

Fuentes