Para empezar, permítanme decir que entiendo cómo y por qué puede suceder el problema que estoy describiendo. Estudié Ciencias de la Computación, y entiendo desbordamiento/subdesbordamiento y aritmética con o sin firma. (Para quienes no estén familiarizados con el tema, la Guía de codificación segura de Apple discusses integer overflow brevemente)¿La mejor manera de manejar e informar errores de asignación de memoria debido al desbordamiento de enteros en Objective-C?
Mi pregunta es acerca de informar y recuperarse de dicho error una vez que se ha detectado, y más específicamente en el caso de un marco Objective-C. (Escribo y mantengo CHDataStructures). Tengo unas pocas clases de colecciones que asignan memoria para almacenar objetos y expandirla dinámicamente según sea necesario. Todavía no he visto ningún bloqueo relacionado con el desbordamiento, probablemente porque mis casos de prueba utilizan en su mayoría datos sanos. Sin embargo, dados valores no validados, las cosas podrían explotar bastante rápido, y quiero evitar eso.
he identificado al menos dos casos comunes donde esto puede ocurrir:
- La persona que llama pasa un muy gran valor sin signo (o valor con signo negativo) a
-initWithCapacity:
. - Se han agregado suficientes objetos para causar la capacidad de expandirse dinámicamente, y la capacidad ha crecido lo suficiente como para causar un desbordamiento.
La parte fácil es detectar si se producirá un desbordamiento. (Por ejemplo, antes de intentar asignar length * sizeof(void*)
bytes, puedo verificar si length <= UINT_MAX/sizeof(void*)
, ya que si falla esta prueba significará que el producto se desbordará y potencialmente asignará una región de memoria mucho más pequeña que la deseada. En las plataformas que la admiten, la checkint.h API es otra alternativa.) La parte más difícil es determinar cómo tratar con gracia. En el primer escenario, la persona que llama está quizás mejor equipada (o al menos en la mentalidad) para lidiar con una falla. El segundo escenario puede ocurrir en cualquier parte del código que un objeto se agrega a la colección, que puede ser bastante no determinista.
Mi pregunta, entonces, es esta: ¿Cómo se espera que el "buen ciudadano" código Objective-C actúe cuando se produce un desbordamiento de entero en este tipo de situación? (Idealmente, dado que mi proyecto es un framework con el mismo espíritu que Foundation in Cocoa, me gustaría modelarlo de la manera en que se comporta para una "coincidencia de impedancias" máxima. La documentación de Apple que he encontrado no menciona mucho sobre esto.) Me imagino que, en cualquier caso, informar el error es un hecho. Dado que las API para agregar un objeto (que podría causar el escenario 2) no aceptan un parámetro de error, ¿qué puedo hacer realmente para ayudar a resolver el problema, en todo caso? ¿Qué se considera realmente correcto en tales situaciones? Soy reacio a escribir a sabiendas el código propenso a bloqueos si puedo hacerlo mejor ...
Afortunadamente, dado que el código en cuestión es un marco de colecciones de bajo nivel, realmente no puedo preocuparme específicamente por ningún dato de usuario, ya que no tengo idea de cómo persistirlo o verificar si hay corrupción. En los pocos lugares donde (2) podría ocurrir, planeo hacer algo inteligente, como intentar una asignación más pequeña (si es una colección en crecimiento) o devolver nada. En cualquier caso, ciertamente registraré evidencia para ayudar a rastrear el problema. Gracias por el útil contexto para hacerlo. –