Les bonnes pratiques du CERT disent qu'il faut quand même d'abord vérifier que la fonction renvoie un résultat pouvant indiquer une erreur, avant de checker l'erreur en question. En plus de setter errno à 0 avant.
D'ailleurs ULONG_MAX n'est pas le seul résultat possible en cas d'erreur, il y a 0 qui est aussi possible. Donc pour vraiment bien faire ce serait:
Code:
errno = 0;
unsigned long int result = strtoul(string, NULL, 10);
if ((result == ULONG_MAX || result == 0) && (errno != 0))
return false;
Ou même mieux, puisque seules certaines valeurs de errno sont normalement possibles:
Code:
errno = 0;
unsigned long int result = strtoul(string, NULL, 10);
if ((result == ULONG_MAX || result == 0) && (errno == EINVAL || errno == ERANGE))
return false;
assert(errno == 0);
Le monde magique de la gestion d'erreur dans un environnement critique.
Bien entendu les outils de code review permettent tout de suite de détecter ce genre de failles, et les développeurs sont bien entendu tous prêts à supporter cette rigueur et ajoutent avec enthousiasme toutes ces vérifications supplémentaires.