Archivos de prueba de casos límite: corruptos, truncados, vacíos y mal etiquetados
36 archivos · enlaces directos · sin anuncios · uso libre
El resto de esta biblioteca responde a "dame un PNG válido". Esta página responde a la pregunta difícil: ¿qué hace tu código con un archivo truncado, vacío, mal nombrado, que miente sobre su tipo o que trae datos que no debería? Esas son las subidas que llegan a producción, y construirlas a mano es tan tedioso que la mayoría de las suites de pruebas nunca las prueban.
Todos los archivos de aquí son seguros. No hay bombas zip, ni entradas con path traversal, ni ejecutables, ni cadenas de prueba de malware; el archivo comprimido más grande se descomprime en menos de un megabyte. Los fallos son reales, las cargas útiles no son peligrosas, y se publica el SHA-256 de cada archivo para que puedas fijarlo como fixture.
.jpg te dice si una subida de imagen puede convertirse en un cross-site scripting almacenado en tu dominio. El CSV con fórmulas te dice si tus exportaciones llegan a la hoja de cálculo de un compañero como fórmulas activas. Son los dos que más fallos reales encuentran.Archivos vacíos y casi vacíos
Una subida de cero bytes es lo que más a menudo se olvida. Los validadores que comprueban un tamaño máximo suelen olvidar el mínimo, y el código que lee el primer byte antes de comprobar la longitud falla aquí en lugar de devolver un error limpio.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
zero-byte.txt | Completamente vacío. Prueba la validación de tamaño mínimo, las divisiones por la longitud y el código que lee un primer byte sin comprobar antes que exista. | 0 B | Descargar |
one-byte.txt | Un solo carácter. Es demasiado pequeño para contener una cabecera válida de cualquier formato, así que la detección del tipo debe fallar de forma controlada. | 1 B | Descargar |
empty-archive.zip | Un ZIP estructuralmente válido sin ninguna entrada. La extracción debe completarse sin producir nada, no lanzar una excepción. | 22 B | Descargar |
Archivos truncados y dañados
Tienen una cabecera válida y datos incompletos o dañados, que es justo el aspecto de una subida interrumpida. El código que se fía de la cabecera y procesa el resto fallará aquí, y el punto donde falle te dirá si tu gestión de errores está donde crees.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
truncated.png | Firma PNG e IHDR válidas, cortado a mitad de los datos de imagen. Los decodificadores lanzan un error en lugar de devolver una imagen parcial. | 4 KB | Descargar |
corrupt-crc.png | Longitud completa y estructura correcta, pero se ha invertido un byte dentro de los datos de imagen y el CRC almacenado ya no coincide. Los decodificadores estrictos lo rechazan; los permisivos devuelven píxeles incorrectos. | 9 KB | Descargar |
truncated.jpg | Un JPEG cortado al 60 por ciento, sin marcador de fin de imagen. Muchos decodificadores devuelven una imagen decodificada en parte en lugar de fallar, y conviene saber qué hace el tuyo. | 603 B | Descargar |
truncated.zip | El directorio central está cortado, que es justo el aspecto de un archivo comprimido subido a medias. Es el ZIP dañado más habitual en la práctica. | 3 KB | Descargar |
malformed.json | Una coma final, una clave sin comillas y una llave sin cerrar. Comprueba que tu analizador indica una posición útil en lugar de un error genérico. | 136 B | Descargar |
Archivos que mienten sobre su tipo
La extensión dice una cosa y los bytes, otra. Si tu gestor de subidas se fía de la extensión o del Content-Type que envía el navegador, estos archivos pasan. El que importa es el archivo HTML con nombre .jpg: si se sirve con un tipo de contenido de imagen es inofensivo, pero si se sirve como HTML desde tu dominio es un cross-site scripting almacenado.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
actually-a-png.jpg | Un PNG auténtico con extensión .jpg. Todo lo que decida según la extensión se lo pasará al decodificador equivocado. | 9 KB | Descargar |
actually-html.jpg | Un documento HTML con extensión .jpg. Si tu aplicación lo guarda y lo vuelve a servir con un tipo de contenido adivinado, tienes un cross-site scripting almacenado. | 335 B | Descargar |
Metadatos y privacidad
Una foto recién sacada del móvil indica dónde se tomó y cuál es su orientación. Si no eliminas lo primero, filtras la ubicación de tus usuarios; si ignoras lo segundo, todos los retratos aparecen de lado. Este archivo incluye ambas cosas, para que puedas verificar que tu flujo de trabajo gestiona cada una.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
exif-gps-orientation.jpg | Contiene coordenadas GPS (la CN Tower de Toronto) y Orientation 6, que indica girar 90 grados en sentido horario para mostrarla derecha. Úsalo para comprobar tanto que eliminas los datos de ubicación como que respetas la rotación. | 1 KB | Descargar |
Texto, codificación y finales de línea
Una marca de orden de bytes (BOM) que se convierte en un carácter visible en la primera columna, campos entrecomillados que contienen comas y saltos de línea literales, tres terminadores de línea distintos en un mismo archivo y ningún terminador al final. Todo esto es normal en los archivos que te envían los usuarios reales.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
bom-crlf-quoted.csv | Una marca de orden de bytes (BOM) UTF-8, finales de línea CRLF, campos entre comillas que contienen comas, comillas dobles escapadas, un salto de línea literal dentro de un campo y nombres no ASCII. Si el BOM aparece en la cabecera de tu primera columna, ahí está el fallo. | 180 B | Descargar |
unicode-torture.txt | Marcas combinantes, un espacio de ancho cero, un carácter de anulación de derecha a izquierda, caracteres de los planos suplementarios y un emoji de bandera de seis puntos de código. Prueba el recuento de longitud, el truncado y la normalización. | 565 B | Descargar |
mixed-line-endings.txt | LF, CRLF y un CR suelto en el mismo archivo, sin terminador en la última línea. Aquí el código que cuenta líneas suele contradecirse a sí mismo. | 107 B | Descargar |
no-trailing-newline.txt | Termina sin salto de línea. Si añades contenido a este archivo sin comprobarlo, dos registros acaban unidos en uno. | 48 B | Descargar |
Nombres de archivo complicados
La prueba está en el nombre, no en el contenido. Los nombres largos desbordan las columnas de la base de datos y los límites del sistema de archivos; los nombres que no son ASCII rompen las cabeceras Content-Disposition, el escapado de URL y la diferencia entre Unicode compuesto y descompuesto en macOS.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
文件名-with spaces-🌲.txt | Caracteres chinos, espacios y un emoji en el nombre de archivo. Prueba la codificación de Content-Disposition, el escapado de URL y la normalización Unicode descompuesta de macOS. | 194 B | Descargar |
Límites estructurales y de recursos
Archivos válidos que son incómodos más que defectuosos: un archivo comprimido con diez mil entradas, JSON anidado a más profundidad de la que admiten por defecto la mayoría de los analizadores y un archivo comprimido cifrado. Ninguno es un ataque: son las formas que hacen que una implementación ingenua se quede sin algún recurso.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
many-entries-10000.zip | Diez mil entradas pequeñas que en total ocupan menos de 1 MB sin comprimir. Prueba el análisis del directorio central y el coste por entrada. A propósito, no es una bomba ZIP. | 1.6 MB | Descargar |
deeply-nested.json | 512 niveles de anidamiento. Es JSON válido, pero más profundo de lo que muchos analizadores permiten por defecto, y lo bastante como para agotar la pila de un analizador recursivo. | 3 KB | Descargar |
encrypted-password-test.zip | Cifrado con ZipCrypto; la contraseña es test. La extracción sin contraseña debe fallar limpiamente en lugar de producir basura. | 292 B | Descargar |
Inyección de fórmulas en hojas de cálculo
Una celda CSV que empieza por =, +, - o @ se interpreta como fórmula al abrir el archivo en Excel, Google Sheets o LibreOffice. Si tu aplicación exporta a CSV texto introducido por los usuarios sin escapar esos prefijos, estás distribuyendo su entrada como fórmulas ejecutables. Las cargas de estos archivos solo calculan operaciones aritméticas inofensivas.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
formula-injection.csv | Celdas que empiezan por =, +, - y @, que las hojas de cálculo tratan como fórmulas. Las cargas calculan operaciones aritméticas inofensivas y una crea un enlace a este sitio. Ninguna ejecuta un comando. | 189 B | Descargar |
Modelos 3D: mallas vacías, defectuosas y engañosas
El código que trabaja con mallas suele dar por hecho un modelo cerrado, de tamaño razonable, con la orientación de caras correcta y al menos un triángulo. Los usuarios suben todo lo demás. Aquí tienes la malla vacía, triángulos de área cero y con las caras invertidas, una malla no manifold, coordenadas demasiado grandes o demasiado pequeñas para que float32 las gestione bien, un GLB cortado a mitad de la subida, un STL cuya cabecera miente, un GLB que se hace pasar por STL y el STL binario que engaña a la clásica comprobación de “si empieza por solid, es ASCII”. Están en la carpeta 3D; los ejemplos 3D válidos están en la categoría de modelos 3D.
| Archivo | Qué prueba | Tamaño | Descargar |
|---|---|---|---|
empty-mesh-zero-triangles.stl | Un STL binario estructuralmente válido: la cabecera de 80 bytes y un recuento de triángulos de 0, nada más (84 bytes). El código de caja delimitadora, centrado y miniaturas a menudo divide por cero o accede a un array vacío en este caso. | 84 B | Descargar |
empty-scene-no-meshes.glb | Un binario glTF 2.0 válido con una escena y un nodo vacío, pero sin mallas, buffers ni materiales. Pasa el validador de Khronos. Los visores deben mostrar una escena vacía, no lanzar una excepción. | 276 B | Descargar |
degenerate-triangles.stl | Un cubo de 10 mm más seis triángulos de área cero: vértices repetidos, puntos colineales y una astilla por debajo del épsilon. El cálculo de normales divide aquí por una longitud cero, y de ahí salen las normales NaN. | 984 B | Descargar |
flipped-normals-inside-out.stl | Un cubo de 10 mm con todos los triángulos en sentido horario y las normales almacenadas apuntando hacia dentro. Se ve negro o invisible con la eliminación de caras traseras (back-face culling), y su volumen con signo es negativo. | 684 B | Descargar |
non-manifold-open-box-and-fins.stl | Una caja sin tapa (un borde abierto) más dos aletas que comparten cada una una arista con otras dos caras. No se puede imprimir tal cual; los slicers y las herramientas de reparación deben señalar ambos problemas. | 684 B | Descargar |
huge-coordinates-1e7.stl | Un cubo de 100 unidades centrado a diez millones de unidades del origen. A esa magnitud, float32 solo puede representar números enteros, así que aparecen problemas de precisión, del plano lejano de la cámara y del encuadre automático. | 684 B | Descargar |
tiny-scale-1e-6.stl | Un cubo de una millonésima de unidad de lado. Leído en milímetros mide un micrómetro: prueba las comprobaciones de tamaño mínimo, la deducción de unidades y cualquier épsilon usado para fusionar vértices. | 684 B | Descargar |
extreme-float-values.stl | Coordenadas de vértices de ±3.0e38, cerca del máximo de float32, y un triángulo formado por valores subnormales de 1e-40. El archivo no contiene NaN ni Infinity, pero calcular el tamaño de la caja delimitadora en float32 desborda a Infinity. | 234 B | Descargar |
truncated.glb | El primer 60 por ciento de un GLB con texturas válido. La cabecera sigue indicando la longitud completa y el bloque BIN termina antes de tiempo, que es justo el aspecto de una subida interrumpida de un GLB. | 80 KB | Descargar |
wrong-triangle-count-header.stl | Un STL binario cuyo recuento uint32 indica 1000 triángulos cuando el archivo contiene 12. Un lector que se fía del recuento lee más allá del final; uno estricto rechaza el archivo porque 84 + 50 × 1000 no coincide con su tamaño. | 684 B | Descargar |
actually-a-glb.stl | Un GLB auténtico y válido (empieza con los bytes glTF) guardado con extensión .stl. Todo lo que decida según la extensión se lo pasará al analizador de STL. | 21 KB | Descargar |
binary-stl-header-starts-with-solid.stl | Un STL binario válido cuya cabecera de texto libre empieza por la palabra solid, como hacen varios exportadores reales. Detectar el STL ASCII por ese prefijo envía este archivo al analizador equivocado; compara mejor el tamaño con el recuento de triángulos. | 684 B | Descargar |
obj-missing-mtl.obj | Un OBJ por lo demás válido cuya línea mtllib apunta a un archivo de materiales que no existe. La geometría debe cargarse igualmente con un material por defecto y un aviso, no fallar. | 914 B | Descargar |
obj-negative-indices.obj | Un OBJ válido cuyas caras usan índices negativos relativos (f -3 -2 -1), algo que el formato permite. Muchos analizadores escritos a mano solo admiten índices positivos. | 675 B | Descargar |
立方体 cube-modèle-🧊.stl | Un cubo válido de 10 mm cuyo nombre de archivo mezcla caracteres chinos, una letra acentuada, un espacio y un emoji. Prueba Content-Disposition, la codificación de URL y las claves de almacenamiento en las subidas de modelos. | 684 B | Descargar |
Una lista breve para gestionar subidas
- Comprueba un tamaño mínimo además del máximo. Las subidas de cero bytes son el caso que más se pasa por alto.
- Determina el tipo a partir de los bytes, nunca de la extensión ni del tipo de contenido que envía el navegador. Ambos los controla el atacante.
- Sirve las subidas de los usuarios desde un dominio aparte, o con
Content-Disposition: attachmentyX-Content-Type-Options: nosniff, para que un archivo que resulte ser HTML no pueda ejecutarse en tu origen. - Elimina los datos EXIF antes de publicar una imagen, y aplica la etiqueta de orientación antes de eliminarlos.
- Escapa los
=,+,-y@iniciales al escribir texto de usuarios en un CSV. - Fija límites explícitos al número de entradas de un archivo comprimido, al tamaño total descomprimido y a la profundidad de recursión del analizador, y devuelve un error claro cuando se alcance alguno.
- Decide qué debe pasar con un archivo subido a medias y pruébalo con los archivos truncados de aquí en lugar de darlo por supuesto.
Preguntas frecuentes
¿Son peligrosos estos archivos?
No. No hay bombas zip, ni entradas con path traversal, ni ejecutables, ni macros, ni cadenas de prueba de malware. El archivo más grande se descomprime en menos de un megabyte. Los fallos son reales (una imagen truncada está realmente truncada), pero nada de aquí ataca al equipo que lo abre. Las fórmulas de la hoja de cálculo calculan operaciones aritméticas inofensivas en lugar de ejecutar un comando.
¿Para qué sirve el archivo HTML con extensión .jpg?
Es el archivo más valioso del paquete. Si tu aplicación lo acepta como imagen, lo almacena y más tarde lo vuelve a servir con un tipo de contenido deducido de su contenido, el navegador lo renderiza como una página de tu dominio. Eso es un cross-site scripting almacenado a través de una subida de imagen. Aceptar el archivo no es un problema; servirlo de vuelta como HTML, sí.
¿Por qué el CSV tiene celdas que empiezan por un signo igual?
Porque Excel, Google Sheets y LibreOffice interpretan una celda que empieza por =, +, - o @ como una fórmula. Si tu aplicación exporta a CSV texto introducido por usuarios sin escapar esos prefijos, lo que alguien escribió en un formulario llega a la hoja de cálculo de un compañero como una fórmula activa. La solución es anteponer un apóstrofo a esas celdas o entrecomillarlas al exportar.
¿De verdad la foto contiene coordenadas GPS?
Sí: la CN Tower de Toronto, a 43,6426 norte y 79,3871 oeste, más una altitud. También lleva la orientación 6, que indica que el visor debe girarla 90 grados en el sentido de las agujas del reloj para mostrarla derecha. Entre las dos cubren lo que cualquier flujo de imágenes debe hacer bien: eliminar los datos de ubicación antes de publicar y respetar la rotación para que los retratos no salgan de lado.
¿Puedo usarlos en una suite de pruebas automatizadas?
Sí, para eso están. Cada archivo es determinista, su SHA-256 se publica aquí y los enlaces directos tienen cachés de larga duración y cabeceras CORS abiertas. Fija el hash en tu prueba y sabrás al instante si un fixture cambia alguna vez.
¿Encontraste un problema o algo que podría mejorar? Leemos todos los mensajes y lo arreglamos rápido.
¿Necesitas archivos válidos?
La mayoría de las pruebas necesitan un archivo que funcione. También los publicamos: imágenes, vídeo, audio, documentos, archivos comprimidos, datos, fuentes y modelos 3D reales, en tamaños exactos y con hashes publicados.