Sécurité des programmes Java T. HSU IUT de LENS, Département informatique November 26, 2014 T. HSU Sécurité des programmes Java Part I Assertion T. HSU Sécurité des programmes Java Introduction En linguistique et en philosophie – w ikipédia un énoncé considéré ou présenté comme vrai En langage informatique une expression qui doit être évaluée à vrai T. HSU Sécurité des programmes Java Un exemple unExemple.java p u b l i c v o i d add ( O b j e c t o ) { m a C o l l e c t i o n . add ( o ) ; // Ma c o l l e c t i o n d o i t a v o i r un o b j e t de p l u s } Vous spécfiez en commentant que votre collection possède un objet de plus Pourquoi ne pas le faire en le faisant comprendre par le langage T. HSU Sécurité des programmes Java Un exemple Bis unExempleBis.java p u b l i c v o i d add ( O b j e c t o ) { o l d s i z e = maCollection . s iz e ( ) ; int m a C o l l e c t i o n . add ( o ) ; a s s e r t m a C o l l e c t i o n . s i z e ( ) == ” Argl ” ; } old size + 1 : Lisibilité Facile à écrire Aide au déboguage T. HSU Sécurité des programmes Java Aucun intérêt ?? Cela semble bien inutile puisque l’on est sûr de nous par définition, l’assertion est vraie Bien entendu, ce que vous écrivez est juste ... si vous n’avez jamais de bugs dans votre code ... T. HSU Sécurité des programmes Java Syntaxe [en Java] assert condition [ : st ] ; condition renvoie un booléen st informe sur l’échec de l’assertion. C’est un objet de n’importe quel type Simple à mettre en oeuvre Attention : n’essayer pas de résoudre tout à coup de assert T. HSU Sécurité des programmes Java Quand utiliser Les assertions Les assertions sont faites pour vérifier la logique interne du programme Une assertion est attachée à un point du programme Elles ne sont pas faites pour vérifier une condition qui ne dépend pas totalement du programme Ne pas utiliser comme précondition d’une méthode publique ! Utiliser pour précondition d’une méthode privée post condition invariant de boucles après les traitements complexes T. HSU Sécurité des programmes Java Attention A NE JAMAIS FAIRE .. assert connect() : ”La connection est impossible”; T. HSU Sécurité des programmes Java Activation des assertions Par défaut les assertions sont désactivées Elles ne doivent être activées que pendant le déboggage Activation en java Compiler avec l’option -source 1.4 Executer avec l’option -ea Avec Eclipse T. HSU Sécurité des programmes Java Coût des assertions Pour les performances, les assertions désactivées ne coûtent que le test d’un seul drapeau qui indique qu’elles sont désactivées Cependant, les assertions prennent de la place dans le code compilé T. HSU Sécurité des programmes Java Part II Les exceptions T. HSU Sécurité des programmes Java Introduction L’instant idéal pour détecter une erreur est la compilation Tout ne peut pas être réglé à cette étape Les problèmes restants doivent être gérés à l’exécution avec un certain formalisme Permettre à l’initiateur de l’erreur de passer une information suffisante à un récepteur qui va savoir comment traiter proprement cette anomalie. T. HSU Sécurité des programmes Java Origine des erreurs Les erreurs d’entrées sorties Fautes de saisies de l’utilisateur Fichier corrompu / inexistant Les erreurs de matériels Imprimante déconnectée Page web temporairement inaccessible Les contraintes physiques Disque dur saturé Mémoire insuffisante Les erreurs de programmation Index de tableau Emploi d’une référence nulle T. HSU Sécurité des programmes Java Traitement des erreurs En présence d’une erreur, un programme peut avoir un comportement Idéal : Revenir à un état défini et poursuivre l’exécution Honnête : Prévenir l’utilisateur, sortir correctement après une sauvegarde Lamentable : Ecran bleu + erreur à l’adresse 0x7743!! T. HSU Sécurité des programmes Java Traitement des erreurs en C Convention de programmation : un programme retourne un code qui permet de connaı̂tre son comportement durant l’exécution Est on sûr que tout le monde programme de cette façon : NON Les programmes C ne sont pas les plus sûrs du monde informatique T. HSU Sécurité des programmes Java Traitement des erreurs en Java/C++ Gestion d’exceptions Si un problème survient, une exception est levée, une exception est un objet spécialement créé pour pour gérer les erreurs Toute exception peut/doit être levée Les comportements anormaux sont gérés avec les exceptions Il est important de distinguer une condition exceptionnelle d’un problème normal Avec une condition exceptionnelle vous ne pouvez pas continuer l’exécution car vous n’avez pas suffisamment d’informations pour la traiter dans le contexte courant Le code de gestions des exceptions est à part Les exceptions sont des classes de Java Les programmes Java sont assez sûrs T. HSU Sécurité des programmes Java Les exceptions Certaines méthodes peuvent lancer des exceptions Lorsqu’on utilise une telle méthode, on peut Attraper les exceptions levées Ignorer les exceptions levées et les relancer T. HSU Sécurité des programmes Java Exemple Dans la classe Scanner (lecture flux entrée) se trouve la méthode nextInt définie comme suit : p u b l i c i n t n e x t I n t ( ) throws I n p u t M i s m a t c h E x c e p t i o n Ainsi toute instance de Scanner peut éventuellement lancer une InputMismatchException Toute fonction utilisant cette méthode a la possibilité de lever l’exception InputMismatchException T. HSU Sécurité des programmes Java Attraper une exception Une méthode qui utilise une méthode levant une exception peut attraper celle ci Un bloc try{ } délimite le code à surveiller Au moins un bloc catch{ } suit : Il gère les exceptions attrapées Chaque bloc catch permet de récupérer la main pour traiter un type d’exception Ils sont considérés dans l’ordre jusqu’à ce que l’exception levée corresponde au type ou à un sous type de celui indiqué en argument un bloc finally{ } apparaı̂t éventuellement T. HSU Sécurité des programmes Java Exemple unExemple.java int l i r e E n t i e r () { int x = 0; S c a n n e r s c = new S c a n n e r ( System . i n ) ; t r y { x=s c . n e x t I n t ( ) ; } catch ( InputMismatchException e ) { System . o u t . p r i n t l n ( ” E r r e u r : ” + e ) ; } System . o u t . p r i n t l n ( ” t o t o=” + x ) ; return x ; } En cas d’erreur Erreur : java.io.InputMismatchException Comportement normal toto=5 T. HSU Sécurité des programmes Java Exemple Lecture Fichier lireFichier.java try { readFromFile ( ” nomFile ” ) ; ... } catch ( Fil eNot Fou ndExc ept ion ) { /∗ G e s t i o n du c a s : f i c h i e r i n t r o u v a b l e ∗/ } } catch ( IOException ) { /∗ G e s t i o n du c a s : e r r e u r de l e c t u r e ∗/ } } catch ( E x c e p t i o n ) { /∗ G e s t i o n du c a s : Toute a u t r e e r r e u r ∗/ } } } T. HSU Sécurité des programmes Java Laisser passer une exception Dans certains cas, il est intéressant de laisser passer l’exception Il faut alors ajouter à l’en-tête le type de l’exception devant être relancée avec le mot-clé throws l’erreur remonte alors vers la méthode appelante qui peut elle-même l’attraper ou la laisser remonter Si tout le monde laisse passer l’exception, y compris la méthode main, alors le programme s’arrête T. HSU Sécurité des programmes Java Exemple exception.java i n t l i r e N o m b r e ( ) throws I n p u t M i s m a t c h E x c e p t i o n { S c a n n e r s c = new S c a n n e r ( System . i n ) ; int x = sc . nextInt ( ) ; return x ; } T. HSU Sécurité des programmes Java et finally Le bloc finally { } contient un traitement exécuté systématiquement que le bloc try ait levé ou pas l’exception que l’exception ait été attrapée ou non utilisé pour libérer certaines ressources T. HSU Sécurité des programmes Java Part III Mécanisme de traitement T. HSU Sécurité des programmes Java Exception levée en dehors du bloc try 1 La méthode retourne immédiatement ; l’exception remonte vers la méthode appelante 2 La main est donnée à la méthode appelante 3 L exception peut alors éventuellement être attrapée par cette méthode appelante ou par une des méthodes actuellement dans la pile d’exécution T. HSU Sécurité des programmes Java Exception levée dans un bloc try 1 Si une des instructions du bloc try provoque une exception, les instructions suivantes du bloc try ne sont pas exécutées et, si au moins une des clauses catch correspond au type de l’exception, 1 2 la première clause catch appropriée est exécutée l’exécution se poursuit juste après le bloc try/catch sinon 1 2 la méthode retourne immédiatement l’exception remonte vers la méthode appelante T. HSU Sécurité des programmes Java Pas d’exception générée dans le bloc try Dans les cas où l exécution des instructions de la clause try ne provoque pas d erreur/exception, 1 2 le déroulement du bloc de la clause try se déroule comme s’il n’y avait pas de bloc try/catch le programme se poursuit après le bloc try/catch T. HSU Sécurité des programmes Java Exemples de traitement Fixer le problème et réessayer le traitement qui a provoqué le passage au bloc catch Faire un traitement alternatif Retourner (return) une valeur particulière Sortir de l’application avec System.exit() Faire un traitement partiel du problème et relancer (throw) la même exception (ou une autre exception) T. HSU Sécurité des programmes Java Lancer une exception On lance une exception pour signaler une situation anormale Dans l’en-tête d’une méthode lançant une exception se trouve le mot-clé throws puis la liste des exceptions pouvant être lancées Dans le corps d’une méthode lançant une exception se trouvent une ou plusieurs instruction throw permettant de lancer des exceptions T. HSU Sécurité des programmes Java unExemple.java i n t l i r e D e n o m i n a t e u r ( ) throws A r i t h m e t i c E x c e p t i o n { int x = 12; x = Mediator . r e a d I n t ( ) ; i f ( x==0) { throw new A r i t h m e t i c E x c e p t i o n ( ) ; } System . o u t . p r i n t l n ( ” x = ” + x ) ; return x ; } Si x=0 n’affiche rien Si x6= 0 x = ?? T. HSU Sécurité des programmes Java Hiérarchie des exceptions Les classes liées aux erreurs/exceptions sont des classes placées dans l’arborescence d héritage de la classe Throwable Le JDK fournit un certain nombre de telles classes Le programmeur peut en ajouter de nouvelles T. HSU Sécurité des programmes Java Arbre d’héritage des exceptions Throwable Exception Error RunTimeExcepion Excptions Controlées Paquet JDK T. HSU Sécurité des programmes Java Définies par le programmeur Classe Error Une exception Error est levée si une erreur interne se produit un manque de ressources (mémoire ...) apparaı̂t ne doit pas être attrapée Assez rare T. HSU Sécurité des programmes Java Types d’erreurs ClassCircularityError ClassFormatError Object LinkageError ExecptionInIniatilizerError AbstractMethodError IncompatibleClassChangeError IllegalAccessError NoClassDefFoundError InstantiationError Throwable UnsatisfiedLinkError NoSuchFieldError VerifyError NoSuchMethodError ThreadDeath Error VirtualMachineError InternalError OutOfMemoryError StackOverflowError UnknownError T. HSU Sécurité des programmes Java Les exceptions non controlés issues de la classe RunTimeException : définies dans SDK Peuvent être lancées par la JVM Peuvent être attrapées, ne doivent pas être signalées exemple : ArrayIndexOutOfBoundsException, NullPointerException... Heureusement, car sinon le code java serait rempli de try et catch et serait extrêmement lent... T. HSU Sécurité des programmes Java Les exceptions controlés Héritent de la classe Exception, mais pas de RunTimeException Le compilateur vérifie que les méthodes les utilisent correctement (les attrapent ou les relancent) Toute méthode qui peut lancer une telle exception doit le déclarer void lance(..) throws TotoException Exemple : ClassNotFoundException, SQLException T. HSU Sécurité des programmes Java Architecture de JUNIT T. HSU Sécurité des programmes Java Créer des nouvelles exceptions Intéressant lorsque l’on rencontre un problème qui ne correspond pas de façon adéquate à l’une des exceptions standards Il suffit de créer une classe héritant de exception On crée deux constructeurs Un sans arguments Un avec une chaı̂ne de caractère comme argument qui contient un message détaillé de l’erreur T. HSU Sécurité des programmes Java Exemple unExemple.java c l a s s DivisionByZeroException extends ArithmeticException { DivisionByZeroException () { s u p e r ( ” D i v i s i o n by 0 ” ) ; } DivisionByZeroException ( String s ) { super ( s ) ; } } C’est tout : DivisionByZeroException est créée, je peux la lancer avec throw T. HSU Sécurité des programmes Java Exemple unExemple.java i n t l i r e D e n o m i n a t e u r ( ) throws D i v i s i o n B y Z e r o E x c e p t i o n { S c a n n e r s c = new S c a n n e r ( System . i n ) ; int x = sc . nextInt ( ) ; i f ( x==0) { throw new D i v i s i o n B y Z e r o E x c e p t i o n ( ) ; } return x ; } T. HSU Sécurité des programmes Java Exceptions et performances Si aucune exception n’est levée, l’impact sur les performances est négligeable La levée d’une exception peut au contraire avoir un impact non négligeable sur les performances T. HSU Sécurité des programmes Java Conseils Les exceptions doivent être utilisées dans des cas exceptionnels Il existe de nombreuses exceptions, essayez de les utiliser avant d’en créer des nouvelles Elles ne doivent pas remplacer des tests simples tels que l’appartenance d’un index dans les bornes d’un tableau ! T. HSU Sécurité des programmes Java Exemple unExemple.java f o r ( i n t i =0; i < a . l e n g t h ; i ++) { System . o u t . p r i n t l n ( a [ i ] ) ; } unAutreExemple.java try { int i = 0; while ( true ) { System . o u t . p r i n t l n ( a [ i ] ) ; i ++; } catch ( ArrayIndexOutOfBoundsException e ) { } 1 2 C’est Horrible ! C’est 20 fois plus lent à l’exécution T. HSU Sécurité des programmes Java