Pieza 27 de 64
Otra épocaPieza nº 0027 de 64

La viñeta que vive en otro sitio

En el Boletín Oficial de la Provincia de Granada, un fichero de JavaScript guarda una función que, según el comentario que lleva encima, prepara el sumario del boletín para convertirlo en PDF. A cada anuncio le pone una viñeta, y la dirección de esa viñeta es la ruta de una carpeta del disco del servidor. En los tres sumarios en PDF que hemos abierto, el último del 25 de septiembre de 2026, no hay ninguna.

Dominio
bop.dipgra.es
Guardado
31 AGO 2026
Citas
5 en 1 fichero guardado
Lectura
unos 4 min
Captura de https://bop.dipgra.es/
foto 1La portada de bop.dipgra.es el 23 de septiembre de 2026: el Boletín Oficial de la Provincia de Granada, con el boletín del día.Captura del 23 de septiembre de 2026, 10:17 (hora peninsular)

El sumario ordena los anuncios por el organismo que los manda: la Diputación, cada ayuntamiento, otras entidades. El fichero tiene cinco funciones que hacen casi lo mismo: recorren los anuncios y los escriben uno detrás de otro, cada una en un formato. La primera escribe la lista de la web. Las otras cuatro llevan encima el mismo comentario con una palabra cambiada: «Este método es utilizado desde JAVA para generar» el HTML, el XML o el JSON del sumario, tres formas de escribir la misma lista para que la lea otro programa.

O sea que esas cuatro no las usa el navegador de quien entra en la web. Las llama el programa, escrito en Java, que corre en el servidor, el ordenador que entrega el boletín, para fabricar el sumario en otros formatos. La primera de las cuatro dice además para qué: el HTML «para el PDF del sumario del BOP». Es el sumario que la página del boletín ofrece para descargar, junto al rótulo Extracto, con un botón que dice PDF.

Captura de https://bop.dipgra.es/publica/consulta-de-bops/buscador/BOP-25-09-2026/
foto 2bop.dipgra.es el 26 de septiembre de 2026: la página del último boletín, el número 186. El recuadro es nuestro y señala el botón PDF que va junto a Extracto: el sumario en PDF, el que prepara la función de la viñeta según su comentario.Captura del 26 de septiembre de 2026, 15:39 (hora peninsular) · el recuadro es nuestro
2de 5bop.dipgra.es/export/system/modules/com.saga.inpro.theme.bop/resources/js/detalle_bop_html.jslínea 99 de 473
Copia
archivo
Guardado
31 ago 2026
Peso
17,9 kB
sha256
d36c297617ef…
96 * @param nivel
97 * @returns {string}
98 */
99function obtenerNivelListadoDetalleSumario(elemento, tieneHijos, nivel) {
100    var htmlResultante = '';
101    //console.log("Funcion obtenerNivelListadoDetalleSumario");
102    // Comrobamos que en elemento tenemos un JSON
2La función que, según su comentario, prepara el HTML del sumario para el PDF: es la única de las cinco que escribe la viñeta.
5de 5bop.dipgra.es/export/system/modules/com.saga.inpro.theme.bop/resources/js/detalle_bop_html.jslínea 93 de 473sigue en el mismo fichero · la línea de al lado
92/**
93 * Este método es utilizado desde JAVA para generar el HTML del sumario para el PDF del sumario del BOP
94 * @param elemento
95 * @param tieneHijos
96 * @param nivel
5El comentario que va encima de la función de la viñeta: la llama el programa del servidor, escrito en Java, para el PDF del sumario.

Esa función es la única de las cinco que pone una viñeta delante de cada anuncio: una imagen minúscula, de cinco píxeles por cinco, de esas que hacen que una lista parezca una lista. Lleva su ancho y su alto escritos a mano, y una dirección. Esa dirección empieza por una barra y sigue así: opt, tomcat, webapps, ROOT, WEB-INF y una carpeta más, con la imagen dentro; esa última parte la tapamos. Eso que parece una dirección de internet es un camino por dentro del disco del servidor.

1de 5bop.dipgra.es/export/system/modules/com.saga.inpro.theme.bop/resources/js/detalle_bop_html.jslínea 144 de 473
Copia
archivo
Guardado
31 ago 2026
Peso
17,9 kB
sha256
d36c297617ef…
Tapado
3 tramos ▒
141'<div class="elemento_listado">' +
142' <div class="etiqueta">' +
143' <div class="texto anuncio">' +
144' <span class="bullet"><img src="/opt/tomcat/webapps/ROOT/WEB-INF/▒▒▒▒▒▒/▒▒▒▒▒▒▒▒▒▒▒▒▒.▒▒▒" width="5" height="5"/></span> <a href="' + valor.link + '" title="' + scapaCaracteresEspecialesHtml(valor.titulo) + '">' +
145' ' + valor.titulo +
146' </a>' +
147' </div>' +
1La viñeta de cada anuncio, con una ruta del disco del servidor como dirección.
▒Los tramos ▒ de esta cita no están así en el fichero: los tapa el museo. Se sustituye cada letra y cada cifra por un bloque, sin cambiar la longitud, para no publicar un identificador de sesión ni una dirección de una red interna. Todo lo demás de la cita es literal.

Traducido: /opt es donde se instalan los programas en un servidor Linux; tomcat es el programa que sirve las aplicaciones Java; webapps es donde Tomcat guarda las que atiende; y ROOT es la que contesta cuando no se pide ninguna en concreto. Es el camino que habría que recorrer por dentro del disco de la máquina donde vive el boletín para llegar a ese fichero de imagen.

Justo antes de la carpeta de las imágenes aparece WEB-INF. En el mundo Java es la carpeta privada de una aplicación: la norma que define cómo funcionan estos servidores dice que su contenido no se entrega nunca a quien lo pida por la web. Ahí van la configuración, las librerías y las clases compiladas. Un programa que corre dentro del propio servidor sí puede leerla; lo prohibido es servirla hacia fuera.

Así que la ruta tiene sentido para un programa que lee del disco de la máquina, y ninguno para uno que pide las imágenes por la web, como un navegador. Nosotros la pedimos por la web el 15 de septiembre de 2026, con una sola petición de lectura, y el servidor contestó que no existe. Cómo busca las imágenes el programa que fabrica el PDF no lo sabemos: no está en nada que hayamos guardado.

El resultado sí se puede mirar. El 23 y el 26 de septiembre de 2026 descargamos los sumarios en PDF de los boletines del 23 y del 25, los que enlaza la página de cada uno. Su lista tiene la forma que escribe la función, con un guion delante de cada organismo y sus anuncios debajo. Pero no hay ninguna viñeta: esos PDF no llevan más imágenes que los fondos de sus páginas. En el sumario del 10 de julio de 2024, uno de los boletines que guardamos, tampoco.

Las otras cuatro funciones escriben la misma lista sin viñeta, cada una a su manera, con sus bucles idénticos y sus mismas comprobaciones repetidas una detrás de otra. Son cinco copias del mismo recorrido en un solo fichero, y la viñeta, con su ruta de disco, está solo en una: la del PDF. Cuando el mismo código vive cinco veces, lo que se escribe en una copia no llega a las demás.

3de 5bop.dipgra.es/export/system/modules/com.saga.inpro.theme.bop/resources/js/detalle_bop_html.jslínea 276 de 473
Copia
archivo
Guardado
31 ago 2026
Peso
17,9 kB
sha256
d36c297617ef…
273 * @param nivel
274 * @returns {string}
275 */
276function obtenerNivelListadoDetalleSumarioXml(elemento, tieneHijos, nivel) {
277    var xmlResultante = '';
278    //console.log("Funcion obtenerNivelListadoDetalleSumarioXml");
279    // Comrobamos que en elemento tenemos un JSON
3Unas ciento treinta líneas más abajo de la viñeta, la misma vuelta a la lista, entera otra vez, para XML.
4de 5bop.dipgra.es/export/system/modules/com.saga.inpro.theme.bop/resources/js/detalle_bop_html.jslínea 357 de 473sigue en el mismo fichero · 81 líneas más abajo
354 * @param nivel
355 * @returns {string}
356 */
357function obtenerNivelListadoDetalleSumarioJson(elemento, tieneHijos, nivel) {
358    var xmlResultante = '';
359    //console.log("Funcion obtenerNivelListadoDetalleSumarioJson");
360    // Comrobamos que en elemento tenemos un JSON
4Y la quinta copia, para JSON. Ninguna de estas dos lleva viñeta.

La viñeta tampoco lleva texto alternativo, la descripción que enseña el navegador cuando una imagen no carga y la que lee en voz alta un lector de pantalla. Aquí daría igual, porque es decorativa y no diría nada que no diga el título del anuncio que va al lado; es de los pocos sitios donde dejarlo vacío es lo correcto.

Y sigue igual. El fichero que pedimos el 15 de septiembre de 2026, y otra vez el 23 y el 26, tiene la misma huella que el que guardamos el 31 de agosto: los 17.888 bytes son idénticos, uno por uno. El servidor dice que lo escribió por última vez el 15 de septiembre, pero lo que escribió es lo mismo, con la viñeta y su ruta dentro.

La viñeta de cada anuncio tiene su dirección en el disco del servidor, en la carpeta que no se entrega a nadie. En los PDF que hemos abierto, ningún anuncio la lleva.

Lo que decimos
  • En el fichero detalle_bop_html.js de bop.dipgra.es, guardado el 31 de agosto de 2026, la función obtenerNivelListadoDetalleSumario, cuyo comentario dice «Este método es utilizado desde JAVA para generar el HTML del sumario para el PDF del sumario del BOP», escribe delante de cada anuncio una etiqueta de imagen cuya dirección es /opt/tomcat/webapps/ROOT/WEB-INF/▒ (lo que sigue lo tapamos), con ancho y alto de cinco píxeles y sin texto alternativo.
  • Es la única imagen que escribe ese fichero.
  • Otras tres funciones llevan el mismo comentario para el HTML, el XML y el JSON del sumario, sin viñeta; la quinta escribe la lista de la web, también sin ella.
  • El 15, el 23 y el 26 de septiembre de 2026 el mismo fichero se sirve con la misma huella sha256 y los mismos 17.888 bytes; el 15, una petición de lectura a esa ruta como dirección web contestó que no existe.
  • Los sumarios en PDF de los boletines del 23 y del 25 de septiembre de 2026, descargados el 23 y el 26 desde la página de cada boletín, que carga el fichero, no contienen más imágenes que los fondos de sus páginas; el del 10 de julio de 2024, tampoco.
  • El fichero lo cargan 41 páginas del boletín en nuestro archivo.
Lo que no decimos
  • No decimos que esa carpeta se pueda leer desde fuera: no existe como dirección web y no hemos intentado nada más que pedirla una vez.
  • No decimos que el sumario esté roto: se ve en la web, se descarga en PDF y sus anuncios están.
  • No decimos por qué no sale la viñeta en el PDF: no sabemos cómo busca las imágenes el programa del servidor, ni si ese PDF lo fabrica esta función u otra parecida; decimos lo que dice su comentario y lo que lleva el PDF.
  • Y no decimos desde cuándo está así ni si la viñeta llegó a verse alguna vez, porque no consta en nada que tengamos.
Procedencia

De dónde sale cada cita

Cada trozo de código de esta ficha está en un fichero guardado tal como lo entregó el servidor, con su huella (sha256) y su hora. Las citas entre «» se comprueban por programa contra ese fichero antes de publicar.

Desgobierno Digital · https://desgobiernodigital.com/piezas/granada-vineta-de-disco/ · copia impresa de la edición generada el 19 de octubre de 2026 · Un proyecto de BQuant · correcciones: @Gsnchez