Llevamos justo un mes de freeze de Debian "Jessie" y la cosa va tomando forma. No es que todavía no queden muchos bugs RC (ahora mismo 243 según el BTS y 227 según UDD), pero al menos la cuenta va hacia abajo, no como hace 15 días que crecía.
De momento la previsión de Lucas Nussbaum de 12 semanas, cuando ya han transcurrido 4, entra dentro de lo posible, máxime teniendo en cuenta que algunos de esos bugs no habría que incluirlos en la cuenta. Por ejemplo, los bugs de seguridad son corregidos incluso después de ser lanzada la estable, así que realmente no son bloqueantes para el lanzamiento (aunque obviamente no creo que nadie pensara en lanzar la versión estable con bugs de seguridad flagrantes conocidos). Para otros bugs ya existe la corrección pertinente, incluso ya está subida a unstable, pero ésta no ha pasado todavía a testing.
Por eso las estadísticas que realiza semanalmente Richard
Hartmann desglosan los bugs en varias categorías,
tratando de captar el número real de bugs que quedan por solucionar
(distinto del número de bugs que están en fase de figurar como
solucionados). Estas cifras son más pequeñas (en algún caso mucho más
pequeñas), aunque no hay que lanzar las campanas al vuelo porque se
siguen encontrándo bugs constantemente. Lo importante es la tendencia:
que el número de bugs encontrados sea paulatinamente menor hasta que
éstos converjan a cero. A ser posible en un número no infinito de
incrementos... :-)
Teniendo más de 30.000 paquetes, es evidente que la mayoría de los bugs (por simple cuestión de números) no están dentro del subconjunto de paquetes que tenemos instalado. Así que la capacidad de contribuir a verificar o solucionar bugs está limitada a unos pocos de toda la lista. Así que captó mi atención el ver un bug en un programa que uso diariamente: mutt. El bug en cuestión era el #771125. Lo abro y en el segundo mensaje me encuentro esto:
char *mutt_substrdup (const char *begin, const char *end)
{
size_t len;
char *p;
if (end)
len = end - begin;
else
len = strlen (begin);
p = safe_malloc (len + 1);
memcpy (p, begin, len);
p[len] = 0;
return p;
}
Si conocéis C, ahora mismo os estaréis echando las manos a la cabeza como yo me las eché al ver eso. No hace falta ni seguir leyendo el resto de intercambios del bug para saber dónde está el potencial problema. ¿Lo habéis visto? Sí, seguro que sí.
Es de suponer por el nombre y el cuerpo que esta función realiza una
copia (supuestamente segura) de una cadena de texto. Dicha cadena de
texto, seguramente para evitarse problemas con caracteres \0
,
acepta un puntero al fin de la cadena a copiar aparte de un puntero al
inicio, ¡pero en ningún momento se comprueba que el puntero apuntando al
final es posterior al que apunta al inicio!
Dicho sea de paso, tampoco se comprueba que el puntero begin
no sea
nulo, lo que en mi opinión es un segundo bug esperando al acecho una
oportunidad de liarla parda.
El bug no está únicamente en la función, está también en el código que la invoca. Pero es una ley de la programación defensiva que cada función se proteja de usos indebidos, de forma que si hay un bug en el codigo que la llama éste no se propague más allá.
Por ejemplo, en este caso, hay un invariante que se debe cumplir
siempre: begin != NULL
. Y hay un invariante que debe cumplirse siempre
que se suministra el puntero end
: begin <= end
. Y fijáos que he
puesto "menor o igual" y no "menor" para que se trate también el caso de
copiar la cadena vacía, que puede tener sentido si se quiere reducir el
número de casos especiales a tratar en los algoritmos que llamen a esta
función.
De hecho, el caso en el que no se suministra el puntero end
y se
se emplea strlen()
para calcular el tamaño de la cadena a duplicar no
maneja correctamente cadenas con carácteres \0
, lo cual puede ser un
problema dependiendo de las asunciones que haga el código llamante.
Yo desde luego dormiría más tranquilo con una función con una aserción:
assert( begin != NULL && end != NULL && begin <= end );
len = end - begin;
que la protegiera de todo mal1.
Si esto está así, sinceramente no quiero ni pensar cómo está el resto del código de mutt.
:wq
-
O de casi todo mal, ya que si
end - begin
es mayor que el máximo almacenable en un size_t podríamos tener problemas. ↩