Argc peut-il déborder?

Je me promenais dans SO et j’ai vu cette question . Puis j’ai commencé à me demander si je pouvais déborder argc.

Standard dit que argv[argc] doit être un pointeur nul mais ce sera faux si argc overflow.

(J’ai écrit un petit programme C et un script python pour le tester mais j’ai obtenu un MemoryError .)

Merci!


Justification de la norme internationale – Langages de programmation – C §5.1.2.2.1 Démarrage du programme

La spécification de argc et argv tant qu’arguments à la main reconnaît une pratique antérieure étendue. argv[argc] doit être un pointeur nul pour fournir une vérification redondante de la fin de la liste, également sur la base des pratiques courantes.

    Selon la norme

    Donc, de votre citation:

    argv[argc] doit être un pointeur nul

    Par conséquent, argc ne peut pas déborder, car alors l’instruction ci-dessus ne serait pas vraie.

    En pratique

    En pratique, la taille totale des arguments transmis à un programme est limitée.

    Sur mon système Linux / x64:

     $ getconf ARG_MAX
     2097152
    

    Par conséquent, la taille totale des arguments est d’environ 2 Mo et argc ne peut pas déborder. Je crois que cette limite mesure une combinaison des données totales en argv et de l’environnement. Si vous dépassez cette limite lorsque vous essayez d’exécuter une commande, exec() échouera avec E2BIG . De l’ man 2 execve :

     E2BIG Le nombre total d'octets dans l'environnement (envp) et l'argument
            liste (argv) est trop grande.
    

    Je crois que la limite de ~ 2 Mo sur mon système est relativement généreuse par rapport aux autres systèmes. Mon système OS X indique une limite de ~ 260 Ko.

    Mais si ARG_MAX était vraiment grand?

    Bon, supposons que vous soyez sur un vieux système / bizarre, donc int est de 16 bits, et ARG_MAX est bien au-dessus de 2 15 , ce qui est plutôt raisonnable. Supposons maintenant que vous execve() avec plus de 2 15 arguments. La mise en œuvre a deux options.

    1. Cela peut permettre à argc de déborder … en fait, en jetant vos données, en vous assurant que le programme que vous exécutez s’exécute de manière inattendue et probablement erronée, en violation du standard C. Pire encore, l’erreur est silencieuse, donc vous ne le saurez peut-être jamais.

    2. Ou, il peut simplement renvoyer EOVERFLOW partir de execve() , vous informant qu’il ne peut tout simplement pas exécuter une image avec autant de parameters. Maintenant, les normes POSIX / SUS ne mentionnent rien à propos de ce résultat d’erreur … mais je suppose que c’est simplement parce que les ARG_MAX standard ne s’attendaient jamais à ce que ARG_MAX soit plus grand INT_MAX .

    L’option n ° 2 est la seule option raisonnable. Si votre système choisit en quelque sorte l’option # 1, alors il est cassé et vous devriez déposer un rapport de bogue.

    Vous pouvez également essayer d’exécuter un ancien programme compilé pour un système 16 bits, mais vous l’exécutez via une couche d’émulation ou de compatibilité. Je m’attendrais à ce que l’émulateur ou la couche de compatibilité envoie un message d’erreur si vous tentez de transmettre plus de 2 15 parameters à un programme.

    En pratique, non, vous ne pouvez pas. La plupart des systèmes envp une limite relativement faible à la taille totale combinée de argv et envp . Les limites de quelques dizaines à quelques centaines de Ko ne sont pas rares; voir http://www.in-ulm.de/~mascheck/various/argmax/ pour une liste assez complète des limites des différents systèmes d’exploitation.

    J’ai essayé ceci:

    test.c:

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

    Puis utilisé un gros fichier zip

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

    Lisez ensuite le fichier en tant que parameters du programme de test:

     ⚡⚡⚡ ./test $(more bigfile) 

    Résultat:

     5 minutes nothing happend, then everything froze 

    Ensuite, j’ai essayé un fichier plus petit:

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

    Et:

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

    Comme indiqué par la norme, argv [argc] doit être une valeur valide.

    Donc, si l’environnement d’exécution est dans une situation telle qu’il ne peut pas le garantir, il ne devrait pas démarrer le programme.