Pregunta Puede argc overflow?


Estaba vagando en SO y vi esta pregunta. Entonces comencé a preguntarme si podría desbordar Argc.

Standard dice que argv[argc] debe ser un puntero nulo, pero esto será falso si se produce un desbordamiento de argc.

(YO escribió un pequeño programa de C y un script de Python para probarlo, pero obtuvo un MemoryError.)

¡Gracias!


Justificación del estándar internacional - Lenguajes de programación - C §5.1.2.2.1 Inicio del programa

La especificación de argc y argv como argumentos para main reconoce una extensa práctica previa. argv[argc] se requiere que sea un puntero nulo para proporcionar una verificación redundante para el final de la lista, también sobre la base de la práctica común.


75
2018-01-21 19:32


origen


Respuestas:


De acuerdo con el estándar

Entonces, de tu cita:

argv[argc] se requiere que sea un puntero nulo

Por lo tanto, argc no puede desbordarse, porque entonces la declaración anterior no sería verdadera.

En la práctica

En la práctica, el tamaño total de los argumentos pasados ​​a un programa es limitado.

En mi sistema Linux / x64:

$ getconf ARG_MAX
2097152

Por lo tanto, el tamaño del argumento total es de aproximadamente 2 megabytes, y argc no puede desbordar Creo que este límite mide una combinación del total de datos en argv y el medio ambiente Si supera este límite cuando intenta ejecutar un comando, exec() fallará con E2BIG. De man 2 execve:

E2BIG El número total de bytes en el entorno (envp) y argumento
       lista (argv) es demasiado grande.

Creo que el límite de ~ 2 megabytes en mi sistema es relativamente generoso en comparación con otros sistemas. Mi sistema OS X informa un límite de ~ 260 KB.

Pero que si ARG_MAX eran realmente grandes?

Bien, supongamos que estás en un sistema viejo / raro, entonces int es de 16 bits, y ARG_MAX es más de 215, que de otra manera es bastante razonable. Ahora, supongamos que invocas execve() con más de 215 argumentos. La implementación tiene dos opciones.

  1. Puede permitir argc desbordamiento ... básicamente, descartando tus datos, asegurándote de que el programa que estás ejecutando se ejecuta de una manera inesperada y probablemente errónea, y violando el estándar C. Lo peor de todo es que el error es silencioso, por lo que nunca se sabe.

  2. O simplemente puede regresar EOVERFLOW de execve(), informándole que simplemente no puede ejecutar una imagen con tantos parámetros. Ahora, los estándares POSIX / SUS no mencionan nada sobre este resultado de error ... pero, sospecho que esto es simplemente porque los escritores estándar nunca esperaron ARG_MAX ser más grande que INT_MAX.

La opción n. ° 2 es la solamente opción razonable. Si su sistema de alguna manera elige la opción n. ° 1, entonces es roto y debe presentar un informe de error.

Alternativamente, podría estar tratando de ejecutar un programa viejo compilado para un sistema de 16 bits, pero lo está ejecutando a través de algún tipo de emulador o capa de compatibilidad. Yo esperaría que el emulador o la capa de compatibilidad daría un mensaje de error si intentas pasar más de 215parámetros a un programa.


78
2018-01-21 19:38



En la práctica, no, no puedes. La mayoría de los sistemas colocan un límite relativamente bajo en el tamaño total combinado de argv y envp. Los límites en decenas a cientos de KB no son infrecuentes; ver http://www.in-ulm.de/~mascheck/various/argmax/ para una lista razonablemente completa de los límites en varios sistemas operativos.


17
2018-01-21 19:38



Intenté esto:

test.c:

   more test.c 
#include <stdio.h>
int main(int argc, char **argv)
{
    printf("argc = %d\n", argc);
    printf("Size of argc = %d\n", sizeof(argc));
    return 0;
}

Luego usé un archivo zip grande

   ls -h bigfile 
-rw-r--r-- 1 ehwas ehwas 355M Jan 22 16:54 bigfile

Luego lea el archivo como parámetros para el programa de prueba:

  ./test $(more bigfile)

Resultado:

5 minutes nothing happend, then everything froze

Luego probé un archivo más pequeño:

   ls -h notsobigfile 
-rw-r--r-- 1 ehwas ehwas 6.7M Jan 22 17:04 notsobigfile

Y:

   ./test $(more notsobigfile)
bash: ./test: Argument list too long

10
2018-01-22 15:07



Según lo indicado por el estándar, argv [argc] debe ser un valor válido.

Entonces, si el entorno de tiempo de ejecución se encuentra en una situación tal que no puede garantizar eso, no debería iniciar el programa.


2
2018-01-28 14:12