Journal Les 25 erreurs de programmation les plus dangereuses

Posté par .
Tags : aucun
8
14
jan.
2009
L'article en lien ci-dessous a été rédigé en collaboration avec des experts travaillant dans des centres de recheche spécialisés et à l'aide de grands éditeurs de logiciels.

Cet article nous montre quels sont les 25 erreurs de programmation les plus risquées.

La doc est en anglais, je n'ai pas eu le temps de lire en détail, mais à première vue très intéressant. Même si un tel document ne constitue pas un abri sans failles aux vulnérabilités, nul doute que les développeurs pourront l'utiliser pour améliorer la qualité de leur code.

Vos avis et commentaires sont les bienvenus.

Le lien :

http://www.sans.org/top25errors/?utm_source=web&utm_medium=t(...)
  • # Une carrière assurée

    Posté par (page perso) . Évalué à 9.

    Combiné avec ça : http://freeworld.thc.org/root/phun/unmaintain.html

    On assure notre emploi pour plusieurs générations.
    • [^] # Re: Une carrière assurée

      Posté par (page perso) . Évalué à 1.

      J'adore ce passage là:

      CapiTaliSaTion
      Randomly capitalize the first letter of a syllable in the middle of a word. For example ComputeRasterHistoGram()

      Car c'est exactement ce que fait Microsoft. Le code que produit Microsoft est donc non-maintenable si l'on en crois ce guide.
      • [^] # Re: Une carrière assurée

        Posté par . Évalué à 2.

        Ne serait-ce pas plutôt la Notation_hongroise chez Microsoft (qui par ailleurs n'a pas toujours bonne réputation non plus).
        • [^] # Re: Une carrière assurée

          Posté par . Évalué à 3.


          Be Abstract
          In naming functions and variables, make heavy use of abstract words like it, everything, data, handle, stuff, do, routine, perform and the digits e.g. routineX48, PerformDataFunction, DoIt, HandleStuff and do_args_method.

          haha c'est vrai qu'à la fin on ne sait plus quoi inventer. Ça fait une tautologie fonction <--> nommage sans se soucier de ce que fait vraiment la fonction dans le cas particulier.
          • [^] # Re: Une carrière assurée

            Posté par . Évalué à 2.

            "Be Abstract" est une erreur ?
            Heu ... Etre trop abstrait oui, créer une abstraction pour certaines fonctions non.
        • [^] # Re: Une carrière assurée

          Posté par (page perso) . Évalué à 2.

          > (qui par ailleurs n'a pas toujours bonne réputation non plus)

          Tu peux me dire pourquoi elle n'a pas une bonne réputation ?
          • [^] # Re: Une carrière assurée

            Posté par . Évalué à 9.

            Mon avis perso: elle rend le code illisible, et transporte une info dont tout le monde se fout a ce niveau, a savoir le type de la variable. Tout ide digne de ce nom te donnera le type de ta variable quand tu en as besoin.
            Si tu ne peux pas inferer le type de la variable a partir de son nom, ton nom de variable est vraiment mauvais, et il faut le changer plutot que de le prefixer d'un suite de caracteres incongrue.

            Ce qui est important c'est de savoir ce que la variable represente (semantiquement), pas son type de donnees.
            En l'occurence, par exemple, savoir que la chaine est echappee (je cite l'exemple d'un papier que j'avais lu sur pourquoi la notation hongroise ne devrait pas etre utilisee, me demandez pas l'adresse, je l'ai pas).

            Sans compter qu'on se doute bien que la chaine de caractere est implementee par un lpsz, les int par des i etc., on a plus 12 ans.

            Bref, information superflue, qui peut etre retrouvee ailleurs simplement de toutes facons et qui n'a donc pas grand chose a faire a cet endroit, a part polluer le code avec du bruit.

            lpfMonTableau de float c'est quand meme plus chiant a lire que monTableauDeFloat. Et dans les 2 cas, tu sais tres bien quel est le type de chaque variable.

            Le plus drole est quand certains appliquent betement ca a du java, par exemple.
            Tu te retrouves alors avec des lp en prefixe de chaque variable non scalaire (bah vi, tout est pointeur!!!) et des sz devant les strings (bon ok, dans ce cas c'est un mauvais choix du prefix, qui aurait du etre s, mais ca fait toujours sourire).
            Ou des i_Machaine en nom dep arametre d'une fonction pour indiquer que la String n'estp as modifiee.
            Quand tu sais que les strings en java sont immutables...

            Bref, excepte a la rigueur pour une distinction s/sz en C, que tu ne peux deviner et rentre dans le cas cite precedemment (ce que represente la variable), c'est du bruit qui pourrit le code.

            Sinon, wikipedia a des citations a ce sujet, surement plus eloquentes que les miennes:
            http://en.wikipedia.org/wiki/Hungarian_notation#Notable_opin(...)
            • [^] # Re: Une carrière assurée

              Posté par . Évalué à 5.

              Stroustrup à un avis assez net sur la notation hongroise : "Si vous souhaitez vraiment utiliser la notation hongroise, vous utilisez alors probablement un langage peu approprié à votre application." [http://msdn.microsoft.com/fr-fr/magazine/cc500572.aspx]

              C'est marrant que cette entretien a été réalisé pour MSDN Magazine.
            • [^] # Re: Une carrière assurée

              Posté par . Évalué à 3.

              Perso je trouves ca plutot utile et je l'utilises constamment.

              Petit exemple:

              1) Length=Value+Difference

              2) dwLength=dwValue+dwDifference

              3) dwLength=wValue+wDifference

              Dans le cas 1) Tu n'as aucune idee si il y a overflow, tu ne connais pas les types a vue d'oeil(c'est peut-etre pas toi qui a ecrit ce code notamment), et le compilo ne te dira rien du tout la dessus
              Dans le cas 2) Tu sais qu'il y a risque d'overflow en voyant le type des variables dans le nom
              Dans le cas 3) Tu sais qu'il n'y a pas de risque d'overflow en voyant le type des variables
              • [^] # Re: Une carrière assurée

                Posté par . Évalué à 2.

                Mmmmh... effectivement.
                Cela dit, j'ai l'impression que conceptuellement, ca se rapproche de ce pour quoi la notation a ete faite, a savoir poser une information semantique (ici: 'tention, debordement de valeur possible), plus que ce pour quoi elle est generalement utilisee (donner le type).

                Disons que l'info que tu vehicules ici, c'est "potentiel debordement de par la nature des valeurs qu'on manipule" plus que "double word", "word".
                T'aurais le meme pb avec des int ou des longs non?
                L'information vehiculee serait la meme, mais ecrite differement, ce qui laisserais penser que la notation n'est pas adaptee.
                Du contexte sur le contenu des valeurs numerique te permettra de savoir si tu as un potentiel debordement ou pas.

                Apres, j'aurais tendance a dire que si debordement de valeur tu as, mauvais choix de type tu as fait en premier lieu. Surtout sur une length (oui, je sais c'est un exemple, mais bon...).
                Je concois que le debordement puisse ne pas avoir d'impact semantique dans certains cas, autant une length qui deborde et devient negative, c'est que mettre ta length sur un dw etait pas un bon choix et qu'il te fallait un int ou un long ou un whatever.
                Je me trompe?
                • [^] # Re: Une carrière assurée

                  Posté par . Évalué à 1.

                  Cela dit, j'ai l'impression que conceptuellement, ca se rapproche de ce pour quoi la notation a ete faite, a savoir poser une information semantique (ici: 'tention, debordement de valeur possible), plus que ce pour quoi elle est generalement utilisee (donner le type).

                  Justement non, c'est en sachant le type (dw et w) que j'arrives a savoir si le code a un probleme ou pas.

                  T'aurais le meme pb avec des int ou des longs non?
                  L'information vehiculee serait la meme, mais ecrite differement, ce qui laisserais penser que la notation n'est pas adaptee.


                  Oui, et la notation marcherait tout autant, le fait de voir les types permet de juger ce qui va arriver lors de l'operation. Ne pas savoir quels sont les types empeche cette analyse immediate.

                  Apres, j'aurais tendance a dire que si debordement de valeur tu as, mauvais choix de type tu as fait en premier lieu. Surtout sur une length (oui, je sais c'est un exemple, mais bon...).
                  Je concois que le debordement puisse ne pas avoir d'impact semantique dans certains cas, autant une length qui deborde et devient negative, c'est que mettre ta length sur un dw etait pas un bon choix et qu'il te fallait un int ou un long ou un whatever.
                  Je me trompe?


                  Oui tu te trompes :)

                  Le fait que ta longueur peut depasser la taille du type est un cas courant (integer overflow), la solution dans la plupart des cas ce n'est pas de changer de type (il y aura toujours un chiffre plus grand que ton type, nombre de protocols ont des champs 64bits et aucun compilo ne gere des entiers >64bit en natif), mais verifier que l'addition ne depasse la capacite du type dans les cas ou l'overflow est possible.

                  Autre avantage :

                  a) wstring wsText1, wsText2;
                  wsText1=wsText2;

                  b) wstring *Text1, *Text2;
                  Text1=Text2;

                  c) wstring *lpwsText1, *lpwsText2;
                  lpwsText1=lpwsText2;

                  Tu vois la difference ?
                  Cas a) Tu connais le type, tu sais que ton objet 1 prend la valeur de l'objet 2 et que modifier une variable n'affecte pas l'autre.
                  Cas b) Tu ne connais rien du type, t'as 2 pointeurs sur le meme objet ou t'as 2 objets separes que tu peux detruire separement ?
                  Cas c) Tu sais que tes 2 variables sont des pointeurs qui pointent sur le meme objet, que donc faire un delete sur les 2 variables cause un double free et changer l'objet change ce qui est pointe par les 2 variables.
                  • [^] # Re: Une carrière assurée

                    Posté par . Évalué à 1.

                    ouais, ouais.

                    Autant le coup de l'overflow, ouais, autant le coup des pointeurs, c'est plus un palliatif au langage qui melange allegrement instance et pointeurs, ce qui pour moi n'est pas la meilleur idee a la base pour ecrire du code maintenable.

                    Bref, on va dire que ca depend du langage, mais c'est loin d'etre une convention qui doit etre adoptee partout.

                    Prend du java ou du python (je citerais bien c# mais j'ai peur de dire une betise ne sachant pas si c# autorise le melange instance/pointeur), ton deuxieme exemple n'a tout simplement pas de sens.
                    • [^] # Re: Une carrière assurée

                      Posté par . Évalué à 1.

                      C'est sur que ca n'a pas la meme importance avec tous les langages, mais dans le cas de C / C++ et certainement qqe autres c'est plutot utile.
                  • [^] # Re: Une carrière assurée

                    Posté par . Évalué à 2.

                    j'éxècre profondément ce principe. Tu coderas pas dans le noyau Linux avec ça. Pourquoi on ajouterai pas le numéro de ligne où se trouve la déclaration en plus, pour rendre ça plus croustillant?
                    • [^] # Re: Une carrière assurée

                      Posté par . Évalué à 2.

                      Pas grave si je code pas dans le noyau Linux avec ca, il y a un autre noyau qui le permet.

                      Le numero de ligne n'apporte rien, le type si, comme demontre plus haut.
                  • [^] # Re: Une carrière assurée

                    Posté par (page perso) . Évalué à 2.

                    C'était ce que je pensais jusqu'à ce que je lise du code dans GNOME/GTK. Bin ils utilisent des noms de variables simple, dans des fonctions courtes. Du coup t'as pas à remonter 300 lignes de code pour voir le type d'une variable, et au final c'est plus court et plus lisible comme une phrase en anglais réel.

                    Je ne fais plus de notation hongroise depuis (sauf dans les cas intéressants cités par Joel Spolsy, différencier des variables de type identique, mais qui ont une utilisation différente, c'est plutôt du typage sémantique).
                    • [^] # Re: Une carrière assurée

                      Posté par . Évalué à 1.

                      Prends l'exemple de C++, tes variables membres sont declarees dans un autre fichier(declaration de la classe), et t'as un certain nombre de methodes, ca devient vite complique de s'y retrouver.

                      La j'ai un projet d'environ 100'000 lignes de code, avec probablement une centaine de classes si ce n'est plus, bonne chance pour te souvenir des types de variable...
                      • [^] # Re: Une carrière assurée

                        Posté par . Évalué à 2.

                        en même temps si les variables sont bien nommée (et pas plop, ploc, plic, plonk, tonk, tak, pic, bunk, plouf...) leur nom devrai suffire à deviner le type :D

                        Quand je travaille sur une classe, j'ai sa définition à gauche (ou à droite selon mon humeur) bien visible, mais ça c'est plus pour une lecture des noms de méthodes/variables que pour les types.

                        Là ou ça pourrait être utile, c'est qu'il faudrait préciser l'unité de la variable, bien plus que le type.
                        Je pense notamment a degré où il faudrait plutôt préciser si ce sont des Celcius Fareinight, kelvin ou un angle :) l'appeler fdegré ou ddegré donne l'impression d'avoir ripé sur le clavier (en plus de devoir taper plus de lettre pour la complétion auto)

                        comme avec distance, où il faudrait plutôt préciser si on est en miles (nautique ou non ), pied, pouce, mètre, centimètre, millimètre, unité astronomique, car

                        Ça ça éviterai bien des boulettes (heureusement un langage permet de préciser les unités des données il me semble )

                        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                        • [^] # Re: Une carrière assurée

                          Posté par . Évalué à 2.

                          Ben pas forcement, une longueur, c'est un entier non-signe 16, 32 ou 64bit ? Selon le soft, les imperatifs d'espace, perf, limitations du probleme... ca peut etre different.

                          Avoir la definition d'une classe visible en meme temps est une methode, perso je prefere cette notation, ca m'evite de tourner la tete toutes les 30 secondes.

                          Sinon, tu bosserais pas pour ArianeEspace par hasard ? :)
                          • [^] # Re: Une carrière assurée

                            Posté par . Évalué à 2.

                            Ariane quel drôle d'idée :D
                            Pour en revenir au fil (hihi), je suis plutôt dans un autre secteur (en ce moment), et savoir ce qu'on manipule comme donnée est bien plus vital qu'un quelconque overflow (qui ne pourrait arriver que sur des valeurs impossible). On manipule des valeurs finie, dans des variables choisie en fonction de ce qui est manipulé (c'est ce qu'on disait pour les années sur 2 chiffre ^^).

                            bon ensuite après un petit test
                            #include

                            using namespace std;
                            int main()
                            {
                            int a=2147483647;
                            long long c;
                            long long d;
                            c = (long long)a + a;
                            d = a+a;
                            cout << "a="<< a << endl << "c=" << c << endl << "d=" << d << endl ;
                            }
                            donne un résultat assez marrant :D
                            a=2147483647
                            c=4294967294
                            d=-2

                            Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                            • [^] # Re: Une carrière assurée

                              Posté par . Évalué à 3.

                              je suis plutôt dans un autre secteur (en ce moment), et savoir ce qu'on manipule comme donnée est bien plus vital qu'un quelconque overflow (qui ne pourrait arriver que sur des valeurs impossible). On manipule des valeurs finie, dans des variables choisie en fonction de ce qui est manipulé (c'est ce qu'on disait pour les années sur 2 chiffre ^^).

                              Dans ce cas il faut utiliser des langages à typage fort, comme ADA, et pas du C/C++... Là au moins c'est le compilo qui peut t'avertir s'il y a un mélange de torchons et de serviettes (à condition de ne pas désactiver ce check, suivez mon regard...).

                              Faire reposer la validité des données sur un simple artifice de nommage est vraiment léger...
                              • [^] # Re: Une carrière assurée

                                Posté par . Évalué à 1.

                                alors la je suis d'accord à 100%
                                Surtout quand on fait appel à des presta :D, ceux qui ont des notions de physique suffisante ne sont pas légion :)
                                Malheureusement l'existant n'est pas en ADA... mais en c++ (et fortran)

                                Il ne faut pas décorner les boeufs avant d'avoir semé le vent

          • [^] # Re: Une carrière assurée

            Posté par (page perso) . Évalué à 3.

            J'ai lu ici même il y a genre un an, que la _vraie_ notation hongroise, inventée par un dev. Microsoft, est bien sémantique (genre uMaChaine pour les chaînes pas échappées (unsecure) et sMaChaine pour les chaînes échappées (secured) (et de même pour les fonctions, donc s1 = uFonc(u2) est un bug alors que s1 = sFonc(u2) est correct du point de vue « sécurité » du moins)) mais a été comprise de travers par les devs des autres départements MS qui ont pondu des « int i_n » des fois qu'on sache pas que « int n » est un entier.
        • [^] # Re: Une carrière assurée

          Posté par . Évalué à 2.

          Puisqu'on aborde la notation hongroise, je vois un gros avantage au notation pseudo-hongroise
          l'autocompletion permet d'éviter de ce demander comment s'apelle cette p... de variable déclarée plus tot.
          C'est plutot utile lorsqu'il faut faire tout un tas d'opération complexe avant de toucher une variable qu'on a déclarer plus tot.
          Ca justifie pas pour autant la notation purement hongroise mais un prefixe est assez pratique...
          • [^] # Re: Une carrière assurée

            Posté par . Évalué à 2.

            La plupart du temps, les variables peuvent (et donc doivent si vous voulez optimiser la maintenabilité) être déclarées juste avant leur première utilisation.
            • [^] # Re: Une carrière assurée

              Posté par . Évalué à 2.

              mouais ... Bof .... Dans une boucle c'est pas toujours la meilleure idée ... Et je suis pas sur que les compilateurs sachent gérer l'optimisation à ce niveau ...
              • [^] # Re: Une carrière assurée

                Posté par . Évalué à 2.

                Les compilateurs courants et ayant moins de 10 ans d'âge, je dirais plutôt oui, ils savent gérer.

                En cas de doute sur des gros trucs dans une boucle cruciale, on peut toujours sortir la déclaration de la boucle et la mettre juste avant en cas de doute, de toute façon une boucle devrait tenir dans un écran et donc je ne pense pas que le résultat poserait un quelconque problème de maintenabilité.

                J'ai dernièrement tendance à énormément qualifier en "const" (faute de coder dans un langage fonctionnel pur :p ) et je trouve que c'est très très pratique pour la relecture. Dans ce contexte j'ai plutôt logiquement tendance à faire rentrer des déclarations dans mes boucles qu'à les en faire sortir.
                • [^] # Re: Une carrière assurée

                  Posté par . Évalué à 1.

                  de toute façon une boucle devrait tenir dans un écran

                  Quelle taille d'ecran ? 17" en 1024x768 ou 30" en 3940x2400 ? :+)

                  J'ai dernièrement tendance à énormément qualifier en "const" (faute de coder dans un langage fonctionnel pur :p ) et je trouve que c'est très très pratique pour la relecture. Dans ce contexte j'ai plutôt logiquement tendance à faire rentrer des déclarations dans mes boucles qu'à les en faire sortir.

                  Quid du C++ avec les variables membres declarees dans un autre fichier ?
                  • [^] # Re: Une carrière assurée

                    Posté par . Évalué à 2.

                    Quelle taille d'ecran ? 17" en 1024x768 ou 30" en 3940x2400 ? :+)

                    Du texte en 80x25, quelle question ;)

                    Quid du C++ avec les variables membres declarees dans un autre fichier ?

                    Je parlais évidemment des variables locales, qui en l'occurrence deviennent plutôt des "constantes locales" si possible. On peut donc faire absolument la même chose en C++. Le problème des membres est distinct et on le retrouve de toute manière en C dans les membres des structures. À ce niveau je pense qu'on ne peut pas à priori savoir ce qui sera le plus pratique dans tous les cas entre pas de convention en rapport avec le typage, une redondance des types du langages ou des conventions sémantiques. J'ai tendance à ne pas trop aimer la redondance des types du langages mais il est tout à fait possible qu'elle s'avère utile dans certains cas -- peut-être aussi que la plupart des fois où elle pourrait-être utile, une convention sémantique le serait encore plus ?
      • [^] # Re: Une carrière assurée

        Posté par (page perso) . Évalué à 1.

        Tu peux donner un exemple de méthode dans les API Windows ou .NET qui a ce défault (par curiosité) ?
        • [^] # Re: Une carrière assurée

          Posté par . Évalué à 1.

          Pour la notation hongroise, tu peux aller regarder les .h des MFC, c'est lisible, mais un peu lourd quand même ...
          • [^] # Re: Une carrière assurée

            Posté par . Évalué à 2.

            Je crois qu'ils utilisent justement la "mauvaise" notation hongroise dans les MFC (types du langage donc redondants, et non types sémantiques utiles)
      • [^] # Re: Une carrière assurée

        Posté par (page perso) . Évalué à 1.

        > J'adore ce passage là:

        > CapiTaliSaTion
        > Randomly capitalize the first letter of a syllable in the middle
        >of a word. For example ComputeRasterHistoGram()

        Là ils parlent du "Histo" et du "Gram" et pas de la capitalisation
        de la première lettre de Compute, Raster et Histo. Pour cette dernière
        c'est surtout le style largement admis (et "conventionné" pour certains)
        pour les C#/C++/Java.

        > Car c'est exactement ce que fait Microsoft. Le code que produit
        > Microsoft est donc non-maintenable si l'on en crois ce guide.

        Si tu fais référence au "Histo" - "Gram", sur quoi te bases-
        tu pour dire ça? Tu as des exemples? Une copie du coding
        style chez Microsoft pour un langage particulier?
  • # Autre version...

    Posté par (page perso) . Évalué à 5.

    Cette version est plus sympa, surtout pour l'impression :
    http://cwe.mitre.org/top25/
  • # Erreur n°1

    Posté par (page perso) . Évalué à -3.

    Créez un clone d'un programme Microsoft....

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.